Microsoft Clarity implementation contd.

haroon_dev
haroon amjad 1 week ago
parent 4eb4d0b37d
commit 1750c7dc44

@ -3,6 +3,7 @@ import 'dart:convert';
import 'dart:developer';
import 'dart:io';
import 'package:clarity_flutter/clarity_flutter.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
@ -264,6 +265,11 @@ class ApiClientImp implements ApiClient {
final message = e.message.contains('Connection reset by peer') ? LocaleKeys.networkConnectionReset.tr() : LocaleKeys.networkErrorMessage.tr();
onFailure(message, -1, failureType: ConnectivityFailure(message));
_analytics.errorTracking.log(endPoint, error: "SocketException: $e");
Clarity.setCustomTag('api_err_url', _getEndofUrl(url.trim()));
Clarity.setCustomTag('api_err_request', _sanitizeRequestBody(requestBody));
Clarity.sendCustomEvent('api_failure');
return;
} on http.ClientException catch (e) {
final message = e.message.contains('Connection reset by peer') ? LocaleKeys.networkConnectionReset.tr() : LocaleKeys.networkErrorMessage.tr();
@ -274,6 +280,10 @@ class ApiClientImp implements ApiClient {
final message = LocaleKeys.networkTimeout.tr();
onFailure(message, -1, failureType: ConnectivityFailure(message));
_analytics.errorTracking.log(endPoint, error: "TimeoutException");
Clarity.setCustomTag('api_err_url', _getEndofUrl(url.trim()));
Clarity.setCustomTag('api_err_request', _sanitizeRequestBody(requestBody));
Clarity.sendCustomEvent('api_timeout_failure');
return;
} catch (e) {
final message = LocaleKeys.networkUnknownError.tr();
@ -287,6 +297,11 @@ class ApiClientImp implements ApiClient {
if (statusCode < 200 || statusCode >= 400) {
onFailure(LocaleKeys.networkErrorWhileFetching.tr(), statusCode, failureType: StatusCodeFailure(LocaleKeys.networkErrorWhileFetching.tr()));
logApiEndpointError(endPoint, LocaleKeys.networkErrorWhileFetching.tr(), statusCode);
Clarity.setCustomTag('api_err_url', _getEndofUrl(url.trim()));
Clarity.setCustomTag('api_err_request', _sanitizeRequestBody(requestBody));
Clarity.setCustomTag('api_err_status', statusCode.toString());
Clarity.sendCustomEvent('api_status_code_failure');
} else {
var parsed = json.decode(utf8.decode(response.bodyBytes));
if (isAllowAny) {
@ -388,6 +403,11 @@ class ApiClientImp implements ApiClient {
);
logApiEndpointError(endPoint, parsed['message'] ?? parsed['message'], statusCode);
}
Clarity.setCustomTag('api_err_url', _getEndofUrl(url.trim()));
Clarity.setCustomTag('api_err_request', _sanitizeRequestBody(requestBody));
Clarity.setCustomTag('api_err_status', statusCode.toString());
Clarity.sendCustomEvent('api_message_status_failure');
}
} else {
if (parsed['SameClinicApptList'] != null) {
@ -666,4 +686,42 @@ class ApiClientImp implements ApiClient {
logApiEndpointError(String endPoint, error, code) {
_analytics.errorTracking.log(endPoint, error: error);
}
String _getEndofUrl(String url) {
const int clarityLimit = 255;
if (url.length <= clarityLimit) return url;
// Extracts the final 252 characters and prepends '...'
return '...${url.substring(url.length - (clarityLimit - 3))}';
}
String _sanitizeRequestBody(String body) {
if (body.isEmpty) return '';
try {
// Handle standard JSON bodies
final Map<String, dynamic> data = json.decode(body);
// Case-insensitive key matching and removal
data.removeWhere((key, value) => key.toLowerCase() == 'sessionid' || key.toLowerCase() == 'tokenid');
return json.encode(data);
} catch (_) {
// Fallback: Handle Form URL Encoded strings or raw key-value pairs (SessionID=XYZ&TokenID=abc)
String modifiedBody = body;
final sensitiveKeys = ['SessionID', 'TokenID'];
for (var key in sensitiveKeys) {
// Matches "key=value" surrounded by standard query delimiters
final regExp = RegExp(r'' + key + r'=[^&]*&?', caseSensitive: false);
modifiedBody = modifiedBody.replaceAll(regExp, '');
}
// Clean up any trailing trailing ampersands
if (modifiedBody.endsWith('&')) {
modifiedBody = modifiedBody.substring(0, modifiedBody.length - 1);
}
return modifiedBody;
}
}
}

@ -49,8 +49,8 @@ class AppState {
bool isPaytabsEnabled = false;
void setIsPaytabsEnabled(bool value) {
// isPaytabsEnabled = value;
isPaytabsEnabled = false;
isPaytabsEnabled = value;
// isPaytabsEnabled = false;
}
int? _superUserID;

@ -1,6 +1,7 @@
import 'dart:async';
import 'dart:io';
import 'package:clarity_flutter/clarity_flutter.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
@ -139,6 +140,7 @@ class OTPWidgetState extends State<OTPWidget> with SingleTickerProviderStateMixi
@override
void initState() {
Clarity.setCurrentScreenName('OTP Verification Screen');
super.initState();
authVm = context.read<AuthenticationViewModel>();
focusNode = widget.focusNode ?? FocusNode();

@ -1,6 +1,7 @@
import 'package:flutter/material.dart';
import 'package:flutter_paytabs_bridge/BaseBillingShippingInfo.dart';
import 'package:flutter_paytabs_bridge/IOSThemeConfiguration.dart';
import 'package:flutter_paytabs_bridge/PaymentSDKNetworks.dart';
import 'package:flutter_paytabs_bridge/PaymentSdkConfigurationDetails.dart';
import 'package:flutter_paytabs_bridge/PaymentSdkLocale.dart';
import 'package:flutter_paytabs_bridge/PaymentSdkTokenFormat.dart';

@ -2,6 +2,7 @@ import 'dart:async';
import 'dart:io';
import 'dart:ui' as ui;
import 'package:clarity_flutter/clarity_flutter.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:hmg_patient_app_new/core/api_consts.dart';
@ -85,6 +86,7 @@ class _AppointmentDetailsPageState extends State<AppointmentDetailsPage> {
@override
void initState() {
Clarity.setCurrentScreenName('Appointment Details Page');
super.initState();
scheduleMicrotask(() async {
@ -892,39 +894,36 @@ class _AppointmentDetailsPageState extends State<AppointmentDetailsPage> {
showCommonBottomSheetWithoutHeight(
title: LocaleKeys.parkingQR.tr(context: context),
context,
child: SizedBox(
// height: 150.h,
child: Column(
children: [
LocaleKeys.parkingQRDesc.tr(context: context).toText16(),
SizedBox(height: 16.h),
Image.memory(
myAppointmentsViewModel.parkingQRImageBytes!,
width: 156.w,
height: 156.h,
fit: BoxFit.cover,
gaplessPlayback: true, // Prevents blink during image rebuild
),
SizedBox(height: 16.h),
CustomButton(
text: LocaleKeys.done.tr(context: context),
onPressed: () {
openDoctorScheduleCalendar();
},
backgroundColor: AppColors.primaryRedColor,
borderColor: AppColors.primaryRedColor,
textColor: Colors.white,
fontSize: 16.f,
fontWeight: FontWeight.w600,
borderRadius: 12.r,
padding: EdgeInsets.symmetric(horizontal: 10.w),
height: 50.h,
icon: AppAssets.checkmark_icon,
iconColor: Colors.white,
iconSize: 18.h,
).paddingSymmetrical(0.h, 0.h),
],
),
child: Column(
children: [
LocaleKeys.parkingQRDesc.tr(context: context).toText16(),
SizedBox(height: 16.h),
Image.memory(
myAppointmentsViewModel.parkingQRImageBytes!,
width: 156.w,
height: 156.h,
fit: BoxFit.cover,
gaplessPlayback: true, // Prevents blink during image rebuild
),
SizedBox(height: 16.h),
CustomButton(
text: LocaleKeys.done.tr(context: context),
onPressed: () {
openDoctorScheduleCalendar();
},
backgroundColor: AppColors.primaryRedColor,
borderColor: AppColors.primaryRedColor,
textColor: Colors.white,
fontSize: 16.f,
fontWeight: FontWeight.w600,
borderRadius: 12.r,
padding: EdgeInsets.symmetric(horizontal: 10.w),
height: 50.h,
icon: AppAssets.checkmark_icon,
iconColor: Colors.white,
iconSize: 18.h,
).paddingSymmetrical(0.h, 0.h),
],
),
callBackFunc: () {},
isFullScreen: false,
@ -1312,6 +1311,7 @@ class _AppointmentDetailsPageState extends State<AppointmentDetailsPage> {
case 50:
// return LocaleKeys.confirmLiveCare.tr(context: context);
case 90:
Clarity.setCurrentScreenName('Appointment CheckIn Page');
showCommonBottomSheetWithoutHeight(context,
title: LocaleKeys.onlineCheckIn.tr(context: context),
child: isAppointmentWithin4Hours
@ -1321,9 +1321,9 @@ class _AppointmentDetailsPageState extends State<AppointmentDetailsPage> {
)
: Utils.getOnlineCheckInWidget(
loadingText: LocaleKeys.onlineCheckIn24HoursOnly.tr(context: context),
),
callBackFunc: () {},
isFullScreen: false);
), callBackFunc: () {
Clarity.setCurrentScreenName('Appointment Details Page');
}, isFullScreen: false);
default:
// return "No Action".needTranslation;
}

@ -2,6 +2,7 @@ import 'dart:async';
import 'dart:developer';
import 'dart:io';
import 'package:clarity_flutter/clarity_flutter.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:hmg_patient_app_new/core/app_assets.dart';
@ -59,6 +60,7 @@ class _AppointmentPaymentPageState extends State<AppointmentPaymentPage> {
@override
void initState() {
scheduleMicrotask(() {
Clarity.setCurrentScreenName('Appointment Payment Page');
payfortViewModel.initPayfortViewModel();
payfortViewModel.setIsApplePayConfigurationLoading(false);
myAppointmentsViewModel.getPatientShareAppointment(
@ -443,21 +445,24 @@ class _AppointmentPaymentPageState extends State<AppointmentPaymentPage> {
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
LocaleKeys.amountBeforeTax.tr(context: context).toText14(isBold: true),
Utils.getPaymentAmountWithSymbol((myAppointmentsVM.patientAppointmentShareResponseModel!.patientShare ?? 0).toString().toText16(isBold: true), AppColors.blackColor,
13,
isSaudiCurrency: true),
ClarityUnmask(
child: Utils.getPaymentAmountWithSymbol(
(myAppointmentsVM.patientAppointmentShareResponseModel!.patientShare ?? 0).toString().toText16(isBold: true), AppColors.blackColor, 13,
isSaudiCurrency: true),
),
],
).paddingSymmetrical(24.h, 0.h),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
"VAT 15%".toText14(isBold: true, color: AppColors.greyTextColor),
Utils.getPaymentAmountWithSymbol(
(myAppointmentsVM.patientAppointmentShareResponseModel!.patientTaxAmount ?? 0).toString()
.toText14(isBold: true, color: AppColors.greyTextColor),
AppColors.greyTextColor,
13,
isSaudiCurrency: true),
ClarityUnmask(
child: Utils.getPaymentAmountWithSymbol(
(myAppointmentsVM.patientAppointmentShareResponseModel!.patientTaxAmount ?? 0).toString().toText14(isBold: true, color: AppColors.greyTextColor),
AppColors.greyTextColor,
13,
isSaudiCurrency: true),
),
],
).paddingSymmetrical(24.h, 0.h),
SizedBox(height: 17.h),
@ -465,10 +470,11 @@ class _AppointmentPaymentPageState extends State<AppointmentPaymentPage> {
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
"".toText14(isBold: true),
Utils.getPaymentAmountWithSymbol(
(myAppointmentsVM.patientAppointmentShareResponseModel!.patientShareWithTax ?? 0).toString().toText24(isBold: true), AppColors.blackColor,
17,
isSaudiCurrency: true),
ClarityUnmask(
child: Utils.getPaymentAmountWithSymbol(
(myAppointmentsVM.patientAppointmentShareResponseModel!.patientShareWithTax ?? 0).toString().toText24(isBold: true), AppColors.blackColor, 17,
isSaudiCurrency: true),
),
],
).paddingSymmetrical(24.h, 0.h),
Platform.isIOS

@ -1,6 +1,7 @@
import 'dart:async';
import 'dart:ui' as ui;
import 'package:clarity_flutter/clarity_flutter.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:hmg_patient_app_new/core/app_assets.dart';
@ -309,16 +310,18 @@ class _AppointmentCardState extends State<AppointmentCard> {
? '${(widget.patientAppointmentHistoryResponseModel.projectName ?? "Habib Hospital").substring(0, 15)}...'
: widget.patientAppointmentHistoryResponseModel.projectName ?? "Habib Hospital")
.toShimmer2(isShow: widget.isLoading),
Directionality(
textDirection: ui.TextDirection.ltr,
child: AppCustomChipWidget(
labelPadding: EdgeInsetsDirectional.only(start: -4.w, end: 6.w),
icon: AppAssets.appointment_calendar_icon,
richText: widget.isLoading
? 'Cardiology'.toText10().toShimmer2(isShow: widget.isLoading)
: "${DateUtil.formatDateToDate(DateUtil.convertStringToDate(widget.patientAppointmentHistoryResponseModel.appointmentDate), false)} ${DateUtil.formatDateToTimeLang(DateUtil.convertStringToDate(widget.patientAppointmentHistoryResponseModel.appointmentDate), false)}"
.toText10(isEnglishOnly: true, isBold: true),
).toShimmer2(isShow: widget.isLoading),
ClarityUnmask(
child: Directionality(
textDirection: ui.TextDirection.ltr,
child: AppCustomChipWidget(
labelPadding: EdgeInsetsDirectional.only(start: -4.w, end: 6.w),
icon: AppAssets.appointment_calendar_icon,
richText: widget.isLoading
? 'Cardiology'.toText10().toShimmer2(isShow: widget.isLoading)
: "${DateUtil.formatDateToDate(DateUtil.convertStringToDate(widget.patientAppointmentHistoryResponseModel.appointmentDate), false)} ${DateUtil.formatDateToTimeLang(DateUtil.convertStringToDate(widget.patientAppointmentHistoryResponseModel.appointmentDate), false)}"
.toText10(isEnglishOnly: true, isBold: true),
).toShimmer2(isShow: widget.isLoading),
),
),
// AppCustomChipWidget(

@ -1,5 +1,6 @@
import 'dart:ui' as ui;
import 'package:clarity_flutter/clarity_flutter.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:hmg_patient_app_new/core/app_assets.dart';
@ -134,17 +135,18 @@ class AppointmentDoctorCard extends StatelessWidget {
labelText: patientAppointmentHistoryResponseModel.projectName ?? "Habib Hospital",
labelPadding: EdgeInsetsDirectional.only(start: 6.w, end: 6.w),
),
Directionality(
textDirection: ui.TextDirection.ltr,
child: AppCustomChipWidget(
labelPadding: EdgeInsetsDirectional.only(start: -6.w, end: 6.w),
icon: AppAssets.doctor_calendar_icon,
richText:
"${DateUtil.formatDateToDate(DateUtil.convertStringToDate(patientAppointmentHistoryResponseModel.appointmentDate), false)} ${DateUtil.formatDateToTimeLang(
DateUtil.convertStringToDate(patientAppointmentHistoryResponseModel.appointmentDate),
false,
)}"
.toText10(isBold: true),
ClarityUnmask(
child: Directionality(
textDirection: ui.TextDirection.ltr,
child: AppCustomChipWidget(
labelPadding: EdgeInsetsDirectional.only(start: -6.w, end: 6.w),
icon: AppAssets.doctor_calendar_icon,
richText: "${DateUtil.formatDateToDate(DateUtil.convertStringToDate(patientAppointmentHistoryResponseModel.appointmentDate), false)} ${DateUtil.formatDateToTimeLang(
DateUtil.convertStringToDate(patientAppointmentHistoryResponseModel.appointmentDate),
false,
)}"
.toText10(isBold: true),
),
),
),
AppCustomChipWidget(

@ -1,3 +1,4 @@
import 'package:clarity_flutter/clarity_flutter.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
@ -32,6 +33,7 @@ class LoginScreenState extends State<LoginScreen> {
@override
void initState() {
Clarity.setCurrentScreenName('Login Screen');
super.initState();
_nationalIdFocusNode = FocusNode();

@ -1,5 +1,6 @@
import 'dart:ui' as ui;
import 'package:clarity_flutter/clarity_flutter.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:hmg_patient_app_new/core/app_assets.dart';
@ -37,6 +38,7 @@ class _SavedLogin extends State<SavedLogin> {
@override
void initState() {
Clarity.setCurrentScreenName('Last Login Screen');
authVm = context.read<AuthenticationViewModel>();
appState = getIt.get<AppState>();
loginType = LoginTypeExtension.fromValue(appState.getSelectDeviceByImeiRespModelElement!.logInType!)!;
@ -58,7 +60,6 @@ class _SavedLogin extends State<SavedLogin> {
if (loginType == LoginTypeEnum.fingerprint || loginType == LoginTypeEnum.face) {
authVm.loginWithFingerPrintFace(() {});
}
super.initState();
}

@ -1,5 +1,6 @@
import 'dart:async';
import 'package:clarity_flutter/clarity_flutter.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_staggered_animations/flutter_staggered_animations.dart';
@ -57,6 +58,7 @@ class _BookAppointmentPageState extends State<BookAppointmentPage> {
@override
void initState() {
Clarity.setCurrentScreenName('Book Appointment Page');
authVM = context.read<AuthenticationViewModel>();
scheduleMicrotask(() {
// bookAppointmentsViewModel.selectedTabIndex = 0;

@ -2,6 +2,7 @@ import 'dart:convert';
import 'dart:developer';
import 'dart:typed_data';
import 'package:clarity_flutter/clarity_flutter.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:get_it/get_it.dart';
@ -48,6 +49,12 @@ class _ReviewAppointmentPageState extends State<ReviewAppointmentPage> {
Uint8List? _cachedImageBytes;
String? _cachedImageDataHash;
@override
void initState() {
Clarity.setCurrentScreenName('Appointment Review Page');
super.initState();
}
@override
Widget build(BuildContext context) {
bookAppointmentsViewModel = Provider.of<BookAppointmentsViewModel>(context, listen: false);

@ -1,3 +1,4 @@
import 'package:clarity_flutter/clarity_flutter.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_staggered_animations/flutter_staggered_animations.dart';
@ -39,6 +40,7 @@ class _SearchDoctorByNameState extends State<SearchDoctorByName> {
@override
void initState() {
Clarity.setCurrentScreenName('Search By Doctor Name Page');
_scrollController = ScrollController();
super.initState();
}

@ -1,5 +1,6 @@
import 'dart:async';
import 'package:clarity_flutter/clarity_flutter.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_staggered_animations/flutter_staggered_animations.dart';
@ -59,6 +60,7 @@ class _SelectClinicPageState extends State<SelectClinicPage> {
@override
void initState() {
Clarity.setCurrentScreenName('Select Clinic Page');
scheduleMicrotask(() {
bookAppointmentsViewModel.getClinics();
});

@ -1,5 +1,6 @@
import 'dart:async';
import 'package:clarity_flutter/clarity_flutter.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_staggered_animations/flutter_staggered_animations.dart';
@ -44,6 +45,7 @@ class _SelectDoctorPageState extends State<SelectDoctorPage> {
@override
void initState() {
Clarity.setCurrentScreenName('Select Doctor Page');
_scrollController = ScrollController();
scheduleMicrotask(() {
bookAppointmentsViewModel.setIsNearestAppointmentSelected(true);

@ -1,6 +1,7 @@
import 'dart:async';
import 'dart:ui' as ui;
import 'package:clarity_flutter/clarity_flutter.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:hmg_patient_app_new/core/app_assets.dart';
@ -59,6 +60,7 @@ class _AppointmentCalendarState extends State<AppointmentCalendar> {
@override
void initState() {
Clarity.setCurrentScreenName('Select Doctor Free Slot Page');
_calendarController = CalendarController();
scheduleMicrotask(() {
_events = {
@ -98,54 +100,56 @@ class _AppointmentCalendarState extends State<AppointmentCalendar> {
child: Localizations.override(
context: context,
locale: isArabic ? const Locale('ar', 'SA') : const Locale('en'),
child: SfCalendar(
controller: _calendarController,
minDate: DateTime.now(),
showNavigationArrow: true,
// headerHeight: 60.h,
headerStyle: CalendarHeaderStyle(
backgroundColor: AppColors.transparent,
textAlign: isArabic ? TextAlign.end : TextAlign.start,
textStyle: TextStyle(fontSize: 18.f, fontWeight: FontWeight.w600, letterSpacing: -0.46, color: AppColors.primaryRedColor),
),
viewHeaderStyle: ViewHeaderStyle(
// backgroundColor: AppColors.scaffoldBgColor,
dayTextStyle: TextStyle(fontSize: 14.f, fontWeight: FontWeight.w600, letterSpacing: -0.46, color: AppColors.textColor),
),
view: CalendarView.month,
todayHighlightColor: Colors.transparent,
todayTextStyle: TextStyle(color: AppColors.textColor, fontWeight: FontWeight.bold),
selectionDecoration: ShapeDecoration(
color: AppColors.transparent,
shape: SmoothRectangleBorder(
borderRadius: BorderRadius.circular(10.r),
smoothness: 1,
side: BorderSide(color: AppColors.primaryRedColor, width: 1.5),
child: ClarityUnmask(
child: SfCalendar(
controller: _calendarController,
minDate: DateTime.now(),
showNavigationArrow: true,
// headerHeight: 60.h,
headerStyle: CalendarHeaderStyle(
backgroundColor: AppColors.transparent,
textAlign: isArabic ? TextAlign.end : TextAlign.start,
textStyle: TextStyle(fontSize: 18.f, fontWeight: FontWeight.w600, letterSpacing: -0.46, color: AppColors.primaryRedColor),
),
),
cellBorderColor: AppColors.transparent,
dataSource: MeetingDataSource(_getDataSource()),
monthCellBuilder: (context, details) => Padding(
padding: EdgeInsets.all(12.h),
child: details.date.day.toString().toText14(
isCenter: true,
color: details.date == _calendarController.selectedDate ? AppColors.primaryRedColor : AppColors.textColor,
isEnglishOnly: true,
),
),
monthViewSettings: MonthViewSettings(
dayFormat: "EEE",
appointmentDisplayMode: MonthAppointmentDisplayMode.indicator,
showTrailingAndLeadingDates: false,
appointmentDisplayCount: 1,
monthCellStyle: MonthCellStyle(
textStyle: TextStyle(fontSize: 19.f),
viewHeaderStyle: ViewHeaderStyle(
// backgroundColor: AppColors.scaffoldBgColor,
dayTextStyle: TextStyle(fontSize: 14.f, fontWeight: FontWeight.w600, letterSpacing: -0.46, color: AppColors.textColor),
),
view: CalendarView.month,
todayHighlightColor: Colors.transparent,
todayTextStyle: TextStyle(color: AppColors.textColor, fontWeight: FontWeight.bold),
selectionDecoration: ShapeDecoration(
color: AppColors.transparent,
shape: SmoothRectangleBorder(
borderRadius: BorderRadius.circular(10.r),
smoothness: 1,
side: BorderSide(color: AppColors.primaryRedColor, width: 1.5),
),
),
cellBorderColor: AppColors.transparent,
dataSource: MeetingDataSource(_getDataSource()),
monthCellBuilder: (context, details) => Padding(
padding: EdgeInsets.all(12.h),
child: details.date.day.toString().toText14(
isCenter: true,
color: details.date == _calendarController.selectedDate ? AppColors.primaryRedColor : AppColors.textColor,
isEnglishOnly: true,
),
),
monthViewSettings: MonthViewSettings(
dayFormat: "EEE",
appointmentDisplayMode: MonthAppointmentDisplayMode.indicator,
showTrailingAndLeadingDates: false,
appointmentDisplayCount: 1,
monthCellStyle: MonthCellStyle(
textStyle: TextStyle(fontSize: 19.f),
),
),
onTap: (CalendarTapDetails details) {
_calendarController.selectedDate = details.date;
_onDaySelected(details.date!);
},
),
onTap: (CalendarTapDetails details) {
_calendarController.selectedDate = details.date;
_onDaySelected(details.date!);
},
),
),
),
@ -153,35 +157,37 @@ class _AppointmentCalendarState extends State<AppointmentCalendar> {
SizedBox(height: 10.h),
Transform.translate(
offset: const Offset(0.0, -10.0),
child: selectedDateDisplay.toText16(isBold: true, isEnglishOnly: !isArabic),
child: ClarityUnmask(child: selectedDateDisplay.toText16(isBold: true, isEnglishOnly: !isArabic)),
),
//TODO: Add Next Day Span here
dayEvents.isNotEmpty
? ConstrainedBox(
constraints: BoxConstraints(
maxHeight: MediaQuery.of(context).size.height * 0.15,
minHeight: 0,
),
child: Directionality(
textDirection: isArabic ? ui.TextDirection.rtl : ui.TextDirection.ltr,
child: SingleChildScrollView(
scrollDirection: Axis.vertical,
child: Wrap(
direction: Axis.horizontal,
alignment: WrapAlignment.start,
spacing: 6.h,
runSpacing: 6.h,
children: List.generate(
dayEvents.length,
(index) => TimeSlotChip(
label: dayEvents[index].isoTime!,
isSelected: index == selectedButtonIndex,
onTap: () {
setState(() {
selectedButtonIndex = index;
selectedTime = dayEvents[index].isoTime!;
});
},
? ClarityUnmask(
child: ConstrainedBox(
constraints: BoxConstraints(
maxHeight: MediaQuery.of(context).size.height * 0.15,
minHeight: 0,
),
child: Directionality(
textDirection: isArabic ? ui.TextDirection.rtl : ui.TextDirection.ltr,
child: SingleChildScrollView(
scrollDirection: Axis.vertical,
child: Wrap(
direction: Axis.horizontal,
alignment: WrapAlignment.start,
spacing: 6.h,
runSpacing: 6.h,
children: List.generate(
dayEvents.length,
(index) => TimeSlotChip(
label: dayEvents[index].isoTime!,
isSelected: index == selectedButtonIndex,
onTap: () {
setState(() {
selectedButtonIndex = index;
selectedTime = dayEvents[index].isoTime!;
});
},
),
),
),
),

@ -2,6 +2,7 @@ import 'dart:async';
import 'dart:developer';
import 'dart:ui' as ui;
import 'package:clarity_flutter/clarity_flutter.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_staggered_animations/flutter_staggered_animations.dart';
@ -112,6 +113,7 @@ class _LandingPageState extends State<LandingPage> {
@override
void initState() {
Clarity.setCurrentScreenName('Landing Page');
authVM = context.read<AuthenticationViewModel>();
habibWalletVM = context.read<HabibWalletViewModel>();
appointmentRatingViewModel = context.read<AppointmentRatingViewModel>();

@ -60,9 +60,9 @@ class _SplashScreenState extends State<SplashPage> {
ZoomService().initializeZoomSDK();
// if (!kDebugMode) {
// _initializeClarity();
// }
if (!kDebugMode) {
_initializeClarity();
}
if (isAppOpenedFromCall) {
navigateToTeleConsult();
@ -87,7 +87,7 @@ class _SplashScreenState extends State<SplashPage> {
void _initializeClarity() {
final config = ClarityConfig(
projectId: "x0qgorlez4", // You can find it on the Settings page of Clarity dashboard.
logLevel: LogLevel.Verbose, // Optional: Set the log level (Verbose, Debug, Info, Warning, Error, None)
logLevel: LogLevel.Error, // Optional: Set the log level (Verbose, Debug, Info, Warning, Error, None)
);
Clarity.initialize(context, config);

Loading…
Cancel
Save