473 lines
20 KiB
Dart
473 lines
20 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:flutter_svg/flutter_svg.dart';
|
|
import 'package:get/get.dart';
|
|
import 'package:taafee_mobile/common/const/const.dart';
|
|
import 'package:taafee_mobile/common/extensions/widget_extension.dart';
|
|
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/core/utils/utils.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';
|
|
import '../../../../common/widgets/header_screen.dart';
|
|
import '../../../../common/widgets/toast.dart';
|
|
import '../../../../core/url launcher/url_launcher_service.dart';
|
|
import '../../../home/business_logic_layer/home_controller.dart';
|
|
import '../../data_layer/model/card_model.dart';
|
|
import '../widgets/appointment_details.dart';
|
|
import '../widgets/appointment_widget.dart';
|
|
import '../widgets/card_email.dart';
|
|
import '../widgets/card_header.dart';
|
|
import '../widgets/card_image.dart';
|
|
import '../widgets/card_information.dart';
|
|
import '../widgets/card_location.dart';
|
|
|
|
class CardDetailsScreen extends StatelessWidget {
|
|
final CardModel cardModel = Get.arguments;
|
|
CardDetailsScreen({super.key});
|
|
final CardController cardController = Get.find<CardController>();
|
|
final HomeController homeController = Get.find<HomeController>();
|
|
final ChatController chatController = Get.find<ChatController>();
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
void appointmentSchedulingDialog(BuildContext context) {
|
|
showDialog(
|
|
context: context,
|
|
builder: (BuildContext context) {
|
|
return AlertDialog(
|
|
shape: RoundedRectangleBorder(
|
|
borderRadius: BorderRadius.circular(20)),
|
|
contentPadding: EdgeInsets.zero,
|
|
actionsPadding: EdgeInsets.zero,
|
|
title: RegularTextWidget(
|
|
"available_times".tr,
|
|
fontSize: 14,
|
|
),
|
|
content: Obx(() {
|
|
if (cardController.availableAppointmentsState.loading ||
|
|
homeController.appointmentSchedulingState.loading) {
|
|
return SizedBox(
|
|
width: 320,
|
|
height: 320,
|
|
child: const CircularProgressIndicator().center());
|
|
}
|
|
return SizedBox(
|
|
height: 320,
|
|
width: 320,
|
|
child: Column(
|
|
children: [
|
|
const SizedBox(
|
|
height: 20,
|
|
),
|
|
SizedBox(
|
|
height: 280,
|
|
child: ListView.builder(
|
|
physics: const BouncingScrollPhysics(),
|
|
itemCount: 12,
|
|
itemBuilder: (context, index) {
|
|
DateTime dateTime = Utils.generateRandomDateTime();
|
|
return AppointmentWidget(dateTime: dateTime)
|
|
.paddingOnly(bottom: 16)
|
|
.onTap(() {
|
|
homeController.scheduleAnAppointment(
|
|
Appointment(
|
|
cardId: cardModel.id,
|
|
dateTime: dateTime,
|
|
user: homeController.user.value!),
|
|
onSuccess: () {
|
|
Toast.showToast(
|
|
'appointment_scheduled_successfully.'.tr);
|
|
RoutingManager.back();
|
|
});
|
|
});
|
|
},
|
|
).paddingOnly(left: 8, right: 8, top: 8, bottom: 8),
|
|
),
|
|
const SizedBox(
|
|
height: 20,
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}),
|
|
);
|
|
});
|
|
}
|
|
|
|
void appointmentDialog(BuildContext context) {
|
|
showDialog(
|
|
context: context,
|
|
builder: (BuildContext context) {
|
|
return AlertDialog(
|
|
shape: RoundedRectangleBorder(
|
|
borderRadius: BorderRadius.circular(20)),
|
|
contentPadding: EdgeInsets.zero,
|
|
actionsPadding: EdgeInsets.zero,
|
|
title: HeaderScreen(
|
|
' ${"appointment".tr}',
|
|
),
|
|
content: AppointmentDetails(
|
|
appointment: homeController.currentCardAppointment.value!),
|
|
);
|
|
});
|
|
}
|
|
|
|
cardController.updateCardNetworkImageUrls(cardModel.cardImages);
|
|
return Scaffold(
|
|
backgroundColor: AppColors.backGroundColor,
|
|
body: SingleChildScrollView(
|
|
child: Column(
|
|
children: [
|
|
if (Responsive.isTablet())
|
|
const SizedBox(
|
|
height: 30,
|
|
),
|
|
HeaderScreen(
|
|
"page_details".tr,
|
|
additionalOnTap: () {
|
|
cardController.cardState.result.clear();
|
|
cardController.getCards();
|
|
},
|
|
)
|
|
.paddingOnly(top: 30, bottom: 30)
|
|
.paddingSymmetric(horizontal: Responsive.isTablet() ? 20 : 20),
|
|
if (Responsive.isTablet())
|
|
const SizedBox(
|
|
height: 20,
|
|
),
|
|
Container(
|
|
width: Get.width * .89,
|
|
decoration: BoxDecoration(
|
|
borderRadius: BorderRadius.circular(4),
|
|
color: Colors.white,
|
|
),
|
|
child: Column(
|
|
crossAxisAlignment: Responsive.isTablet()
|
|
? CrossAxisAlignment.start
|
|
: CrossAxisAlignment.center,
|
|
children: [
|
|
CardHeaderWidget(
|
|
cardModel: cardModel,
|
|
isFromDetailsScreen: true,
|
|
),
|
|
CardInformation(cardModel: cardModel)
|
|
.paddingSymmetric(
|
|
horizontal: Responsive.isTablet() ? 0 : 5, vertical: 5)
|
|
.paddingOnly(
|
|
left: homeController.isArabic.value ? 0 : 3,
|
|
right: homeController.isArabic.value ? 3 : 0,
|
|
),
|
|
const SizedBox(
|
|
height: 8,
|
|
),
|
|
CardEmailWidget(
|
|
cardModel: cardModel,
|
|
).paddingSymmetric(
|
|
horizontal: 7,
|
|
),
|
|
const SizedBox(
|
|
height: 8,
|
|
),
|
|
CardLocationWidget(
|
|
cardModel: cardModel,
|
|
).paddingSymmetric(
|
|
horizontal: 5,
|
|
vertical: 5,
|
|
),
|
|
CardServiceWidget(
|
|
cardModel: cardModel,
|
|
maxLines: 4,
|
|
width: Get.width * 0.69,
|
|
)
|
|
.paddingSymmetric(
|
|
horizontal: 5,
|
|
vertical: 5,
|
|
)
|
|
.paddingOnly(
|
|
left: homeController.isArabic.value ? 0 : 8,
|
|
right: homeController.isArabic.value ? 8 : 0,
|
|
)
|
|
.align(
|
|
alignment: homeController.isArabic.value
|
|
? Alignment.centerRight
|
|
: Alignment.centerLeft),
|
|
CardDetailsWidget(
|
|
cardModel: cardModel,
|
|
).paddingSymmetric(horizontal: Responsive.isTablet() ? 0 : 15),
|
|
if (cardModel.cardImages.isEmpty)
|
|
const SizedBox(
|
|
height: 8,
|
|
),
|
|
if (cardModel.cardImages.isNotEmpty)
|
|
Divider(
|
|
color: AppColors.dividerColor,
|
|
thickness: 1,
|
|
).paddingSymmetric(horizontal: 15),
|
|
if (cardModel.cardImages.isNotEmpty)
|
|
MediumTextWidget(
|
|
"images".tr,
|
|
textAlign: TextAlign.left,
|
|
).paddingSymmetric(horizontal: 15).align(
|
|
alignment: homeController.isArabic.value
|
|
? Alignment.centerRight
|
|
: Alignment.centerLeft),
|
|
if (cardModel.cardImages.isNotEmpty)
|
|
if (Responsive.isTablet())
|
|
Row(
|
|
children: [
|
|
CardImageWidget(
|
|
width: Get.width * 0.4,
|
|
height: Get.width * 0.4,
|
|
cardImages: cardModel.cardImages[0],
|
|
).onTap(() {
|
|
cardController.changeImageIndex(0);
|
|
cardController.pageControllerInitialValue(0);
|
|
RoutingManager.to(RouteName.imagesGalleryView,
|
|
arguments: cardController.cardNetworkImagesUrls);
|
|
}),
|
|
if (cardModel.cardImages.length > 1)
|
|
SizedBox(
|
|
width: Get.width * 0.4,
|
|
height: Get.width * 0.4,
|
|
child: GridView.builder(
|
|
physics: const NeverScrollableScrollPhysics(),
|
|
itemCount: cardModel.cardImages.length - 1,
|
|
shrinkWrap: true,
|
|
gridDelegate:
|
|
SliverGridDelegateWithFixedCrossAxisCount(
|
|
crossAxisCount: Responsive.isTablet() ? 2 : 3,
|
|
childAspectRatio:
|
|
Responsive.isTablet() ? 1 : 1.5,
|
|
),
|
|
itemBuilder: (BuildContext context, index) {
|
|
return CardImageWidget(
|
|
cardImages: cardModel.cardImages[index + 1],
|
|
).onTap(() {
|
|
cardController.changeImageIndex(index + 1);
|
|
cardController
|
|
.pageControllerInitialValue(index + 1);
|
|
RoutingManager.to(RouteName.imagesGalleryView,
|
|
arguments:
|
|
cardController.cardNetworkImagesUrls);
|
|
});
|
|
},
|
|
),
|
|
),
|
|
],
|
|
).paddingOnly(bottom: 20),
|
|
if (!Responsive.isTablet())
|
|
GridView.builder(
|
|
physics: const NeverScrollableScrollPhysics(),
|
|
itemCount: cardModel.cardImages.length,
|
|
shrinkWrap: true,
|
|
gridDelegate:
|
|
const SliverGridDelegateWithFixedCrossAxisCount(
|
|
crossAxisCount: 3,
|
|
childAspectRatio: 1.5,
|
|
),
|
|
itemBuilder: (BuildContext context, index) {
|
|
return CardImageWidget(
|
|
cardImages: cardModel.cardImages[index],
|
|
).onTap(() {
|
|
cardController.changeImageIndex(index);
|
|
cardController.pageControllerInitialValue(index);
|
|
RoutingManager.to(RouteName.imagesGalleryView,
|
|
arguments: cardController.cardNetworkImagesUrls);
|
|
});
|
|
},
|
|
)
|
|
],
|
|
),
|
|
),
|
|
const SizedBox(
|
|
height: 40,
|
|
),
|
|
Row(
|
|
children: [
|
|
ButtonWidget(
|
|
color: AppColors.callColor,
|
|
haveIcon: true,
|
|
onTap: () async {
|
|
await UrlLauncherService.makePhoneCall(cardModel.phoneNumber);
|
|
},
|
|
title: "call_owner".tr,
|
|
textColor: Colors.white,
|
|
child: SvgPicture.asset(
|
|
"assets/icons/phone.svg",
|
|
colorFilter:
|
|
const ColorFilter.mode(Colors.white, BlendMode.srcIn),
|
|
),
|
|
)
|
|
.paddingSymmetric(horizontal: 4)
|
|
.expanded(Responsive.isTablet() ? 1 : 5),
|
|
ButtonWidget(
|
|
color: AppColors.emailColor,
|
|
haveIcon: true,
|
|
onTap: () async {
|
|
await UrlLauncherService.sendEmail(cardModel.user.email);
|
|
},
|
|
title: "email".tr,
|
|
textColor: Colors.white,
|
|
child: SvgPicture.asset("assets/icons/Email.svg"),
|
|
)
|
|
.paddingSymmetric(horizontal: 4)
|
|
.expanded(Responsive.isTablet() ? 1 : 5),
|
|
if (Responsive.isTablet())
|
|
Visibility(
|
|
visible:
|
|
chatController.chatUser.id != cardModel.user.chatUserId,
|
|
child: Obx(() {
|
|
return 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);
|
|
});
|
|
} else {
|
|
Toast.showToast(
|
|
'you_have_no_internet_connection.'.tr);
|
|
}
|
|
},
|
|
title: "start_conversation".tr,
|
|
fontSize: 13,
|
|
child: SvgPicture.asset("assets/icons/message.svg"),
|
|
).expanded(Responsive.isTablet() ? 1 : 5);
|
|
}),
|
|
),
|
|
if (Responsive.isTablet())
|
|
Obx(() {
|
|
return Visibility(
|
|
visible: homeController.user.value!.id != cardModel.user.id,
|
|
child: (homeController.currentCardAppointment.value != null)
|
|
? ButtonWidget(
|
|
haveIcon: true,
|
|
onTap: () {
|
|
appointmentDialog(context);
|
|
},
|
|
fontSize: 13,
|
|
color: AppColors.secondaryColor,
|
|
title: 'you_have_an_appointment'.tr,
|
|
child: const Icon(
|
|
Icons.schedule,
|
|
color: Colors.white,
|
|
),
|
|
)
|
|
.paddingSymmetric(horizontal: 4)
|
|
.expanded(Responsive.isTablet() ? 1 : 5)
|
|
: ButtonWidget(
|
|
onTap: () {
|
|
cardController.getAvailableAppointments();
|
|
appointmentSchedulingDialog(context);
|
|
},
|
|
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),
|
|
);
|
|
}),
|
|
],
|
|
).paddingSymmetric(
|
|
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(
|
|
haveIcon: true,
|
|
onTap: () {
|
|
appointmentDialog(context);
|
|
},
|
|
fontSize: 12,
|
|
color: AppColors.secondaryColor,
|
|
title: 'you_have_an_appointment'.tr,
|
|
child: const Icon(
|
|
Icons.schedule,
|
|
color: Colors.white,
|
|
),
|
|
)
|
|
.paddingSymmetric(horizontal: 4)
|
|
.expanded(Responsive.isTablet() ? 1 : 5)
|
|
: ButtonWidget(
|
|
onTap: () {
|
|
cardController.getAvailableAppointments();
|
|
appointmentSchedulingDialog(context);
|
|
},
|
|
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(
|
|
height: 60,
|
|
),
|
|
],
|
|
).paddingSymmetric(horizontal: Responsive.isTablet() ? 20 : 0)),
|
|
).makeSafeArea();
|
|
}
|
|
}
|