appointments ui and caching
This commit is contained in:
parent
ecd3e791c2
commit
e00f0354dd
|
|
@ -16,6 +16,7 @@ class ButtonWidget extends StatelessWidget {
|
|||
final bool? isLoading;
|
||||
final double? buttonHeight;
|
||||
final bool hideTextOnLoading;
|
||||
final double? fontSize;
|
||||
const ButtonWidget(
|
||||
{super.key,
|
||||
required this.onTap,
|
||||
|
|
@ -27,6 +28,7 @@ class ButtonWidget extends StatelessWidget {
|
|||
this.loaderColor,
|
||||
this.width,
|
||||
this.buttonHeight,
|
||||
this.fontSize,
|
||||
this.textColor,
|
||||
this.isLoading = false});
|
||||
|
||||
|
|
@ -44,6 +46,7 @@ class ButtonWidget extends StatelessWidget {
|
|||
child ?? Container(),
|
||||
BoldTextWidget(
|
||||
title,
|
||||
fontSize: fontSize,
|
||||
color: Colors.white,
|
||||
).paddingSymmetric(horizontal: 10),
|
||||
])
|
||||
|
|
@ -58,6 +61,8 @@ class ButtonWidget extends StatelessWidget {
|
|||
isLoading!),
|
||||
child: BoldTextWidget(
|
||||
title,
|
||||
fontSize: fontSize,
|
||||
textAlign: TextAlign.center,
|
||||
color: Colors.white,
|
||||
).paddingSymmetric(horizontal: 20),
|
||||
),
|
||||
|
|
@ -72,6 +77,8 @@ class ButtonWidget extends StatelessWidget {
|
|||
)
|
||||
: BoldTextWidget(
|
||||
title,
|
||||
fontSize: fontSize,
|
||||
textAlign: TextAlign.center,
|
||||
color: Colors.white,
|
||||
),
|
||||
).onTap(() {
|
||||
|
|
|
|||
|
|
@ -1,8 +1,10 @@
|
|||
import 'dart:convert';
|
||||
import 'dart:developer';
|
||||
|
||||
import 'package:get_storage/get_storage.dart';
|
||||
|
||||
import '../../features/auth/data_layer/model/user.dart';
|
||||
import '../../features/card/data_layer/model/appointment.dart';
|
||||
|
||||
class LocalStorage {
|
||||
final GetStorage storage = GetStorage();
|
||||
|
|
@ -76,4 +78,31 @@ class LocalStorage {
|
|||
Future<void> clearCache() async {
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,8 @@ class PagesTranslations implements Translations {
|
|||
@override
|
||||
Map<String, Map<String, String>> get keys => {
|
||||
'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.',
|
||||
'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.',
|
||||
},
|
||||
'ar': {
|
||||
'schedule_an_appointment': 'جدولة موعد',
|
||||
'you_have_an_appointment_on': 'لديك موعد بتاريخ',
|
||||
'schedule_an_appointment': 'حجز موعد',
|
||||
'There are no notifications to display at this time.':
|
||||
'لا توجد إشعارات لعرضها في الوقت الحالي.',
|
||||
'no_previous_conversations_!': 'لا توجد محادثات سابقة!',
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ class AccountScreen extends StatelessWidget {
|
|||
@override
|
||||
Widget build(BuildContext context) {
|
||||
accountController.getSelectedLanguageIcon();
|
||||
homeController.readUser();
|
||||
// homeController.readUser();
|
||||
return Scaffold(
|
||||
backgroundColor: AppColors.backGroundColor,
|
||||
body: SingleChildScrollView(
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
import 'package:taafee_mobile/features/card/data_layer/model/appointment.dart';
|
||||
|
||||
class User {
|
||||
int id;
|
||||
String firstName;
|
||||
|
|
@ -5,6 +7,7 @@ class User {
|
|||
String email;
|
||||
int chatUserId;
|
||||
String? avatarImage;
|
||||
List<Appointment>? appointments;
|
||||
User({
|
||||
required this.id,
|
||||
required this.firstName,
|
||||
|
|
@ -12,6 +15,7 @@ class User {
|
|||
required this.email,
|
||||
required this.avatarImage,
|
||||
required this.chatUserId,
|
||||
this.appointments,
|
||||
});
|
||||
|
||||
factory User.fromJson(Map<String, dynamic> json) => User(
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import 'package:image_gallery_saver/image_gallery_saver.dart';
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.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/card_images.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 {
|
||||
//---------------data source-----------//
|
||||
CardService cardService = CardService();
|
||||
LocalStorage localStorage = LocalStorage();
|
||||
//----------- model-----------//
|
||||
Rx<AddCardModel> cardModel = AddCardModel.zero().obs;
|
||||
|
||||
|
|
|
|||
41
lib/features/card/data_layer/model/appointment.dart
Normal file
41
lib/features/card/data_layer/model/appointment.dart
Normal 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()}';
|
||||
}
|
||||
}
|
||||
|
|
@ -7,6 +7,7 @@ import 'package:taafee_mobile/common/widgets/button.dart';
|
|||
import 'package:taafee_mobile/common/widgets/text.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/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_service.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(
|
||||
children: [
|
||||
ButtonWidget(
|
||||
|
|
@ -215,7 +219,7 @@ class CardDetailsScreen extends StatelessWidget {
|
|||
const ColorFilter.mode(Colors.white, BlendMode.srcIn),
|
||||
),
|
||||
)
|
||||
.paddingSymmetric(horizontal: 10)
|
||||
.paddingSymmetric(horizontal: 4)
|
||||
.expanded(Responsive.isTablet() ? 1 : 5),
|
||||
ButtonWidget(
|
||||
color: AppColors.emailColor,
|
||||
|
|
@ -227,7 +231,7 @@ class CardDetailsScreen extends StatelessWidget {
|
|||
textColor: Colors.white,
|
||||
child: SvgPicture.asset("assets/icons/Email.svg"),
|
||||
)
|
||||
.paddingSymmetric(horizontal: 10)
|
||||
.paddingSymmetric(horizontal: 4)
|
||||
.expanded(Responsive.isTablet() ? 1 : 5),
|
||||
if (Responsive.isTablet())
|
||||
Visibility(
|
||||
|
|
@ -257,15 +261,78 @@ class CardDetailsScreen extends StatelessWidget {
|
|||
).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(
|
||||
vertical: Responsive.isTablet() ? 20 : 10,
|
||||
vertical: Responsive.isTablet() ? 20 : 4,
|
||||
horizontal: Responsive.isTablet() ? 40 : 10),
|
||||
if (!Responsive.isTablet())
|
||||
Obx(() {
|
||||
return Row(
|
||||
children: [
|
||||
Obx(() {
|
||||
return Visibility(
|
||||
visible:
|
||||
homeController.user.value!.id != cardModel.user.id,
|
||||
child:
|
||||
(homeController.currentCardAppointment.value != null)
|
||||
? ButtonWidget(
|
||||
onTap: () {},
|
||||
fontSize: 12,
|
||||
color: AppColors.secondaryColor,
|
||||
title:
|
||||
'${'you_have_an_appointment_on'.tr} ${homeController.currentCardAppointment.value!.dateTime.toString().substring(0, 11)}',
|
||||
)
|
||||
.paddingSymmetric(horizontal: 4)
|
||||
.expanded(Responsive.isTablet() ? 1 : 5)
|
||||
: ButtonWidget(
|
||||
onTap: () {
|
||||
homeController.scheduleAnAppointment(
|
||||
Appointment(
|
||||
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: Obx(() {
|
||||
return ButtonWidget(
|
||||
visible:
|
||||
chatController.chatUser.id != cardModel.user.chatUserId,
|
||||
child: ButtonWidget(
|
||||
isLoading: chatController.createRoomState.loading,
|
||||
textColor: Colors.white,
|
||||
color: AppColors.messageColor,
|
||||
|
|
@ -284,13 +351,20 @@ class CardDetailsScreen extends StatelessWidget {
|
|||
}
|
||||
},
|
||||
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(
|
||||
height: 60,
|
||||
)
|
||||
),
|
||||
],
|
||||
).paddingSymmetric(horizontal: Responsive.isTablet() ? 20 : 0)),
|
||||
).makeSafeArea();
|
||||
|
|
|
|||
|
|
@ -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/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/home/business_logic_layer/home_controller.dart';
|
||||
|
||||
import '../../../../core/routing/routing_manager.dart';
|
||||
import 'card_header.dart';
|
||||
|
||||
class FirstCardWidget extends StatelessWidget {
|
||||
final CardModel cardModel;
|
||||
const FirstCardWidget(this.cardModel, {super.key});
|
||||
|
||||
final HomeController homeController = Get.find<HomeController>();
|
||||
FirstCardWidget(this.cardModel, {super.key});
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
|
|
@ -95,6 +96,7 @@ class FirstCardWidget extends StatelessWidget {
|
|||
),
|
||||
],
|
||||
).onTap(() {
|
||||
homeController.setCardAppointment(cardModel.id);
|
||||
RoutingManager.to(RouteName.cardDetails, arguments: cardModel);
|
||||
}),
|
||||
],
|
||||
|
|
|
|||
|
|
@ -70,6 +70,7 @@ class MyCardWidget extends StatelessWidget {
|
|||
),
|
||||
],
|
||||
).onTap(() {
|
||||
homeController.setCardAppointment(cardModel.id);
|
||||
RoutingManager.to(RouteName.cardDetails, arguments: cardModel);
|
||||
}),
|
||||
],
|
||||
|
|
|
|||
|
|
@ -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/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/home/business_logic_layer/home_controller.dart';
|
||||
|
||||
import '../../../../common/const/const.dart';
|
||||
import '../../../../core/routing/routing_manager.dart';
|
||||
|
||||
class SecondCardWidget extends StatelessWidget {
|
||||
final CardModel cardModel;
|
||||
const SecondCardWidget(this.cardModel, {super.key});
|
||||
final HomeController homeController = Get.find<HomeController>();
|
||||
SecondCardWidget(this.cardModel, {super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
|
@ -92,6 +94,7 @@ class SecondCardWidget extends StatelessWidget {
|
|||
).paddingSymmetric(horizontal: 5),
|
||||
],
|
||||
).onTap(() {
|
||||
homeController.setCardAppointment(cardModel.id);
|
||||
RoutingManager.to(RouteName.cardDetails, arguments: cardModel);
|
||||
}),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -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/favorite/business_logic_layer/favorite_controller.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 {
|
||||
final CardController cardController = Get.find<CardController>();
|
||||
final FavoriteController favoriteController = Get.find<FavoriteController>();
|
||||
final HomeController homeController = Get.find<HomeController>();
|
||||
FavoriteScreen({super.key});
|
||||
|
||||
@override
|
||||
|
|
@ -41,8 +43,8 @@ class FavoriteScreen extends StatelessWidget {
|
|||
width: Get.width,
|
||||
height: Get.height * 0.75,
|
||||
rxFuture: favoriteController.getFavoriteState,
|
||||
child: () =>
|
||||
(favoriteController.getFavoriteState.result.isNotEmpty)
|
||||
child: () => (favoriteController
|
||||
.getFavoriteState.result.isNotEmpty)
|
||||
? GridViewWidget(
|
||||
mainAxisExtent: 150,
|
||||
count: Responsive.isTablet() ? 3 : 2,
|
||||
|
|
@ -50,12 +52,14 @@ class FavoriteScreen extends StatelessWidget {
|
|||
favoriteController.getFavoriteState.result.length,
|
||||
child: (index) => Obx(() {
|
||||
return FavoriteCardWidget(
|
||||
favoriteModel: favoriteController
|
||||
.getFavoriteState.result[index],
|
||||
favoriteModel:
|
||||
favoriteController.getFavoriteState.result[index],
|
||||
).onTap(() {
|
||||
homeController.setCardAppointment(favoriteController
|
||||
.getFavoriteState.result[index].cardModel.id);
|
||||
RoutingManager.to(RouteName.cardDetails,
|
||||
arguments: favoriteController.getFavoriteState
|
||||
.result[index].cardModel);
|
||||
arguments: favoriteController
|
||||
.getFavoriteState.result[index].cardModel);
|
||||
});
|
||||
}),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import 'package:taafee_mobile/common/widgets/button.dart';
|
|||
import 'package:taafee_mobile/common/widgets/text.dart';
|
||||
import 'package:taafee_mobile/core/local_storage/local_storage.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/home/data_layer/model/city.dart';
|
||||
import 'package:taafee_mobile/features/home/data_layer/model/search.dart';
|
||||
|
|
@ -50,7 +51,6 @@ class HomeController extends GetxController {
|
|||
}
|
||||
|
||||
//------------read user----------////
|
||||
|
||||
//pick avatar image
|
||||
Rx<File?> pickedUserImage = null.obs;
|
||||
RxBool isAvatarImagePicked = false.obs;
|
||||
|
|
@ -64,7 +64,12 @@ class HomeController extends GetxController {
|
|||
} else {
|
||||
isUserHasAvatar.value = false;
|
||||
}
|
||||
|
||||
List<Appointment>? appointments = storage.getAppointments();
|
||||
if (appointments != null) {
|
||||
user.update((val) {
|
||||
val!.appointments = appointments;
|
||||
});
|
||||
}
|
||||
user.refresh();
|
||||
isUserHasAvatar.refresh();
|
||||
}
|
||||
|
|
@ -167,4 +172,46 @@ class HomeController extends GetxController {
|
|||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user