import 'dart:convert'; import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:mohem_flutter_app/app_state/app_state.dart'; import 'package:mohem_flutter_app/classes/colors.dart'; import 'package:mohem_flutter_app/classes/date_uitl.dart'; import 'package:mohem_flutter_app/classes/file_process.dart'; import 'package:mohem_flutter_app/classes/utils.dart'; import 'package:mohem_flutter_app/extensions/int_extensions.dart'; import 'package:mohem_flutter_app/extensions/string_extensions.dart'; import 'package:mohem_flutter_app/extensions/widget_extensions.dart'; import 'package:mohem_flutter_app/models/dashboard/get_accural_ticket_balance_model.dart'; import 'package:mohem_flutter_app/models/eit/get_eit_transaction_model.dart'; import 'package:mohem_flutter_app/models/eit_attachment_ticket_model.dart'; import 'package:mohem_flutter_app/provider/dashboard_provider_model.dart'; import 'package:mohem_flutter_app/widgets/app_bar_widget.dart'; import 'package:mohem_flutter_app/widgets/balances_dashboard_widget.dart'; import 'package:mohem_flutter_app/widgets/button/default_button.dart'; import 'package:mohem_flutter_app/widgets/item_detail_view_widget.dart'; import 'package:mohem_flutter_app/widgets/sso_webview_widget.dart'; import 'package:provider/provider.dart'; class TicketDetailedScreen extends StatefulWidget { final String? url; final String? jwtToken; const TicketDetailedScreen({super.key, this.url, this.jwtToken}); @override State createState() => _TicketDetailedScreenState(); } class _TicketDetailedScreenState extends State { DashboardProviderModel? dashboardProviderModel; late DateTime accrualDateTime; @override void initState() { dashboardProviderModel = Provider.of(context, listen: false); accrualDateTime = DateTime.now(); super.initState(); } void changeAccrualDate(bool showLoading) async { try { if (showLoading) Utils.showLoading(context); await dashboardProviderModel?.fetchTicketAccuralBalance(context, accrualDateTime); if (showLoading) Utils.hideLoading(context); setState(() {}); } catch (ex) { if (showLoading) Utils.hideLoading(context); Utils.handleException(ex, context, null); } } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: Colors.white, appBar: AppBarWidget(context, title: "Ticket Details"), body: Column( children: [ ListView( padding: const EdgeInsets.all(21), physics: const BouncingScrollPhysics(), children: [ if (dashboardProviderModel == null && dashboardProviderModel?.accrualTicketBalanceList == null) ...[Utils.getNoDataWidget(context).paddingOnly(top: 50)] else ...[ Container( padding: const EdgeInsets.all(16.0), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(12.0), boxShadow: [BoxShadow(color: Colors.grey.withOpacity(0.2), spreadRadius: 2, blurRadius: 5, offset: const Offset(0, 3))], ), child: Column( children: [ Row( children: [ "Current Ticket Balance".toText20().expanded, Row( children: [ const Icon(Icons.calendar_month_rounded, color: MyColors.darkIconColor, size: 16), 5.width, DateUtil.formatDateToDate(accrualDateTime, AppState().isArabic(context)).toText13(isUnderLine: true), 8.width, ], ).onPress(() async { DateTime selectedDate = await Utils.selectDate(context, accrualDateTime); if (selectedDate != accrualDateTime) { accrualDateTime = selectedDate; changeAccrualDate(true); } }), ], ), 8.height, Column( crossAxisAlignment: CrossAxisAlignment.start, children: dashboardProviderModel!.accrualTicketBalanceList!.map((GetTicketAccuralBalanceModel item) { return Padding( padding: const EdgeInsets.symmetric(vertical: 6.0), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ item.accuralPlanCode.toString().replaceAll('_', ' ').toCamelCase.toText14(), item.accrualNetEntitlement.toString().toText16(color: MyColors.textMixColor, isBold: true), ], ), ); }).toList(), ), ], ), ), const SizedBox(height: 21), dashboardProviderModel == null && dashboardProviderModel!.ticketHistoryTransactionList == null ? const SizedBox() : ListView( shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), children: [ "Tickets History".toText20().expanded, 12.height, ListView.separated( physics: const NeverScrollableScrollPhysics(), shrinkWrap: true, padding: EdgeInsets.zero, itemBuilder: (BuildContext cxt, int cardIndex) { List transactionDetails = dashboardProviderModel!.ticketHistoryTransactionList![cardIndex]; const Set allowedSegmentNames = { "TICKETS_ROUTE", "TRAVELER_NAME", "TICKETS_EFFECTIVE_DATE", "TICKET_ARRIVAL", "TICKET_AMOUNT", "TICKET_COMP_SHARE", "TICKET_EMP_SHARE", }; // Get items for display List uniqueDetails = transactionDetails .where( (CollectionTransaction item) => item.dISPLAYFLAG != 'N' && item.sEGMENTPROMPT != null && item.sEGMENTPROMPT!.isNotEmpty && allowedSegmentNames.contains(item.sEGMENTNAME), ) .toList(); // Get PEI_EXTRA_INFO_ID value for View PDF CollectionTransaction? peiExtraInfoItem = transactionDetails.firstWhere( (CollectionTransaction item) => item.aPPLICATIONCOLUMNNAME == "PEI_EXTRA_INFO_ID", orElse: () => CollectionTransaction(), ); num? peiExtraInfoId = peiExtraInfoItem.nUMBERVALUE; return Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [ ListView.builder( physics: const NeverScrollableScrollPhysics(), shrinkWrap: true, itemCount: (uniqueDetails.length / 2).ceil(), itemBuilder: (BuildContext context, int rowIndex) { int firstIndex = rowIndex * 2; int? secondIndex = (firstIndex + 1 < uniqueDetails.length) ? firstIndex + 1 : null; bool isLastRow = (rowIndex == (uniqueDetails.length / 2).ceil() - 1); CollectionTransaction item1 = uniqueDetails[firstIndex]; ItemDetailViewCol child1 = ItemDetailViewCol(item1.sEGMENTPROMPT!, item1.vARCHAR2VALUE ?? item1.nUMBERVALUE?.toString() ?? ""); Widget child2; if (secondIndex != null) { CollectionTransaction item2 = uniqueDetails[secondIndex]; child2 = ItemDetailViewCol(item2.sEGMENTPROMPT!, item2.vARCHAR2VALUE ?? item2.nUMBERVALUE?.toString() ?? ""); } else { child2 = const SizedBox(); // Empty widget if there is no second item } return ItemDetailGrid(child1, child2, isItLast: isLastRow); }, ), // View PDF link at the bottom if (peiExtraInfoId != null) ...[ const SizedBox(height: 5), Align( alignment: Alignment.centerRight, child: GestureDetector( onTap: () async { Utils.showLoading(context); try { GetEitAttachmentTicket? result = await dashboardProviderModel!.getTicketEitPDFDownload(peiExtraInfoId: peiExtraInfoId.toString()); if (result != null && result.getEitAttachmentList != null && result.getEitAttachmentList!.isNotEmpty) { String? base64Data = result.getEitAttachmentList!.first.fileData; if (base64Data != null && base64Data.isNotEmpty) { String fileName = result.getEitAttachmentList!.first.fileName!; await FileProcess.downloadFile(base64Data, fileName); Utils.hideLoading(context); FileProcess.openFile(fileName); } else { Utils.hideLoading(context); Utils.showToast("PDF data not available"); } } else { Utils.hideLoading(context); Utils.showToast("No attachment found"); } } catch (e) { Utils.hideLoading(context); Utils.showToast("Something Went Wrong"); } }, child: Padding(padding: const EdgeInsets.only(top: 8.0, left: 0.0, bottom: 8.0), child: "View PDF".toText14(isUnderLine: true, isBold: true)), ), ), ], ], ).objectContainerView(); }, separatorBuilder: (BuildContext cxt, int index) => 12.height, itemCount: dashboardProviderModel!.ticketHistoryTransactionList!.length, ), ], ), ], ], ).expanded, DefaultButton("Proceed For Booking", () { if (widget.url != null && widget.jwtToken != null) { Navigator.push(context, MaterialPageRoute(builder: (BuildContext context) => SsoLoginWebView(url: widget.url, jwtToken: widget.jwtToken))); } }).insideContainer, ], ), ); } }