appointments ui and caching

This commit is contained in:
MhdZiadHirati 2023-10-19 17:26:07 +03:00
parent ecd3e791c2
commit e00f0354dd
13 changed files with 292 additions and 76 deletions

View File

@ -16,6 +16,7 @@ class ButtonWidget extends StatelessWidget {
final bool? isLoading; final bool? isLoading;
final double? buttonHeight; final double? buttonHeight;
final bool hideTextOnLoading; final bool hideTextOnLoading;
final double? fontSize;
const ButtonWidget( const ButtonWidget(
{super.key, {super.key,
required this.onTap, required this.onTap,
@ -27,6 +28,7 @@ class ButtonWidget extends StatelessWidget {
this.loaderColor, this.loaderColor,
this.width, this.width,
this.buttonHeight, this.buttonHeight,
this.fontSize,
this.textColor, this.textColor,
this.isLoading = false}); this.isLoading = false});
@ -44,6 +46,7 @@ class ButtonWidget extends StatelessWidget {
child ?? Container(), child ?? Container(),
BoldTextWidget( BoldTextWidget(
title, title,
fontSize: fontSize,
color: Colors.white, color: Colors.white,
).paddingSymmetric(horizontal: 10), ).paddingSymmetric(horizontal: 10),
]) ])
@ -58,6 +61,8 @@ class ButtonWidget extends StatelessWidget {
isLoading!), isLoading!),
child: BoldTextWidget( child: BoldTextWidget(
title, title,
fontSize: fontSize,
textAlign: TextAlign.center,
color: Colors.white, color: Colors.white,
).paddingSymmetric(horizontal: 20), ).paddingSymmetric(horizontal: 20),
), ),
@ -72,6 +77,8 @@ class ButtonWidget extends StatelessWidget {
) )
: BoldTextWidget( : BoldTextWidget(
title, title,
fontSize: fontSize,
textAlign: TextAlign.center,
color: Colors.white, color: Colors.white,
), ),
).onTap(() { ).onTap(() {

View File

@ -1,8 +1,10 @@
import 'dart:convert';
import 'dart:developer'; import 'dart:developer';
import 'package:get_storage/get_storage.dart'; import 'package:get_storage/get_storage.dart';
import '../../features/auth/data_layer/model/user.dart'; import '../../features/auth/data_layer/model/user.dart';
import '../../features/card/data_layer/model/appointment.dart';
class LocalStorage { class LocalStorage {
final GetStorage storage = GetStorage(); final GetStorage storage = GetStorage();
@ -76,4 +78,31 @@ class LocalStorage {
Future<void> clearCache() async { Future<void> clearCache() async {
await storage.erase(); await storage.erase();
} }
Future<void> setAppointments(List<Appointment> appointments) async {
for (int i = 0; i < appointments.length; i++) {
await storage.write(
'appointments[$i]', jsonEncode(appointments[i].toJson()));
}
await storage.write('appointments_length', appointments.length);
}
List<Appointment>? getAppointments() {
int appointmentsLength = storage.read('appointments_length') ?? 0;
if (appointmentsLength == 0) {
return null;
} else {
List<Appointment> appointments = [];
for (int i = 0; i < appointmentsLength; i++) {
appointments.add(
Appointment.fromJson(
jsonDecode(
storage.read('appointments[$i]'),
),
),
);
}
return appointments;
}
}
} }

View File

@ -4,7 +4,8 @@ class PagesTranslations implements Translations {
@override @override
Map<String, Map<String, String>> get keys => { Map<String, Map<String, String>> get keys => {
'en': { 'en': {
'schedule_an_appointment': 'Schedule an appointment', 'you_have_an_appointment_on': 'your appointment on',
'schedule_an_appointment': 'Appointment',
'There are no notifications to display at this time.': 'There are no notifications to display at this time.':
'There are no notifications to display at this time.', 'There are no notifications to display at this time.',
'no_previous_conversations_!': 'No Previous Conversations !', 'no_previous_conversations_!': 'No Previous Conversations !',
@ -183,7 +184,8 @@ class PagesTranslations implements Translations {
'Enter your email to reset your password please \n We will send verification code to your Email.', 'Enter your email to reset your password please \n We will send verification code to your Email.',
}, },
'ar': { 'ar': {
'schedule_an_appointment': 'جدولة موعد', 'you_have_an_appointment_on': 'لديك موعد بتاريخ',
'schedule_an_appointment': 'حجز موعد',
'There are no notifications to display at this time.': 'There are no notifications to display at this time.':
'لا توجد إشعارات لعرضها في الوقت الحالي.', 'لا توجد إشعارات لعرضها في الوقت الحالي.',
'no_previous_conversations_!': 'لا توجد محادثات سابقة!', 'no_previous_conversations_!': 'لا توجد محادثات سابقة!',

View File

@ -33,7 +33,7 @@ class AccountScreen extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
accountController.getSelectedLanguageIcon(); accountController.getSelectedLanguageIcon();
homeController.readUser(); // homeController.readUser();
return Scaffold( return Scaffold(
backgroundColor: AppColors.backGroundColor, backgroundColor: AppColors.backGroundColor,
body: SingleChildScrollView( body: SingleChildScrollView(

View File

@ -1,3 +1,5 @@
import 'package:taafee_mobile/features/card/data_layer/model/appointment.dart';
class User { class User {
int id; int id;
String firstName; String firstName;
@ -5,6 +7,7 @@ class User {
String email; String email;
int chatUserId; int chatUserId;
String? avatarImage; String? avatarImage;
List<Appointment>? appointments;
User({ User({
required this.id, required this.id,
required this.firstName, required this.firstName,
@ -12,6 +15,7 @@ class User {
required this.email, required this.email,
required this.avatarImage, required this.avatarImage,
required this.chatUserId, required this.chatUserId,
this.appointments,
}); });
factory User.fromJson(Map<String, dynamic> json) => User( factory User.fromJson(Map<String, dynamic> json) => User(

View File

@ -5,6 +5,7 @@ import 'package:image_gallery_saver/image_gallery_saver.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:taafee_mobile/common/const/const.dart'; import 'package:taafee_mobile/common/const/const.dart';
import 'package:taafee_mobile/core/local_storage/local_storage.dart';
import 'package:taafee_mobile/features/card/data_layer/model/add_card.dart'; import 'package:taafee_mobile/features/card/data_layer/model/add_card.dart';
import 'package:taafee_mobile/features/card/data_layer/model/card_images.dart'; import 'package:taafee_mobile/features/card/data_layer/model/card_images.dart';
import 'package:taafee_mobile/features/card/data_layer/model/card_model.dart'; import 'package:taafee_mobile/features/card/data_layer/model/card_model.dart';
@ -17,6 +18,7 @@ import '../../../core/utils/pagination_list.dart';
class CardController extends GetxController { class CardController extends GetxController {
//---------------data source-----------// //---------------data source-----------//
CardService cardService = CardService(); CardService cardService = CardService();
LocalStorage localStorage = LocalStorage();
//----------- model-----------// //----------- model-----------//
Rx<AddCardModel> cardModel = AddCardModel.zero().obs; Rx<AddCardModel> cardModel = AddCardModel.zero().obs;

View File

@ -0,0 +1,41 @@
import '../../../auth/data_layer/model/user.dart';
class Appointment {
DateTime dateTime;
int cardId;
User user;
Appointment(
{required this.cardId, required this.dateTime, required this.user});
factory Appointment.fromJson(Map<String, dynamic> jsonMap) => Appointment(
cardId: jsonMap['card_id'],
dateTime: DateTime.parse(jsonMap['date']),
user: User.fromJson(jsonMap['user']));
Map<String, dynamic> toJson() => {
"card_id": cardId,
"date": dateTime.toString(),
"user": user.toJson(),
};
static List<Appointment> fromJsonList(List jsonList) {
List<Appointment> appointments = [];
// ignore: avoid_function_literals_in_foreach_calls
jsonList.forEach((element) {
appointments.add(Appointment.fromJson(element));
});
return appointments;
}
static List<Map<String, dynamic>> toJsonList(List<Appointment> appointments) {
List<Map<String, dynamic>> jsonList = [];
// ignore: avoid_function_literals_in_foreach_calls
appointments.forEach((element) {
jsonList.add(element.toJson());
});
return jsonList;
}
@override
toString() {
return 'card_id:$cardId,userName:${user.firstName},date:${dateTime.toString()}';
}
}

View File

@ -7,6 +7,7 @@ import 'package:taafee_mobile/common/widgets/button.dart';
import 'package:taafee_mobile/common/widgets/text.dart'; import 'package:taafee_mobile/common/widgets/text.dart';
import 'package:taafee_mobile/core/routing/routing_manager.dart'; import 'package:taafee_mobile/core/routing/routing_manager.dart';
import 'package:taafee_mobile/features/card/business_logic_layer/card_controller.dart'; import 'package:taafee_mobile/features/card/business_logic_layer/card_controller.dart';
import 'package:taafee_mobile/features/card/data_layer/model/appointment.dart';
import 'package:taafee_mobile/features/card/presentation_layer/widgets/card_details.dart'; import 'package:taafee_mobile/features/card/presentation_layer/widgets/card_details.dart';
import 'package:taafee_mobile/features/card/presentation_layer/widgets/card_service.dart'; import 'package:taafee_mobile/features/card/presentation_layer/widgets/card_service.dart';
import 'package:taafee_mobile/features/chat/business%20logic%20layer/chat_controller.dart'; import 'package:taafee_mobile/features/chat/business%20logic%20layer/chat_controller.dart';
@ -199,6 +200,9 @@ class CardDetailsScreen extends StatelessWidget {
], ],
), ),
), ),
const SizedBox(
height: 40,
),
Row( Row(
children: [ children: [
ButtonWidget( ButtonWidget(
@ -215,7 +219,7 @@ class CardDetailsScreen extends StatelessWidget {
const ColorFilter.mode(Colors.white, BlendMode.srcIn), const ColorFilter.mode(Colors.white, BlendMode.srcIn),
), ),
) )
.paddingSymmetric(horizontal: 10) .paddingSymmetric(horizontal: 4)
.expanded(Responsive.isTablet() ? 1 : 5), .expanded(Responsive.isTablet() ? 1 : 5),
ButtonWidget( ButtonWidget(
color: AppColors.emailColor, color: AppColors.emailColor,
@ -227,7 +231,7 @@ class CardDetailsScreen extends StatelessWidget {
textColor: Colors.white, textColor: Colors.white,
child: SvgPicture.asset("assets/icons/Email.svg"), child: SvgPicture.asset("assets/icons/Email.svg"),
) )
.paddingSymmetric(horizontal: 10) .paddingSymmetric(horizontal: 4)
.expanded(Responsive.isTablet() ? 1 : 5), .expanded(Responsive.isTablet() ? 1 : 5),
if (Responsive.isTablet()) if (Responsive.isTablet())
Visibility( Visibility(
@ -257,40 +261,110 @@ class CardDetailsScreen extends StatelessWidget {
).expanded(2); ).expanded(2);
}), }),
), ),
if (Responsive.isTablet())
Visibility(
visible: homeController.user.value!.id != cardModel.user.id,
child: ButtonWidget(
onTap: () {
homeController.scheduleAnAppointment(
Appointment(
cardId: cardModel.id,
dateTime: DateTime.now(),
user: homeController.user.value!),
);
},
haveIcon: true,
title: 'schedule_an_appointment'.tr,
color: AppColors.secondaryColor,
child: const Icon(
Icons.schedule,
color: Colors.white,
),
)
.paddingSymmetric(horizontal: 10)
.expanded(Responsive.isTablet() ? 1 : 5),
),
], ],
).paddingSymmetric( ).paddingSymmetric(
vertical: Responsive.isTablet() ? 20 : 10, vertical: Responsive.isTablet() ? 20 : 4,
horizontal: Responsive.isTablet() ? 40 : 10), horizontal: Responsive.isTablet() ? 40 : 10),
if (!Responsive.isTablet()) if (!Responsive.isTablet())
Visibility( Obx(() {
visible: chatController.chatUser.id != cardModel.user.chatUserId, return Row(
child: Obx(() { children: [
return ButtonWidget( Obx(() {
isLoading: chatController.createRoomState.loading, return Visibility(
textColor: Colors.white, visible:
color: AppColors.messageColor, homeController.user.value!.id != cardModel.user.id,
haveIcon: true, child:
onTap: () { (homeController.currentCardAppointment.value != null)
if (chatController.connectionState.value == ? ButtonWidget(
SocketConnectionState.connected) { onTap: () {},
chatController.createRoom( fontSize: 12,
chatUserId: cardModel.user.chatUserId, color: AppColors.secondaryColor,
onSuccess: (room) { title:
RoutingManager.to(RouteName.chatDetails, '${'you_have_an_appointment_on'.tr} ${homeController.currentCardAppointment.value!.dateTime.toString().substring(0, 11)}',
arguments: room); )
}); .paddingSymmetric(horizontal: 4)
} else { .expanded(Responsive.isTablet() ? 1 : 5)
Toast.showToast('you_have_no_internet_connection'.tr); : ButtonWidget(
} onTap: () {
}, homeController.scheduleAnAppointment(
title: "start_conversation".tr, Appointment(
child: SvgPicture.asset("assets/icons/message.svg"), cardId: cardModel.id,
); dateTime: DateTime.now(),
}), user: homeController.user.value!),
), );
},
haveIcon: true,
fontSize: 12,
title: 'schedule_an_appointment'.tr,
color: AppColors.secondaryColor,
child: const Icon(
Icons.schedule,
color: Colors.white,
),
)
.paddingSymmetric(horizontal: 4)
.expanded(Responsive.isTablet() ? 1 : 5),
);
}),
Visibility(
visible:
chatController.chatUser.id != cardModel.user.chatUserId,
child: ButtonWidget(
isLoading: chatController.createRoomState.loading,
textColor: Colors.white,
color: AppColors.messageColor,
haveIcon: true,
onTap: () {
if (chatController.connectionState.value ==
SocketConnectionState.connected) {
chatController.createRoom(
chatUserId: cardModel.user.chatUserId,
onSuccess: (room) {
RoutingManager.to(RouteName.chatDetails,
arguments: room);
});
} else {
Toast.showToast('you_have_no_internet_connection'.tr);
}
},
title: "start_conversation".tr,
fontSize: 12,
child: SvgPicture.asset("assets/icons/message.svg"),
)
.paddingSymmetric(horizontal: 4)
.expanded(Responsive.isTablet() ? 1 : 5),
),
],
).paddingSymmetric(
vertical: Responsive.isTablet() ? 20 : 4,
horizontal: Responsive.isTablet() ? 40 : 10);
}),
const SizedBox( const SizedBox(
height: 60, height: 60,
) ),
], ],
).paddingSymmetric(horizontal: Responsive.isTablet() ? 20 : 0)), ).paddingSymmetric(horizontal: Responsive.isTablet() ? 20 : 0)),
).makeSafeArea(); ).makeSafeArea();

View File

@ -7,14 +7,15 @@ import 'package:taafee_mobile/common/extensions/widget_extension.dart';
import 'package:taafee_mobile/common/widgets/text.dart'; import 'package:taafee_mobile/common/widgets/text.dart';
import 'package:taafee_mobile/features/card/data_layer/model/card_model.dart'; import 'package:taafee_mobile/features/card/data_layer/model/card_model.dart';
import 'package:taafee_mobile/features/card/presentation_layer/widgets/card_location.dart'; import 'package:taafee_mobile/features/card/presentation_layer/widgets/card_location.dart';
import 'package:taafee_mobile/features/home/business_logic_layer/home_controller.dart';
import '../../../../core/routing/routing_manager.dart'; import '../../../../core/routing/routing_manager.dart';
import 'card_header.dart'; import 'card_header.dart';
class FirstCardWidget extends StatelessWidget { class FirstCardWidget extends StatelessWidget {
final CardModel cardModel; final CardModel cardModel;
const FirstCardWidget(this.cardModel, {super.key}); final HomeController homeController = Get.find<HomeController>();
FirstCardWidget(this.cardModel, {super.key});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Container( return Container(
@ -95,6 +96,7 @@ class FirstCardWidget extends StatelessWidget {
), ),
], ],
).onTap(() { ).onTap(() {
homeController.setCardAppointment(cardModel.id);
RoutingManager.to(RouteName.cardDetails, arguments: cardModel); RoutingManager.to(RouteName.cardDetails, arguments: cardModel);
}), }),
], ],

View File

@ -70,6 +70,7 @@ class MyCardWidget extends StatelessWidget {
), ),
], ],
).onTap(() { ).onTap(() {
homeController.setCardAppointment(cardModel.id);
RoutingManager.to(RouteName.cardDetails, arguments: cardModel); RoutingManager.to(RouteName.cardDetails, arguments: cardModel);
}), }),
], ],

View File

@ -6,13 +6,15 @@ import 'package:taafee_mobile/common/extensions/widget_extension.dart';
import 'package:taafee_mobile/common/widgets/text.dart'; import 'package:taafee_mobile/common/widgets/text.dart';
import 'package:taafee_mobile/features/card/data_layer/model/card_model.dart'; import 'package:taafee_mobile/features/card/data_layer/model/card_model.dart';
import 'package:taafee_mobile/features/card/presentation_layer/widgets/card_header.dart'; import 'package:taafee_mobile/features/card/presentation_layer/widgets/card_header.dart';
import 'package:taafee_mobile/features/home/business_logic_layer/home_controller.dart';
import '../../../../common/const/const.dart'; import '../../../../common/const/const.dart';
import '../../../../core/routing/routing_manager.dart'; import '../../../../core/routing/routing_manager.dart';
class SecondCardWidget extends StatelessWidget { class SecondCardWidget extends StatelessWidget {
final CardModel cardModel; final CardModel cardModel;
const SecondCardWidget(this.cardModel, {super.key}); final HomeController homeController = Get.find<HomeController>();
SecondCardWidget(this.cardModel, {super.key});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -92,6 +94,7 @@ class SecondCardWidget extends StatelessWidget {
).paddingSymmetric(horizontal: 5), ).paddingSymmetric(horizontal: 5),
], ],
).onTap(() { ).onTap(() {
homeController.setCardAppointment(cardModel.id);
RoutingManager.to(RouteName.cardDetails, arguments: cardModel); RoutingManager.to(RouteName.cardDetails, arguments: cardModel);
}), }),
), ),

View File

@ -11,10 +11,12 @@ import 'package:taafee_mobile/core/routing/routing_manager.dart';
import 'package:taafee_mobile/features/card/business_logic_layer/card_controller.dart'; import 'package:taafee_mobile/features/card/business_logic_layer/card_controller.dart';
import 'package:taafee_mobile/features/favorite/business_logic_layer/favorite_controller.dart'; import 'package:taafee_mobile/features/favorite/business_logic_layer/favorite_controller.dart';
import 'package:taafee_mobile/features/favorite/presentation_layer/widgets/favorite_card.dart'; import 'package:taafee_mobile/features/favorite/presentation_layer/widgets/favorite_card.dart';
import 'package:taafee_mobile/features/home/business_logic_layer/home_controller.dart';
class FavoriteScreen extends StatelessWidget { class FavoriteScreen extends StatelessWidget {
final CardController cardController = Get.find<CardController>(); final CardController cardController = Get.find<CardController>();
final FavoriteController favoriteController = Get.find<FavoriteController>(); final FavoriteController favoriteController = Get.find<FavoriteController>();
final HomeController homeController = Get.find<HomeController>();
FavoriteScreen({super.key}); FavoriteScreen({super.key});
@override @override
@ -41,44 +43,46 @@ class FavoriteScreen extends StatelessWidget {
width: Get.width, width: Get.width,
height: Get.height * 0.75, height: Get.height * 0.75,
rxFuture: favoriteController.getFavoriteState, rxFuture: favoriteController.getFavoriteState,
child: () => child: () => (favoriteController
(favoriteController.getFavoriteState.result.isNotEmpty) .getFavoriteState.result.isNotEmpty)
? GridViewWidget( ? GridViewWidget(
mainAxisExtent: 150, mainAxisExtent: 150,
count: Responsive.isTablet() ? 3 : 2, count: Responsive.isTablet() ? 3 : 2,
itemCount: itemCount:
favoriteController.getFavoriteState.result.length, favoriteController.getFavoriteState.result.length,
child: (index) => Obx(() { child: (index) => Obx(() {
return FavoriteCardWidget( return FavoriteCardWidget(
favoriteModel: favoriteController favoriteModel:
.getFavoriteState.result[index], favoriteController.getFavoriteState.result[index],
).onTap(() { ).onTap(() {
RoutingManager.to(RouteName.cardDetails, homeController.setCardAppointment(favoriteController
arguments: favoriteController.getFavoriteState .getFavoriteState.result[index].cardModel.id);
.result[index].cardModel); RoutingManager.to(RouteName.cardDetails,
}); arguments: favoriteController
}), .getFavoriteState.result[index].cardModel);
) });
: SizedBox( }),
height: Get.height * 0.75, )
child: Column( : SizedBox(
mainAxisAlignment: MainAxisAlignment.center, height: Get.height * 0.75,
children: [ child: Column(
SizedBox( mainAxisAlignment: MainAxisAlignment.center,
width: 128, children: [
height: 128, SizedBox(
child: Lottie.asset( width: 128,
'assets/animations/NO Favorite.json', height: 128,
repeat: false, child: Lottie.asset(
), 'assets/animations/NO Favorite.json',
), repeat: false,
RegularTextWidget( ),
'add_some_favorite_cards !'.tr, ),
fontSize: Responsive.isTablet() ? 18 : 16, RegularTextWidget(
), 'add_some_favorite_cards !'.tr,
], fontSize: Responsive.isTablet() ? 18 : 16,
).center(), ),
), ],
).center(),
),
) )
// const ListViewWidget( // const ListViewWidget(
// itemCount: 8, // itemCount: 8,

View File

@ -6,6 +6,7 @@ import 'package:taafee_mobile/common/widgets/button.dart';
import 'package:taafee_mobile/common/widgets/text.dart'; import 'package:taafee_mobile/common/widgets/text.dart';
import 'package:taafee_mobile/core/local_storage/local_storage.dart'; import 'package:taafee_mobile/core/local_storage/local_storage.dart';
import 'package:taafee_mobile/core/routing/routing_manager.dart'; import 'package:taafee_mobile/core/routing/routing_manager.dart';
import 'package:taafee_mobile/features/card/data_layer/model/appointment.dart';
import 'package:taafee_mobile/features/card/data_layer/model/card_model.dart'; import 'package:taafee_mobile/features/card/data_layer/model/card_model.dart';
import 'package:taafee_mobile/features/home/data_layer/model/city.dart'; import 'package:taafee_mobile/features/home/data_layer/model/city.dart';
import 'package:taafee_mobile/features/home/data_layer/model/search.dart'; import 'package:taafee_mobile/features/home/data_layer/model/search.dart';
@ -50,7 +51,6 @@ class HomeController extends GetxController {
} }
//------------read user----------//// //------------read user----------////
//pick avatar image //pick avatar image
Rx<File?> pickedUserImage = null.obs; Rx<File?> pickedUserImage = null.obs;
RxBool isAvatarImagePicked = false.obs; RxBool isAvatarImagePicked = false.obs;
@ -64,7 +64,12 @@ class HomeController extends GetxController {
} else { } else {
isUserHasAvatar.value = false; isUserHasAvatar.value = false;
} }
List<Appointment>? appointments = storage.getAppointments();
if (appointments != null) {
user.update((val) {
val!.appointments = appointments;
});
}
user.refresh(); user.refresh();
isUserHasAvatar.refresh(); isUserHasAvatar.refresh();
} }
@ -167,4 +172,46 @@ class HomeController extends GetxController {
} }
isArabic.refresh(); isArabic.refresh();
} }
/// ----------- schedule an appointment -------///
Rx<Appointment?> currentCardAppointment = null.obs;
void setCardAppointment(int cardId) {
currentCardAppointment = getCardAppointment(cardId).obs;
currentCardAppointment.refresh();
user.refresh();
}
void scheduleAnAppointment(Appointment appointment) async {
user.update((val) {
if (val!.appointments != null) {
val.appointments!.add(appointment);
} else {
val.appointments = [];
val.appointments!.add(appointment);
}
});
try {
await storage.setAppointments(user.value!.appointments!);
print(user.value!.appointments);
} catch (error) {
print(error.toString());
}
currentCardAppointment = appointment.obs;
currentCardAppointment.refresh();
print('currentCardAppointment:${currentCardAppointment.value}');
user.refresh();
}
Appointment? getCardAppointment(int cardId) {
if (user.value!.appointments == null || user.value!.appointments!.isEmpty) {
return null;
}
print('user appointments: ${user.value!.appointments!}');
Appointment? appointment = user.value!.appointments!
.firstWhereOrNull((element) => (element.cardId == cardId));
print('current appointment:$appointment');
return appointment;
}
} }