From 7f877fae730515026a9633f981f8f638a6325bcb Mon Sep 17 00:00:00 2001 From: Faiz Hashmi Date: Thu, 18 Sep 2025 16:57:37 +0300 Subject: [PATCH] completed new design --- lib/constants/app_constants.dart | 4 + lib/views/common_widgets/app_footer.dart | 397 ++++++++++++------ .../components/priority_tickets.dart | 322 +++----------- .../components/ticket_item.dart | 232 +++++----- .../components/ticket_item_normal_card.dart | 4 +- .../main_queue_screen/main_queue_screen.dart | 11 + pubspec.lock | 8 + pubspec.yaml | 1 + 8 files changed, 460 insertions(+), 519 deletions(-) diff --git a/lib/constants/app_constants.dart b/lib/constants/app_constants.dart index 0e3a741..bb42a71 100644 --- a/lib/constants/app_constants.dart +++ b/lib/constants/app_constants.dart @@ -10,6 +10,9 @@ bool isNeedToBreakVoiceForArabic = true; bool isSpeechCompleted = true; class AppStrings { + static String timeRemainingText = "Time Remaining"; + static String namazTimeText = "Namaz Time"; + static String poweredBy = "Powered By"; static String appName = "QLine"; static String fontNamePoppins = "Poppins"; @@ -77,6 +80,7 @@ class AppColors { static Color greyContainerColor = const Color(0xFF4B5B6A); static Color newGreenColor = const Color(0xFF03A567); static Color newRedColor = const Color(0xFFEC1C2B); + static Color newRedColorWithLessOpacity = const Color(0x33FF0000); static Color lightBorderColor = const Color(0xFFEDEDED); static Color newVitalSignColor = greyContainerColor; diff --git a/lib/views/common_widgets/app_footer.dart b/lib/views/common_widgets/app_footer.dart index c09d402..a1590f5 100644 --- a/lib/views/common_widgets/app_footer.dart +++ b/lib/views/common_widgets/app_footer.dart @@ -1,18 +1,94 @@ +import 'dart:async'; // Add this import import 'package:flutter/material.dart'; import 'package:flutter_svg/svg.dart'; -import 'package:hmg_qline/view_models/queuing_view_model.dart'; import 'package:hmg_qline/view_models/screen_config_view_model.dart'; import 'package:hmg_qline/views/common_widgets/app_general_widgets.dart'; -import 'package:marquee/marquee.dart'; import 'package:provider/provider.dart'; import 'package:hmg_qline/constants/app_constants.dart'; import 'package:hmg_qline/utilities/enums.dart'; import 'package:hmg_qline/views/common_widgets/app_texts_widget.dart'; import 'package:hmg_qline/views/view_helpers/size_config.dart'; -class AppFooter extends StatelessWidget { +class AppFooter extends StatefulWidget { const AppFooter({super.key}); + @override + State createState() => _AppFooterState(); +} + +class _AppFooterState extends State { + Timer? _timer; + String _remainingTime = ""; + + @override + void initState() { + super.initState(); + _startTimer(); + } + + @override + void dispose() { + _timer?.cancel(); + super.dispose(); + } + + void _startTimer() { + _timer = Timer.periodic(const Duration(seconds: 1), (timer) { + if (mounted) { + setState(() { + _updateRemainingTime(); + }); + } + }); + _updateRemainingTime(); + } + + void _updateRemainingTime() { + final screenConfigVM = Provider.of(context, listen: false); + final nextPrayerTimeStr = screenConfigVM.nextPrayerTime; + + if (nextPrayerTimeStr.isEmpty) { + _remainingTime = ""; + return; + } + + try { + final now = DateTime.now(); + final timeParts = nextPrayerTimeStr.split(' '); + final timeStr = timeParts[0]; + final amPm = timeParts.length > 1 ? timeParts[1].toUpperCase() : 'AM'; + + final hourMin = timeStr.split(':'); + int hour = int.parse(hourMin[0]); + final minute = int.parse(hourMin[1]); + + if (amPm == 'PM' && hour != 12) { + hour += 12; + } else if (amPm == 'AM' && hour == 12) { + hour = 0; + } + + DateTime nextPrayer = DateTime(now.year, now.month, now.day, hour, minute); + + if (nextPrayer.isBefore(now)) { + nextPrayer = nextPrayer.add(const Duration(days: 1)); + } + + final difference = nextPrayer.difference(now); + + if (difference.isNegative) { + _remainingTime = "00:00:00"; + } else { + final hours = difference.inHours; + final minutes = difference.inMinutes % 60; + final seconds = difference.inSeconds % 60; + _remainingTime = "${hours.toString().padLeft(2, '0')}:${minutes.toString().padLeft(2, '0')}:${seconds.toString().padLeft(2, '0')}"; + } + } catch (e) { + _remainingTime = "00:00:00"; + } + } + Widget _buildStatusRow(String label, bool isConnected) { return Row( children: [ @@ -49,151 +125,208 @@ class AppFooter extends StatelessWidget { ); } + bool _isMoreThanOneHour(String timeString) { + if (timeString.isEmpty) return false; + + try { + final parts = timeString.split(':'); + if (parts.length >= 3) { + final hours = int.parse(parts[0]); + return hours >= 1; + } + } catch (e) { + return false; + } + return false; + } + + String _getHoursFromTime(String timeString) { + if (timeString.isEmpty) return "0"; + + try { + final parts = timeString.split(':'); + if (parts.length >= 3) { + final hours = int.parse(parts[0]); + final minutes = int.parse(parts[1]); + if (minutes > 30) { + return "${hours + 1}"; + } + return hours.toString(); + } + } catch (e) { + return "0"; + } + return "0"; + } + @override Widget build(BuildContext context) { - return Consumer(builder: (BuildContext context, ScreenConfigViewModel screenConfigVM, Widget? child) { - bool isPortrait = screenConfigVM.globalConfigurationsModel.orientationTypeEnum == ScreenOrientationEnum.portraitUp || - screenConfigVM.globalConfigurationsModel.orientationTypeEnum == ScreenOrientationEnum.portraitDown; - return Padding( - padding: EdgeInsets.symmetric( - horizontal: SizeConfig.getWidthMultiplier() * 4, - vertical: SizeConfig.getHeightMultiplier() * 0.14, - ), - child: Row( - children: [ - Expanded( - flex: 3, - child: customShadowSmoothContainer( - height: SizeConfig.getHeightMultiplier() * 0.8, - padding: EdgeInsets.symmetric( - horizontal: SizeConfig.getWidthMultiplier() * 3, - vertical: SizeConfig.getHeightMultiplier() * 0.1, - ), - child: Row( - crossAxisAlignment: CrossAxisAlignment.end, - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Row( - crossAxisAlignment: CrossAxisAlignment.end, - children: [ - Padding( - padding: EdgeInsets.only(top: SizeConfig.getHeightMultiplier()! * 0.1), - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - AppText( - AppStrings.poweredBy, - fontSize: SizeConfig.getWidthMultiplier()! * 1.5, - fontWeight: FontWeight.w400, - color: AppColors.darkGreyTextColor, - ), - AppText( - "v${screenConfigVM.currentScreenIP.replaceAll(".", "").replaceAll("0", "-")}(${AppConstants.currentBuildVersion})", - fontSize: SizeConfig.getWidthMultiplier()! * 1, - fontWeight: FontWeight.w400, - color: AppColors.darkGreyTextColor, - ), - ], - ), - ), - SizedBox(width: SizeConfig.getWidthMultiplier()!), - Padding( - padding: EdgeInsets.only(bottom: SizeConfig.getHeightMultiplier()! * 0.06), - child: Image.asset( - AppAssets.cloudLogo, - height: isPortrait ? SizeConfig.getHeightMultiplier()! * 0.6 : SizeConfig.getHeightMultiplier()! * 0.4, - ), - ), - ], - ), - Padding( - padding: isPortrait - ? EdgeInsets.only( - top: SizeConfig.getHeightMultiplier()! * 0.3, - ) - : EdgeInsets.only( - top: SizeConfig.getHeightMultiplier()! * 0.15, - ), - child: isPortrait - ? Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, + return Consumer( + builder: (BuildContext context, ScreenConfigViewModel screenConfigVM, Widget? child) { + bool isPortrait = screenConfigVM.globalConfigurationsModel.orientationTypeEnum == ScreenOrientationEnum.portraitUp || + screenConfigVM.globalConfigurationsModel.orientationTypeEnum == ScreenOrientationEnum.portraitDown; + + return Padding( + padding: EdgeInsets.symmetric( + horizontal: SizeConfig.getWidthMultiplier() * 4, + vertical: SizeConfig.getHeightMultiplier() * 0.14, + ), + child: Row( + children: [ + Expanded( + flex: 3, + child: customShadowSmoothContainer( + height: SizeConfig.getHeightMultiplier() * 0.8, + padding: EdgeInsets.symmetric( + horizontal: SizeConfig.getWidthMultiplier() * 3, + vertical: SizeConfig.getHeightMultiplier() * 0.1, + ), + child: Row( + crossAxisAlignment: CrossAxisAlignment.end, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Row( + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + Padding( + padding: EdgeInsets.only(top: SizeConfig.getHeightMultiplier()! * 0.1), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, children: [ - _buildStatusRow("Hub Status ", screenConfigVM.isHubConnected), - SizedBox(width: SizeConfig.getWidthMultiplier()! * 2), - _buildStatusRow("Network Status ", screenConfigVM.isInternetConnected), + AppText( + AppStrings.poweredBy, + fontSize: SizeConfig.getWidthMultiplier()! * 1.5, + fontWeight: FontWeight.w400, + color: AppColors.darkGreyTextColor, + ), + AppText( + "v${screenConfigVM.currentScreenIP.replaceAll(".", "").replaceAll("0", "-")}(${AppConstants.currentBuildVersion})", + fontSize: SizeConfig.getWidthMultiplier()! * 1, + fontWeight: FontWeight.w400, + color: AppColors.darkGreyTextColor, + ), ], - ) - : Column( + ), + ), + SizedBox(width: SizeConfig.getWidthMultiplier()!), + Padding( + padding: EdgeInsets.only(bottom: SizeConfig.getHeightMultiplier()! * 0.06), + child: Image.asset( + AppAssets.cloudLogo, + height: isPortrait ? SizeConfig.getHeightMultiplier()! * 0.6 : SizeConfig.getHeightMultiplier()! * 0.4, + ), + ), + ], + ), + Padding( + padding: isPortrait ? EdgeInsets.only(top: SizeConfig.getHeightMultiplier()! * 0.3) : EdgeInsets.only(top: SizeConfig.getHeightMultiplier()! * 0.15), + child: isPortrait + ? Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + _buildStatusRow("Hub Status ", screenConfigVM.isHubConnected), + SizedBox(width: SizeConfig.getWidthMultiplier()! * 2), + _buildStatusRow("Network Status ", screenConfigVM.isInternetConnected), + ], + ) + : Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + _buildStatusRow("Hub Status ", screenConfigVM.isHubConnected), + SizedBox(height: SizeConfig.getHeightMultiplier()! * 0.05), + _buildStatusRow("Network Status ", screenConfigVM.isInternetConnected), + ], + ), + ), + ], + ), + ), + ), + if (screenConfigVM.globalConfigurationsModel.isPrayerTimeReq) ...[ + SizedBox(width: SizeConfig.getWidthMultiplier()! * 1.7), + Directionality( + textDirection: screenConfigVM.globalConfigurationsModel.textDirection, + child: Expanded( + flex: isPortrait ? 2 : 3, + child: customShadowSmoothContainer( + height: SizeConfig.getHeightMultiplier() * 0.8, + padding: EdgeInsets.symmetric( + horizontal: isPortrait ? SizeConfig.getWidthMultiplier() * 3 : SizeConfig.getWidthMultiplier() * 1.5, + vertical: SizeConfig.getHeightMultiplier() * 0.1, + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + SizedBox( + width: SizeConfig.getWidthMultiplier() * 15, + child: Column( crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.center, children: [ - _buildStatusRow("Hub Status ", screenConfigVM.isHubConnected), SizedBox(height: SizeConfig.getHeightMultiplier()! * 0.05), - _buildStatusRow("Network Status ", screenConfigVM.isInternetConnected), + Padding( + padding: EdgeInsets.only(left: SizeConfig.getWidthMultiplier()! * 0.5), + child: AppText( + _isMoreThanOneHour(_remainingTime) ? AppStrings.namazTimeText : AppStrings.timeRemainingText, + fontSize: SizeConfig.getWidthMultiplier()! * 1.5, + fontFamily: AppStrings.fontNamePoppins, + ), + ), + _isMoreThanOneHour(_remainingTime) + ? AppText( + screenConfigVM.nextPrayerTime, + fontSize: SizeConfig.getWidthMultiplier()! * 3, + fontWeight: FontWeight.bold, + color: AppColors.newRedColor, + letterSpacing: 1.5, + ) + : AppText( + _remainingTime, + fontSize: SizeConfig.getWidthMultiplier()! * 3, + fontWeight: FontWeight.bold, + color: AppColors.newRedColor, + letterSpacing: 1.5, + ), ], ), - ), - ], - ), - ), - ), - if (screenConfigVM.globalConfigurationsModel.isPrayerTimeReq) ...[ - SizedBox(width: SizeConfig.getWidthMultiplier()! * 1.7), - Directionality( - textDirection: screenConfigVM.globalConfigurationsModel.textDirection, - child: Expanded( - flex: isPortrait ? 2 : 3, - child: customShadowSmoothContainer( - height: SizeConfig.getHeightMultiplier() * 0.8, - padding: EdgeInsets.symmetric( - horizontal: isPortrait ? SizeConfig.getWidthMultiplier() * 3 : SizeConfig.getWidthMultiplier() * 1.5, - vertical: SizeConfig.getHeightMultiplier() * 0.1, - ), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - AppText( - screenConfigVM.nextPrayerTime, - fontSize: SizeConfig.getWidthMultiplier()! * 3, - fontWeight: FontWeight.bold, - color: AppColors.newRedColor, - letterSpacing: 1.5, - ), - Row( - children: [ - if (screenConfigVM.nextPrayerToShowEng.isNotEmpty) ...[ - _buildPrayerColumn(screenConfigVM.globalConfigurationsModel.nextPrayerTextEng, "${screenConfigVM.nextPrayerToShowEng} "), - ], - if (screenConfigVM.nextPrayerToShowEng.isNotEmpty && screenConfigVM.nextPrayerToShowArb.isNotEmpty) ...[ - Padding( - padding: EdgeInsets.fromLTRB( - SizeConfig.getWidthMultiplier()! * 0.1, - SizeConfig.getHeightMultiplier()! * 0.18, - SizeConfig.getWidthMultiplier()! * 0.1, - 0, + ), + Row( + children: [ + if (screenConfigVM.nextPrayerToShowEng.isNotEmpty) ...[ + _buildPrayerColumn(screenConfigVM.globalConfigurationsModel.nextPrayerTextEng, "${screenConfigVM.nextPrayerToShowEng} "), + ], + if (screenConfigVM.nextPrayerToShowEng.isNotEmpty && screenConfigVM.nextPrayerToShowArb.isNotEmpty) ...[ + Padding( + padding: EdgeInsets.fromLTRB( + SizeConfig.getWidthMultiplier()! * 0.1, + SizeConfig.getHeightMultiplier()! * 0.18, + SizeConfig.getWidthMultiplier()! * 0.1, + 0, + ), + child: AppText("|", fontSize: SizeConfig.getWidthMultiplier()! * 1.8, color: AppColors.darkGreyTextColor), ), - child: AppText("|", fontSize: SizeConfig.getWidthMultiplier()! * 1.8, color: AppColors.darkGreyTextColor), - ), - ], - if (screenConfigVM.nextPrayerToShowArb.isNotEmpty) ...[ - _buildPrayerColumn(screenConfigVM.globalConfigurationsModel.nextPrayerTextArb, screenConfigVM.nextPrayerToShowArb, isForArabic: true), + ], + if (screenConfigVM.nextPrayerToShowArb.isNotEmpty) ...[ + _buildPrayerColumn(screenConfigVM.globalConfigurationsModel.nextPrayerTextArb, screenConfigVM.nextPrayerToShowArb, isForArabic: true), + ], ], - ], - ), - if (isPortrait) ...[ - SvgPicture.asset( - AppAssets.salahTimeIcon, - height: SizeConfig.getHeightMultiplier() * 0.5, ), + if (isPortrait) ...[ + SvgPicture.asset( + AppAssets.salahTimeIcon, + height: SizeConfig.getHeightMultiplier() * 0.5, + ), + ], ], - ], + ), ), ), ), - ), + ], ], - ], - ), - ); - }); + ), + ); + }, + ); } } diff --git a/lib/views/main_queue_screen/components/priority_tickets.dart b/lib/views/main_queue_screen/components/priority_tickets.dart index 9768d87..7caa641 100644 --- a/lib/views/main_queue_screen/components/priority_tickets.dart +++ b/lib/views/main_queue_screen/components/priority_tickets.dart @@ -1,185 +1,4 @@ -// import 'dart:developer'; -// -// import 'package:flutter/material.dart'; -// import 'package:hmg_qline/constants/app_constants.dart'; -// import 'package:hmg_qline/models/global_config_model.dart'; -// import 'package:hmg_qline/models/ticket_model.dart'; -// import 'package:hmg_qline/utilities/enums.dart'; -// import 'package:hmg_qline/views/common_widgets/app_general_widgets.dart'; -// import 'package:hmg_qline/views/main_queue_screen/components/ticket_item.dart'; -// import 'package:hmg_qline/views/main_queue_screen/components/ticket_item_calling_card.dart'; -// import 'package:hmg_qline/views/main_queue_screen/components/ticket_item_normal_card.dart'; -// import 'package:hmg_qline/views/view_helpers/size_config.dart'; -// import 'package:zo_animated_border/widget/zo_color_change_border.dart'; -// -// class PriorityTickets extends StatelessWidget { -// final List tickets; -// final GlobalConfigurationsModel globalConfigurationsModel; -// -// const PriorityTickets({required this.tickets, required this.globalConfigurationsModel, super.key}); -// -// @override -// Widget build(BuildContext context) { -// final TicketData firstTicket = tickets[0].ticketModel!; -// TicketData? secondTicket; -// List otherTickets = []; -// if (tickets.length > 1) { -// secondTicket = tickets[1].ticketModel!; -// } -// -// if (tickets.length > 3) { -// otherTickets = tickets.sublist(2, tickets.length); -// } -// -// log("tickets: ${tickets.length}"); -// -// return Directionality( -// textDirection: globalConfigurationsModel.textDirection, -// child: Column( -// mainAxisAlignment: MainAxisAlignment.center, -// crossAxisAlignment: CrossAxisAlignment.center, -// children: [ -// if (tickets.length == 1) ...[ -// QueueItemCallingCard( -// isGradientRequired: true, -// isBorderRequired: true, -// ticketNo: firstTicket.queueNo ?? '', -// scale: globalConfigurationsModel.screenTypeEnum == ScreenTypeEnum.roomLevelScreen ? 2 : 1.2, -// blink: true, -// roomNo: firstTicket.roomNo ?? '', -// roomText: (globalConfigurationsModel.qTypeEnum == QTypeEnum.appointment ? globalConfigurationsModel.roomTextEng : globalConfigurationsModel.counterTextEng) ?? "", -// roomTextAr: (globalConfigurationsModel.qTypeEnum == QTypeEnum.appointment ? globalConfigurationsModel.roomTextArb : globalConfigurationsModel.counterTextArb) ?? "", -// isClinicAdded: false, -// callTypeEnum: firstTicket.callTypeEnum, -// textDirection: globalConfigurationsModel.textDirection, -// screenTypeEnum: globalConfigurationsModel.screenTypeEnum, -// langTypeEnum: globalConfigurationsModel.screenLanguageEnum, -// globalConfigurationsModel: globalConfigurationsModel, -// ), -// ], -// if (tickets.length == 2) ...[ -// Row( -// children: [ -// Expanded( -// flex: 2, -// child: QueueItemCallingCard( -// isGradientRequired: true, -// isBorderRequired: true, -// ticketNo: firstTicket.queueNo ?? '', -// scale: globalConfigurationsModel.screenTypeEnum == ScreenTypeEnum.roomLevelScreen ? 2 : 1.2, -// blink: true, -// roomNo: firstTicket.roomNo ?? '', -// roomText: (globalConfigurationsModel.qTypeEnum == QTypeEnum.appointment ? globalConfigurationsModel.roomTextEng : globalConfigurationsModel.counterTextEng) ?? "", -// roomTextAr: (globalConfigurationsModel.qTypeEnum == QTypeEnum.appointment ? globalConfigurationsModel.roomTextArb : globalConfigurationsModel.counterTextArb) ?? "", -// isClinicAdded: false, -// callTypeEnum: firstTicket.callTypeEnum, -// textDirection: globalConfigurationsModel.textDirection, -// screenTypeEnum: globalConfigurationsModel.screenTypeEnum, -// langTypeEnum: globalConfigurationsModel.screenLanguageEnum, -// globalConfigurationsModel: globalConfigurationsModel, -// ), -// ), -// SizedBox(width: SizeConfig.getWidthMultiplier() * 2), -// Expanded( -// flex: 1, -// child: QueueItemNormalCard( -// ticketNo: secondTicket!.queueNo ?? '', -// roomNo: secondTicket.roomNo ?? '', -// roomText: (globalConfigurationsModel.qTypeEnum == QTypeEnum.appointment ? globalConfigurationsModel.roomTextEng : globalConfigurationsModel.counterTextEng) ?? "", -// roomTextAr: (globalConfigurationsModel.qTypeEnum == QTypeEnum.appointment ? globalConfigurationsModel.roomTextArb : globalConfigurationsModel.counterTextArb) ?? "", -// isClinicAdded: false, -// callTypeEnum: secondTicket.callTypeEnum, -// textDirection: globalConfigurationsModel.textDirection, -// screenTypeEnum: globalConfigurationsModel.screenTypeEnum, -// langTypeEnum: globalConfigurationsModel.screenLanguageEnum, -// globalConfigurationsModel: globalConfigurationsModel, -// ), -// ), -// ], -// ), -// ], -// if (tickets.length > 2) ...[ -// Column( -// children: [ -// Row( -// children: [ -// Expanded( -// flex: 2, -// child: QueueItemCallingCard( -// isGradientRequired: true, -// isBorderRequired: true, -// ticketNo: firstTicket.queueNo ?? '', -// scale: globalConfigurationsModel.screenTypeEnum == ScreenTypeEnum.roomLevelScreen ? 2 : 1.2, -// blink: true, -// roomNo: firstTicket.roomNo ?? '', -// roomText: (globalConfigurationsModel.qTypeEnum == QTypeEnum.appointment ? globalConfigurationsModel.roomTextEng : globalConfigurationsModel.counterTextEng) ?? "", -// roomTextAr: (globalConfigurationsModel.qTypeEnum == QTypeEnum.appointment ? globalConfigurationsModel.roomTextArb : globalConfigurationsModel.counterTextArb) ?? "", -// isClinicAdded: false, -// callTypeEnum: firstTicket.callTypeEnum, -// textDirection: globalConfigurationsModel.textDirection, -// screenTypeEnum: globalConfigurationsModel.screenTypeEnum, -// langTypeEnum: globalConfigurationsModel.screenLanguageEnum, -// globalConfigurationsModel: globalConfigurationsModel, -// ), -// ), -// SizedBox(width: SizeConfig.getWidthMultiplier() * 2), -// Expanded( -// flex: 1, -// child: QueueItemNormalCard( -// ticketNo: secondTicket!.queueNo ?? '', -// roomNo: secondTicket.roomNo ?? '', -// roomText: (globalConfigurationsModel.qTypeEnum == QTypeEnum.appointment ? globalConfigurationsModel.roomTextEng : globalConfigurationsModel.counterTextEng) ?? "", -// roomTextAr: (globalConfigurationsModel.qTypeEnum == QTypeEnum.appointment ? globalConfigurationsModel.roomTextArb : globalConfigurationsModel.counterTextArb) ?? "", -// isClinicAdded: false, -// callTypeEnum: secondTicket.callTypeEnum, -// textDirection: globalConfigurationsModel.textDirection, -// screenTypeEnum: globalConfigurationsModel.screenTypeEnum, -// langTypeEnum: globalConfigurationsModel.screenLanguageEnum, -// globalConfigurationsModel: globalConfigurationsModel, -// ), -// ), -// ], -// ), -// Padding( -// padding: EdgeInsets.symmetric(vertical: SizeConfig.getHeightMultiplier() * 0.1), -// child: engArabicTextWithSeparatorWidget( -// englishText: globalConfigurationsModel.currentServeTextEng ?? "", -// arabicText: globalConfigurationsModel.currentServeTextArb ?? "", -// ), -// ), -// Row( -// children: List.generate( -// otherTickets.length, -// (index) => Expanded( -// child: Padding( -// padding: EdgeInsets.only(right: index != otherTickets.length - 1 ? SizeConfig.getWidthMultiplier() * 2 : 0), -// child: QueueItemNormalCard( -// ticketNo: otherTickets[index].ticketModel!.queueNo ?? '', -// roomNo: otherTickets[index].ticketModel!.roomNo ?? '', -// roomText: (globalConfigurationsModel.qTypeEnum == QTypeEnum.appointment ? globalConfigurationsModel.roomTextEng : globalConfigurationsModel.counterTextEng) ?? "", -// roomTextAr: (globalConfigurationsModel.qTypeEnum == QTypeEnum.appointment ? globalConfigurationsModel.roomTextArb : globalConfigurationsModel.counterTextArb) ?? "", -// isClinicAdded: false, -// callTypeEnum: otherTickets[index].ticketModel!.callTypeEnum, -// textDirection: globalConfigurationsModel.textDirection, -// screenTypeEnum: globalConfigurationsModel.screenTypeEnum, -// langTypeEnum: globalConfigurationsModel.screenLanguageEnum, -// globalConfigurationsModel: globalConfigurationsModel, -// ), -// ), -// ), -// ), -// ), -// ], -// ), -// ], -// ], -// ), -// ); -// } -// } - import 'dart:developer'; - import 'package:flutter/material.dart'; import 'package:hmg_qline/models/global_config_model.dart'; import 'package:hmg_qline/models/ticket_model.dart'; @@ -212,46 +31,20 @@ class PriorityTickets extends StatelessWidget { ); } - Widget _buildAnimatedTicket({required Widget child, required int delay, String? key}) { - return TweenAnimationBuilder( - key: key != null ? ValueKey(key) : null, - duration: Duration(milliseconds: 400 + delay), - tween: Tween(begin: 0.0, end: 1.0), - curve: Curves.easeOutCubic, - // Changed from elasticOut to prevent overshoot - builder: (context, value, child) { - final clampedValue = value.clamp(0.0, 1.0); - - return Transform.scale( - scale: 0.8 + (clampedValue * 0.2), // Scale from 0.8 to 1.0 instead of 0 to 1 - child: Opacity( - opacity: clampedValue, - child: child, - ), - ); - }, - child: child, - ); - } - - Widget _buildAnimatedOtherTicketsRow() { - final otherTickets = tickets.length > 2 ? tickets.sublist(2) : []; + Widget _buildAnimatedOtherTicketsRow(BuildContext context, {required int noOfTicketsToSkipFromStart, bool isHalf = false}) { + final otherTickets = tickets.length > 2 ? tickets.sublist(noOfTicketsToSkipFromStart) : []; if (otherTickets.isEmpty) return const SizedBox.shrink(); return Row( children: List.generate( otherTickets.length, (index) => Expanded( - child: _buildAnimatedTicket( - key: 'other_ticket_${otherTickets[index].ticketModel?.queueNo ?? index}', - child: Padding( - padding: EdgeInsets.only( - right: (index != otherTickets.length - 1 && globalConfigurationsModel.textDirection == TextDirection.ltr) ? SizeConfig.getWidthMultiplier() * 2 : 0, - left: (index != otherTickets.length - 1 && globalConfigurationsModel.textDirection == TextDirection.rtl) ? SizeConfig.getWidthMultiplier() * 2 : 0, - ), - child: _buildSecondaryTicket(otherTickets[index]), + child: Padding( + padding: EdgeInsets.only( + right: (index != otherTickets.length - 1 && globalConfigurationsModel.textDirection == TextDirection.ltr) ? SizeConfig.getWidthMultiplier() * 2 : 0, + left: (index != otherTickets.length - 1 && globalConfigurationsModel.textDirection == TextDirection.rtl) ? SizeConfig.getWidthMultiplier() * 2 : 0, ), - delay: 200 + (index * 100), + child: _buildSecondaryTicket(context, otherTickets[index], isHalf: isHalf), ), ), ), @@ -260,37 +53,24 @@ class PriorityTickets extends StatelessWidget { List _buildTicketLayout(BuildContext context) { if (tickets.isEmpty) return []; - log("tickets.length: ${tickets.length}"); + switch (tickets.length) { case 1: + return [_buildPrimaryTicket(context, tickets[0], isFullWidth: true)]; + + case 2: return [ - _buildAnimatedTicket( - child: _buildPrimaryTicket(context, tickets[0], isFullWidth: true), - delay: 0, - ), + _buildPrimaryTicket(context, tickets[0], isHalf: true), + _buildCurrentServeText(), + _buildSecondaryTicket(context, tickets[1], isHalf: true), ]; - case 2: + case 3: + case 4: return [ - Row( - children: [ - Expanded( - flex: 3, - child: _buildAnimatedTicket( - child: _buildPrimaryTicket(context, tickets[0]), - delay: 0, - ), - ), - _buildSpacing(), - Expanded( - flex: 2, - child: _buildAnimatedTicket( - child: _buildSecondaryTicket(tickets[1]), - delay: 150, - ), - ), - ], - ), + _buildPrimaryTicket(context, tickets[0], isHalf: true), + _buildCurrentServeText(), + _buildAnimatedOtherTicketsRow(context, noOfTicketsToSkipFromStart: 1, isHalf: true), ]; default: @@ -299,28 +79,22 @@ class PriorityTickets extends StatelessWidget { children: [ Expanded( flex: 2, - child: _buildAnimatedTicket( - child: _buildPrimaryTicket(context, tickets[0]), - delay: 0, - ), + child: _buildPrimaryTicket(context, tickets[0]), ), _buildSpacing(), Expanded( flex: 1, - child: _buildAnimatedTicket( - child: _buildSecondaryTicket(tickets[1]), - delay: 100, - ), + child: _buildSecondaryTicket(context, tickets[1]), ), ], ), _buildCurrentServeText(), - _buildAnimatedOtherTicketsRow(), + _buildAnimatedOtherTicketsRow(context, noOfTicketsToSkipFromStart: 2), ]; } } - Widget _buildPrimaryTicket(BuildContext context, TicketDetailsModel ticket, {bool isFullWidth = false}) { + Widget _buildPrimaryTicket(BuildContext context, TicketDetailsModel ticket, {bool isFullWidth = false, bool isHalf = false}) { Widget primaryCallingCard = QueueItemCallingCard( isGradientRequired: true, isBorderRequired: true, @@ -339,6 +113,21 @@ class PriorityTickets extends StatelessWidget { globalConfigurationsModel: globalConfigurationsModel, ); + if (isHalf) { + return Center( + child: ConstrainedBox( + constraints: BoxConstraints( + maxWidth: MediaQuery.of(context).size.width * 0.7, // 60% of screen width + minHeight: SizeConfig.getHeightMultiplier() * 2.2, // Minimum height + ), + child: Transform.scale( + scale: _getTicketScale(), + child: primaryCallingCard, + ), + ), + ); + } + if (isFullWidth) { return Center( child: ConstrainedBox( @@ -357,8 +146,8 @@ class PriorityTickets extends StatelessWidget { return primaryCallingCard; } - Widget _buildSecondaryTicket(TicketDetailsModel ticket) { - return QueueItemNormalCard( + Widget _buildSecondaryTicket(BuildContext context, TicketDetailsModel ticket, {bool isHalf = false}) { + Widget secondaryCallingCard = QueueItemNormalCard( ticketNo: ticket.ticketModel?.queueNo ?? '', roomNo: ticket.ticketModel?.roomNo ?? '', roomText: _getRoomText(), @@ -370,31 +159,26 @@ class PriorityTickets extends StatelessWidget { langTypeEnum: globalConfigurationsModel.screenLanguageEnum, globalConfigurationsModel: globalConfigurationsModel, ); - } - Widget _buildOtherTicketsRow(TextDirection textDirection) { - final otherTickets = tickets.length > 2 ? tickets.sublist(2) : []; - if (otherTickets.isEmpty) return const SizedBox.shrink(); - - return Row( - children: List.generate( - otherTickets.length, - (index) => Expanded( - child: Padding( - padding: EdgeInsets.only( - right: (index != otherTickets.length - 1 && textDirection == TextDirection.ltr) ? SizeConfig.getWidthMultiplier() * 2 : 0, - left: (index != otherTickets.length - 1 && textDirection == TextDirection.rtl) ? SizeConfig.getWidthMultiplier() * 2 : 0, - ), - child: _buildSecondaryTicket(otherTickets[index]), + if (isHalf) { + return Center( + child: ConstrainedBox( + constraints: BoxConstraints( + maxWidth: MediaQuery.of(context).size.width * 0.65, // 60% of screen width + minHeight: SizeConfig.getHeightMultiplier() * 2, // Minimum height ), + child: secondaryCallingCard, ), - ), - ); + ); + } + + return secondaryCallingCard; } Widget _buildCurrentServeText() { + bool isPortrait = globalConfigurationsModel.orientationTypeEnum == ScreenOrientationEnum.portraitUp || globalConfigurationsModel.orientationTypeEnum == ScreenOrientationEnum.portraitDown; return Padding( - padding: EdgeInsets.symmetric(vertical: SizeConfig.getHeightMultiplier() * 0.13), + padding: EdgeInsets.symmetric(vertical: isPortrait ? SizeConfig.getHeightMultiplier() * 0.13 : SizeConfig.getHeightMultiplier() * 0.25), child: engArabicTextWithSeparatorWidget( englishText: globalConfigurationsModel.currentServeTextEng ?? "", arabicText: globalConfigurationsModel.currentServeTextArb ?? "", diff --git a/lib/views/main_queue_screen/components/ticket_item.dart b/lib/views/main_queue_screen/components/ticket_item.dart index 30898eb..a68d370 100644 --- a/lib/views/main_queue_screen/components/ticket_item.dart +++ b/lib/views/main_queue_screen/components/ticket_item.dart @@ -1,116 +1,116 @@ -import 'package:blinking_text/blinking_text.dart'; -import 'package:flutter/material.dart'; -import 'package:hmg_qline/constants/app_constants.dart'; -import 'package:hmg_qline/models/global_config_model.dart'; -import 'package:hmg_qline/utilities/enums.dart'; -import 'package:hmg_qline/utilities/extensions.dart'; -import 'package:hmg_qline/views/common_widgets/app_texts_widget.dart'; -import 'package:hmg_qline/views/view_helpers/size_config.dart'; - -class TicketItem extends StatelessWidget { - final String ticketNo; - final String roomNo; - final bool blink; - final double scale; - final bool isClinicAdded; - final TextDirection textDirection; - final String roomText; - final GlobalConfigurationsModel globalConfigurationsModel; - final CallTypeEnum callTypeEnum; - final ScreenTypeEnum screenTypeEnum; - final LanguageEnum langTypeEnum; - - const TicketItem({ - super.key, - required this.isClinicAdded, - required this.ticketNo, - required this.roomNo, - required this.scale, - required this.textDirection, - required this.roomText, - required this.globalConfigurationsModel, - required this.callTypeEnum, - required this.screenTypeEnum, - required this.langTypeEnum, - this.blink = false, - }); - - String getFormattedTicket(String ticketNo, bool isClinicAdded) { - if (isClinicAdded) { - var formattedString = ticketNo.split(" "); - if (formattedString.length > 1) { - return "${formattedString[0]} ${formattedString[1]}"; - } else { - return ticketNo; - } - } - return ticketNo; - } - - @override - Widget build(BuildContext context) { - return Transform.scale( - scale: scale, - child: Column( - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - BlinkText(getFormattedTicket(ticketNo, isClinicAdded), - style: TextStyle( - fontSize: SizeConfig.getWidthMultiplier() * 10, - letterSpacing: -1, - height: 0.5, - fontWeight: FontWeight.bold, - fontFamily: langTypeEnum == LanguageEnum.arabic ? AppStrings.fontNameCairo : AppStrings.fontNamePoppins, - ), - beginColor: Colors.black, - endColor: blink ? Colors.black.withOpacity(0.1) : Colors.black, - times: 0, - duration: const Duration(seconds: 1)), - const SizedBox(height: 30), - screenTypeEnum == ScreenTypeEnum.roomLevelScreen - ? const SizedBox() - : Directionality( - textDirection: textDirection, - child: Row( - crossAxisAlignment: CrossAxisAlignment.end, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Padding( - padding: const EdgeInsets.only(bottom: 8.0), - child: SizedBox( - height: SizeConfig.getWidthMultiplier() * 3, - child: callTypeEnum.getIconByCallType(SizeConfig.getHeightMultiplier() * 0.3), - ), - ), - const SizedBox(width: 13), - AppText( - callTypeEnum.getMessageByCallTypeForEnglish(globalConfigurationsModel, isListView: false), - color: callTypeEnum.getColorByCallType(), - fontSize: SizeConfig.getWidthMultiplier() * 3.8, - fontWeight: FontWeight.w600, - fontHeight: 1, - fontFamily: langTypeEnum == LanguageEnum.arabic ? AppStrings.fontNameCairo : AppStrings.fontNamePoppins, - ), - Container( - color: Colors.grey.withOpacity(0.5), - width: 5, - height: SizeConfig.getHeightMultiplier() * 0.3, - margin: const EdgeInsets.symmetric(horizontal: 15), - ), - AppText( - textDirection == TextDirection.ltr ? "$roomText: $roomNo" : " $roomNo : $roomText", - color: callTypeEnum.getColorByCallType(), - letterSpacing: -1, - fontSize: SizeConfig.getWidthMultiplier() * 3.8, - fontWeight: FontWeight.w600, - fontHeight: 1, - fontFamily: langTypeEnum == LanguageEnum.arabic ? AppStrings.fontNameCairo : AppStrings.fontNamePoppins, - ), - ], - ), - ), - ], - ), - ); - } -} +// import 'package:blinking_text/blinking_text.dart'; +// import 'package:flutter/material.dart'; +// import 'package:hmg_qline/constants/app_constants.dart'; +// import 'package:hmg_qline/models/global_config_model.dart'; +// import 'package:hmg_qline/utilities/enums.dart'; +// import 'package:hmg_qline/utilities/extensions.dart'; +// import 'package:hmg_qline/views/common_widgets/app_texts_widget.dart'; +// import 'package:hmg_qline/views/view_helpers/size_config.dart'; +// +// class TicketItem extends StatelessWidget { +// final String ticketNo; +// final String roomNo; +// final bool blink; +// final double scale; +// final bool isClinicAdded; +// final TextDirection textDirection; +// final String roomText; +// final GlobalConfigurationsModel globalConfigurationsModel; +// final CallTypeEnum callTypeEnum; +// final ScreenTypeEnum screenTypeEnum; +// final LanguageEnum langTypeEnum; +// +// const TicketItem({ +// super.key, +// required this.isClinicAdded, +// required this.ticketNo, +// required this.roomNo, +// required this.scale, +// required this.textDirection, +// required this.roomText, +// required this.globalConfigurationsModel, +// required this.callTypeEnum, +// required this.screenTypeEnum, +// required this.langTypeEnum, +// this.blink = false, +// }); +// +// String getFormattedTicket(String ticketNo, bool isClinicAdded) { +// if (isClinicAdded) { +// var formattedString = ticketNo.split(" "); +// if (formattedString.length > 1) { +// return "${formattedString[0]} ${formattedString[1]}"; +// } else { +// return ticketNo; +// } +// } +// return ticketNo; +// } +// +// @override +// Widget build(BuildContext context) { +// return Transform.scale( +// scale: scale, +// child: Column( +// crossAxisAlignment: CrossAxisAlignment.center, +// children: [ +// BlinkText(getFormattedTicket(ticketNo, isClinicAdded), +// style: TextStyle( +// fontSize: SizeConfig.getWidthMultiplier() * 10, +// letterSpacing: -1, +// height: 0.5, +// fontWeight: FontWeight.bold, +// fontFamily: langTypeEnum == LanguageEnum.arabic ? AppStrings.fontNameCairo : AppStrings.fontNamePoppins, +// ), +// beginColor: Colors.black, +// endColor: blink ? Colors.black.withOpacity(0.1) : Colors.black, +// times: 0, +// duration: const Duration(seconds: 1)), +// const SizedBox(height: 30), +// screenTypeEnum == ScreenTypeEnum.roomLevelScreen +// ? const SizedBox() +// : Directionality( +// textDirection: textDirection, +// child: Row( +// crossAxisAlignment: CrossAxisAlignment.end, +// mainAxisAlignment: MainAxisAlignment.center, +// children: [ +// Padding( +// padding: const EdgeInsets.only(bottom: 8.0), +// child: SizedBox( +// height: SizeConfig.getWidthMultiplier() * 3, +// child: callTypeEnum.getIconByCallType(SizeConfig.getHeightMultiplier() * 0.3), +// ), +// ), +// const SizedBox(width: 13), +// AppText( +// callTypeEnum.getMessageByCallTypeForEnglish(globalConfigurationsModel, isListView: false), +// color: callTypeEnum.getColorByCallType(), +// fontSize: SizeConfig.getWidthMultiplier() * 3.8, +// fontWeight: FontWeight.w600, +// fontHeight: 1, +// fontFamily: langTypeEnum == LanguageEnum.arabic ? AppStrings.fontNameCairo : AppStrings.fontNamePoppins, +// ), +// Container( +// color: Colors.grey.withOpacity(0.5), +// width: 5, +// height: SizeConfig.getHeightMultiplier() * 0.3, +// margin: const EdgeInsets.symmetric(horizontal: 15), +// ), +// AppText( +// textDirection == TextDirection.ltr ? "$roomText: $roomNo" : " $roomNo : $roomText", +// color: callTypeEnum.getColorByCallType(), +// letterSpacing: -1, +// fontSize: SizeConfig.getWidthMultiplier() * 3.8, +// fontWeight: FontWeight.w600, +// fontHeight: 1, +// fontFamily: langTypeEnum == LanguageEnum.arabic ? AppStrings.fontNameCairo : AppStrings.fontNamePoppins, +// ), +// ], +// ), +// ), +// ], +// ), +// ); +// } +// } diff --git a/lib/views/main_queue_screen/components/ticket_item_normal_card.dart b/lib/views/main_queue_screen/components/ticket_item_normal_card.dart index f0706fe..a5e0387 100644 --- a/lib/views/main_queue_screen/components/ticket_item_normal_card.dart +++ b/lib/views/main_queue_screen/components/ticket_item_normal_card.dart @@ -97,7 +97,7 @@ class QueueItemNormalCard extends StatelessWidget { SizedBox(height: SizeConfig.getHeightMultiplier()! * 0.14), AppText( textAlign: TextAlign.center, - callTypeEnum.getMessageByCallTypeForArabic(globalConfigurationsModel, isListView: false), + "${callTypeEnum.getMessageByCallTypeForArabic(globalConfigurationsModel, isListView: false)} ", color: callTypeEnum.getColorByCallType(), fontSize: SizeConfig.getWidthMultiplier() * 2, fontHeight: 1, @@ -115,7 +115,7 @@ class QueueItemNormalCard extends StatelessWidget { child: AppText( text, color: callTypeEnum.getColorByCallType(), - fontSize: SizeConfig.getWidthMultiplier() * 1.6, + fontSize: SizeConfig.getWidthMultiplier() * 1.5, fontFamily: AppStrings.fontNamePoppins, textAlign: TextAlign.left, textOverflow: TextOverflow.clip, diff --git a/lib/views/main_queue_screen/main_queue_screen.dart b/lib/views/main_queue_screen/main_queue_screen.dart index 8a3ca0d..5cbfcb7 100644 --- a/lib/views/main_queue_screen/main_queue_screen.dart +++ b/lib/views/main_queue_screen/main_queue_screen.dart @@ -57,6 +57,17 @@ class _MainQueueScreenState extends State { String text = AppStrings.awaitingArrivalEng; String fontFamily = AppStrings.fontNamePoppins; + // return Center(child: Image.asset("assets/images/majnu.JPG", fit: BoxFit.fill)); + // return intimationWidget( + // text: "Sarkar Farmanday nayy\n Jera Dhamaal naa Pavay.... !!", + // fontName: AppStrings.fontNamePoppins, + // isForRoomLevel: false, + // isRoomNoRequired: false, + // isForError: true, + // counterNo: 0, + // roomText: '', + // ); + if (screenConfigViewModel.currentQTypeEnum == QTypeEnum.general) { text = AppStrings.awaitingQueueNumberEng; } diff --git a/pubspec.lock b/pubspec.lock index 946f3b5..241b66a 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -1,6 +1,14 @@ # Generated by pub # See https://dart.dev/tools/pub/glossary#lockfile packages: + animated_flip_counter: + dependency: "direct main" + description: + name: animated_flip_counter + sha256: "73f852d84c461c3e4c1ddf320bee334dde8dba89441922ab11a8013be0b2fad1" + url: "https://pub.dev" + source: hosted + version: "0.3.4" args: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index a586f40..9abc469 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -56,6 +56,7 @@ dependencies: flutter_foreground_task: ^9.1.0 restart_app: ^1.3.2 zo_animated_border: ^1.0.1 + animated_flip_counter: ^0.3.4 # esc_pos_printer: ^4.0.0 # Ensure you are using the latest version # esc_pos_utils: ^1.0.0