import 'dart:convert'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; import 'package:google_fonts/google_fonts.dart'; import 'package:intl/intl.dart'; import 'package:jwt_decode/jwt_decode.dart'; import 'package:nhance_app_pwa/customAppBar/customAppBar.dart'; import 'package:nhance_app_pwa/pages/postEnrollment/service/api_service.dart'; import 'package:nhance_app_pwa/pages/service/SessionManager.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:http/http.dart' as http; import '../../customAppBar/customFooter.dart'; import '../../customAppBar/responsive.dart'; import '../../customAppBar/tabs.dart'; import '../../customAppBar/toastHelper.dart'; import '../service/TokenService.dart'; import '../service/popup_helper.dart'; import 'package:nhance_app_pwa/logger.dart'; class tickettracklist extends StatefulWidget { final String ticketID; const tickettracklist({Key? key, required this.ticketID}) : super(key: key); @override State createState() => _tickettracklistState(); } class _tickettracklistState extends State { late ApiService apiService; late String ticketID; dynamic _token; bool isLoading = false; dynamic empCodeString; dynamic empPrimaryId; dynamic client_id; dynamic policyList; dynamic policyDataIsEmpty = 1; dynamic policyHeading; dynamic policyName; dynamic name; dynamic policyType; dynamic policyTickID; dynamic policyDate; dynamic policyStatus; dynamic policySubject; dynamic policyMessage; dynamic policyNo; dynamic hospitalName; dynamic admitDate; dynamic dischargeDate; dynamic claimAmount; dynamic member; dynamic accidentDate; dynamic departmentID; dynamic EmployeePolicy; List> employeeDetails = []; dynamic argumentsData; dynamic decodedToken; // dynamic claimTrackMsgList; List claimTrackMsgList = []; dynamic claimTrackMasterList; dynamic claimTrackList; dynamic empName; // dynamic ticketID; late TextEditingController messageController; final Map statusColors = { 'Open': Colors.green, 'Answered': Colors.blue, 'Awaiting Reply': Colors.orange, 'Inprogress': Colors.yellow, 'Closed': Colors.red, }; // Create a unique form key for each accordion section final GlobalKey formKey = GlobalKey(); final session = SessionManager(); @override void initState() { super.initState(); ticketID = widget.ticketID; logDebug('ticketID: $ticketID'); apiService = ApiService(context); // Initialize ApiService here _loadToken(); messageController = TextEditingController(); } @override void dispose() { super.dispose(); messageController.dispose(); } @override // void didChangeDependencies() { // super.didChangeDependencies(); // logDebug('ticket'); // dynamic arguments = ModalRoute.of(context)!.settings.arguments; // if (arguments != null && arguments is int) { // ticketID = arguments; // logDebug('ticketID: $ticketID'); // } // } Future _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? decodedToken = Jwt.parseJwt(token); logDebug(decodedToken); empCodeString = session.empCodeString; logDebug(empCodeString); // Check if emp_code is correct empPrimaryId = session.empPrimaryId; client_id = session.client_id; logDebug(client_id); getTicketConvoList(); } } void sendClaimsMessage(Map formData) async { setState(() { isLoading = true; }); try { logDebug("FORMDATA - $formData"); formData = formData.map((key, value) => MapEntry(key, value.toString())); logDebug("FORMDATA1 - $formData"); final response = await apiService.sendClaimsMessageToApi(formData); logDebug("REs - $response"); if (response['status'] == 'success') { messageController.clear(); // ToastHelper.showSuccessToast(context, 'Saved Successfully...'); messageController.clear(); setState(() { isLoading = false; }); // Navigator.pushNamed(context, 'claims', arguments: 0); getTicketConvoList(); logDebug('Form data sent successfully.'); } else { logDebug('Failed to submit form data: ${response['status']}'); } } catch (e) { logDebug('Error submitting form data: $e'); } } Color getStatusColor(String? policyStatus) { if (policyStatus != null && statusColors.containsKey(policyStatus)) { return statusColors[policyStatus]!; } else { return Color(0xFF000000); // Default color for policyStatus text } } Future getTicketConvoList() async { setState(() { isLoading = true; }); try { logDebug('check getTicketList 1'); final response = await apiService.getTicketConverList(ticketID); logDebug('check getTicketList 2'); setState(() { isLoading = false; }); // if (response['success'] == true && response['data'] is List) { setState(() { claimTrackList = response['data']; logDebug("TCtt1 - $claimTrackList"); claimTrackMasterList = response['data']['master']; logDebug("TCtt2 - $claimTrackMasterList"); claimTrackMsgList = response['data']['notes']; logDebug("TCtt3 - $claimTrackMsgList"); if (claimTrackMasterList != []) { logDebug("ClaimLST - "); logDebug(claimTrackMasterList[0]['thz_id']); policyTickID = claimTrackMasterList[0]['thz_id']; policyName = claimTrackMasterList[0]['policy_no']; // name = claimTrackMasterList[0]['name']; policyType = claimTrackMasterList[0]['ticket_type']; policyStatus = claimTrackMasterList[0]['status']; member = claimTrackMasterList[0]['assignee_name']; policySubject = claimTrackMasterList[0]['subject']; policyMessage = claimTrackMasterList[0]['message']; // logDebug("ClaimLST - ${claimTrackMasterList['thz_id'].toString()}"); } // reversedTicketList = List>.from(ticketList); // logDebug("TC2 - $ticketList"); // ticketList = reversedTicketList.reversed.toList(); // logDebug("TC3 - $ticketList"); }); // } // else if (response['status'] == "error" && // response['message'] == "No tickets found") { // setState(() { // ticketList = []; // trackClaimsList = []; // trackClaimsClosedList = []; // }); // ToastHelper.showErrorToast(context, 'No tickets found'); // } else { // setState(() { // isLoading = false; // }); // ToastHelper.showErrorToast(context, 'Unable to process. Please try again later'); // logDebug('API request failed with status: ${response['status']}'); // } } catch (e) { // ToastHelper.showErrorToast(context, 'Failed to load data'); logDebug('Error in getTicketList: $e'); } finally { if (mounted) { setState(() { isLoading = false; }); } } } @override Widget build(BuildContext context) { return PopScope( canPop: false, onPopInvokedWithResult: (didPop, result) { if (didPop) return; context.go('/raisedTicketHistory'); }, 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.2, // 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: [ Card( elevation: 5, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(15.0), // Set border radius here ), child: Container( decoration: BoxDecoration( color: Colors.white, // Set background color to white borderRadius: BorderRadius.circular( 15.0), // Set border radius for Container ), padding: Responsive.isDesktop(context) ? EdgeInsets.only(top: 15, bottom: 15, left: 15, right: 15) : EdgeInsets.only( top: 10, bottom: 10, left: 10, right: 10), // Add padding to the container child: Row( children: [ Expanded( flex: 12, child: Container( alignment: Alignment.centerLeft, child: Column( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( decoration: BoxDecoration( color: Color( 0xFFFFFCE5), // Set background color for the container borderRadius: BorderRadius.circular( 10), // Set border radius for the container ), padding: Responsive.isDesktop(context) ? EdgeInsets.only( top: 20, bottom: 20, left: 10, right: 10) : EdgeInsets.only( top: 10, bottom: 10, left: 10, right: 10), child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start, children: [ Row( mainAxisAlignment: MainAxisAlignment.start, children: [ Expanded( flex: 1, child: InkWell( onTap: () { context.go( '/raisedTicketHistory'); }, child: Icon( Icons .chevron_left, // Replace with your desired icon color: Color(0xFF000000), size: 30, ), ), ), Expanded( flex: 11, child: Row( mainAxisAlignment: MainAxisAlignment.start, children: [ Text( policyType ?? '', textAlign: TextAlign.start, style: GoogleFonts.poppins( fontSize: Responsive.isDesktop( context) ? 20 : 16, fontWeight: FontWeight.w600, color: Color(0xFF000000), ), ) ], ), ) ], ), SizedBox( height: Responsive.isDesktop(context) ? 20 : 20), // Space between rows Container( child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start, children: [ Responsive.isDesktop(context) ? buildDesktopLayout(context) : buildMobileLayout(context) ], ), ), // Space between rows ], ), ), SizedBox(height: 15), Container( decoration: BoxDecoration( // color: Color( // 0xFFFFFCE5), // Set background color for the container borderRadius: BorderRadius.circular( 10), // Set border radius for the container ), child: SingleChildScrollView( child: Padding( padding: const EdgeInsets.symmetric( vertical: 4.0, horizontal: 4.0), child: Column( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ SizedBox( height: 5, ), Text( "Conversation", style: GoogleFonts.poppins( fontSize: Responsive.isDesktop( context) ? 18 : 14, fontWeight: FontWeight.w500, color: Color(0xFF000000), ), ), ...claimTrackMsgList .map((message) { bool isUserMessage; // bool isUserMessage = // message['notes_by'] == null; String messageContent = message['notes']; String messageDate = message['created_at']; dynamic messagername; messagername = message['notes_by']; dynamic name; name = message['name']; // if (isUserMessage) { // messagername = empName; // } else { // messagername = message['staff_name']; // } if (messagername == "Staff") { isUserMessage = true; } else { isUserMessage = false; } return Padding( padding: const EdgeInsets.symmetric( vertical: 4.0, horizontal: 4.0), child: Align( alignment: isUserMessage ? Alignment.centerLeft : Alignment.centerLeft, child: Container( constraints: BoxConstraints( maxWidth: 800), padding: EdgeInsets.all(10), decoration: BoxDecoration( color: isUserMessage ? Colors.blue[100] : Colors.green[100], borderRadius: BorderRadius.circular( 10), ), child: Column( crossAxisAlignment: CrossAxisAlignment .start, children: [ Text( messageContent, style: GoogleFonts .poppins( fontSize: Responsive .isDesktop( context) ? 14 : 12, fontWeight: FontWeight.w400, color: Color( 0xFF000000), ), ), SizedBox(height: 5), Row( mainAxisAlignment: MainAxisAlignment .spaceBetween, children: [ Row( children: [ Icon( Icons.person, color: Color( 0xFFE26728), size: 15, ), SizedBox( width: 5), Text( name ?? '', style: GoogleFonts .poppins( fontSize: Responsive.isDesktop(context) ? 16 : 14, fontWeight: FontWeight .w500, color: Color( 0xFF000000), ), ), ], ), Text( // formatDateWithTime( // messageDate), formatDateWithTime( messageDate), style: GoogleFonts .poppins( fontSize: Responsive .isDesktop( context) ? 12 : 10, fontWeight: FontWeight .w400, color: Color( 0xFF636363), ), ), ], ), // Divider(), ], ), ), ), ); }).toList(), Padding( padding: const EdgeInsets.symmetric( vertical: 8.0), child: Row( children: [ Expanded( flex: Responsive.isDesktop( context) ? 10 : 9, child: TextFormField( controller: messageController, onChanged: (value) => null, decoration: InputDecoration( border: OutlineInputBorder(), hintText: 'Message', labelText: 'Message', contentPadding: EdgeInsets .symmetric( vertical: 10, horizontal: 15), ), validator: (value) { if (value == null || value.isEmpty) { return 'Message is required'; } return null; }, ), ), Expanded( flex: Responsive.isDesktop( context) ? 2 : 4, child: Container( alignment: Alignment .centerRight, child: ElevatedButton( onPressed: () { // Check if any of the fields are empty if (messageController .text.isEmpty) { ToastHelper .showWarningToast( context, 'All fields are required'); } else { // Create a map to hold the form data Map formData = { 'thz_id': ticketID, 'notes': messageController .text, 'notes_by': 'User', // Add more form fields as needed }; // Call the function to send form data to API sendClaimsMessage( formData); } }, style: ElevatedButton .styleFrom( backgroundColor: Color( 0xFFE26728), shape: RoundedRectangleBorder( borderRadius: BorderRadius .circular( 5), ), ), child: Text( 'Reply', style: GoogleFonts .poppins( color: Colors .white), ), ), ), ), ], )), ]), ), ), ), ], ))), ], ), ), ), SizedBox(height: Responsive.isDesktop(context) ? 40 : 10), ]), )), 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: 0, // Initial index of the bottom navigation bar ), ) ); } String formatDateWithTime(String timestamp) { // Parse the timestamp string to DateTime DateTime date = DateTime.parse(timestamp); // Format the DateTime object with date and time String formattedDate = DateFormat('d MMM y hh:mm a').format(date); return formattedDate; } // Widget buildDesktopLayout(BuildContext context) { // return Container( // color: Colors.redAccent.shade100, // child: Column( // // mainAxisAlignment: MainAxisAlignment.center, // // crossAxisAlignment: CrossAxisAlignment.center, // children: [ // Container( // color: Colors.yellowAccent.shade100, // child: Row( // children: [ // buildExpandedColumn(context, 'Ticket No', policyTickID), // if (policyType != "Sales") // buildExpandedColumn(context, 'Policy No', policyName), // // buildExpandedColumn(context, 'Ticket Type', policyType), // buildExpandedColumn(context, 'Status', policyStatus), // // buildExpandedColumn(context, 'Message', policyMessage), // ], // ), // ), // if (departmentID == '4') // Conditional check for policy_type // Column( // children: [ // SizedBox(height: 20), // Row( // mainAxisAlignment: MainAxisAlignment.center, // children: [ // buildExpandedColumn(context, 'Member', member), // buildExpandedColumn(context, 'Hospital Name', hospitalName), // buildExpandedColumn(context, 'Claim Amount', claimAmount), // ], // ), // SizedBox(height: 20), // Row( // mainAxisAlignment: MainAxisAlignment.center, // children: [ // buildExpandedColumn(context, 'Admit Date', admitDate), // buildExpandedColumn( // context, 'Discharge Date', dischargeDate), // buildExpandedColumn(context, '', ''), // ], // ), // ], // ), // if (departmentID == '3') // Conditional check for policy_type // Column( // children: [ // SizedBox(height: 20), // Row( // mainAxisAlignment: MainAxisAlignment.center, // children: [ // buildExpandedColumn(context, 'Member', member), // buildExpandedColumn(context, 'Accident Date', accidentDate), // buildExpandedColumn(context, 'Claim Amount', claimAmount), // ], // ), // ], // ), // ], // ), // ); // } Widget buildDesktopLayout(BuildContext context) { return Container( child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start, children: [ buildExpandedColumn(context, 'Ticket No', policyTickID), SizedBox( height: 5, ), if (policyType != "Sales") buildExpandedColumn(context, 'Policy No', policyName), SizedBox( height: 5, ), buildExpandedColumn(context, 'Status', policyStatus), SizedBox( height: 5, ), buildExpandedColumn(context, 'Subject', policySubject), SizedBox( height: 5, ), buildExpandedColumn(context, 'Message', policyMessage), SizedBox( height: 5, ), // buildExpandedColumn(context, 'Message', policyMessage), ], ), ); } Widget buildMobileLayout(BuildContext context) { return SingleChildScrollView( child: Container( child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start, children: [ buildExpandedColumn(context, 'Ticket No', policyTickID), SizedBox( height: 5, ), if (policyType != "Sales") buildExpandedColumn(context, 'Policy No', policyName), if (policyType != "Sales") SizedBox( height: 5, ), buildExpandedColumn(context, 'Status', policyStatus), SizedBox( height: 5, ), buildExpandedColumn(context, 'Subject', policySubject), SizedBox( height: 5, ), buildExpandedColumn(context, 'Message', policyMessage), SizedBox( height: 5, ), // SizedBox(height: 20), // if (policyType != "Sales") // Row( // mainAxisAlignment: MainAxisAlignment.center, // children: [ // buildExpandedColumn(context, 'Status', policyStatus), // // buildExpandedColumn(context, 'Ticket Type', policyType), // ], // ), // if (departmentID == '4') // Column( // children: [ // SizedBox(height: 20), // Row( // mainAxisAlignment: MainAxisAlignment.center, // children: [ // buildExpandedColumn(context, 'Claim Amount', claimAmount), // buildExpandedColumn( // context, 'Hospital Name', hospitalName), // ], // ), // SizedBox(height: 20), // Row( // mainAxisAlignment: MainAxisAlignment.center, // children: [ // buildExpandedColumn(context, 'Admit Date', admitDate), // buildExpandedColumn( // context, 'Discharge Date', dischargeDate), // ], // ), // ], // ), // if (departmentID == '3') // Column( // children: [ // SizedBox(height: 20), // Row( // mainAxisAlignment: MainAxisAlignment.center, // children: [ // buildExpandedColumn(context, 'Claim Amount', claimAmount), // buildExpandedColumn( // context, 'Accident Date', accidentDate), // ], // ), // ], // ), ], ), ), ); } Widget buildExpandedColumn( BuildContext context, String title, String? value) { return Container( // color: Colors.orange.shade100, width: Responsive.isDesktop(context) ? MediaQuery.of(context).size.width * 0.6 : MediaQuery.of(context).size.width * 1, // alignment: Alignment.center, child: Row( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ Expanded( flex: 1, child: Container( // color: Colors.pink.shade100, child: Column( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( title, textAlign: TextAlign.start, style: GoogleFonts.poppins( fontSize: Responsive.isDesktop(context) ? 14 : 12, fontWeight: FontWeight.w400, color: Color(0xFF000000), ), ), ], ), ), ), // SizedBox(width: Responsive.isDesktop(context) ? 10 : 4), Expanded( flex: 3, child: Container( // color: Colors.deepPurple.shade100, child: Column( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ title == 'Status' ? Text( value ?? '', // Null check for value textAlign: TextAlign.start, style: GoogleFonts.poppins( fontSize: Responsive.isDesktop(context) ? 14 : 12, fontWeight: FontWeight.w600, color: getStatusColor(policyStatus), ), ) : Text( value ?? '', // Null check for value textAlign: TextAlign.start, softWrap: true, maxLines: 50, overflow: TextOverflow.ellipsis, style: GoogleFonts.poppins( fontSize: Responsive.isDesktop(context) ? 14 : 12, fontWeight: FontWeight.w600, color: Color(0xFF000000), ), ), ], ), ), ), ], ), ); // ); } Widget buildExpandedRow(BuildContext context, String title, String? value) { return Expanded( flex: 3, child: Container( alignment: Alignment.center, child: Column( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ SizedBox( width: 100, child: Text( title, // textAlign: TextAlign.center, style: GoogleFonts.poppins( fontSize: Responsive.isDesktop(context) ? 18 : 14, fontWeight: FontWeight.w400, color: Color(0xFF000000), ), ), ), SizedBox(width: Responsive.isDesktop(context) ? 10 : 4), Flexible( child: Text( value ?? '', // Null check for value // textAlign: TextAlign.center, style: GoogleFonts.poppins( fontSize: Responsive.isDesktop(context) ? 18 : 16, fontWeight: FontWeight.w600, color: Color(0xFF000000), ), ), ), ], ), ), ); } }