|
|
|
|
@ -1,107 +1,148 @@
|
|
|
|
|
import 'package:carousel_slider/carousel_slider.dart';
|
|
|
|
|
import 'package:flutter/material.dart';
|
|
|
|
|
import 'package:flutter_svg/svg.dart';
|
|
|
|
|
import 'package:mc_common_app/classes/app_state.dart';
|
|
|
|
|
import 'package:mc_common_app/classes/consts.dart';
|
|
|
|
|
import 'package:mc_common_app/config/routes.dart';
|
|
|
|
|
import 'package:mc_common_app/extensions/int_extensions.dart';
|
|
|
|
|
import 'package:mc_common_app/extensions/string_extensions.dart';
|
|
|
|
|
import 'package:mc_common_app/models/appointments_models/appointment_list_model.dart';
|
|
|
|
|
import 'package:mc_common_app/theme/colors.dart';
|
|
|
|
|
import 'package:mc_common_app/utils/enums.dart';
|
|
|
|
|
import 'package:mc_common_app/utils/navigator.dart';
|
|
|
|
|
import 'package:mc_common_app/view_models/appointments_view_model.dart';
|
|
|
|
|
import 'package:mc_common_app/view_models/dashboard_view_model_customer.dart';
|
|
|
|
|
import 'package:mc_common_app/views/advertisement/custom_add_button.dart';
|
|
|
|
|
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
|
|
|
|
|
import 'package:provider/provider.dart';
|
|
|
|
|
|
|
|
|
|
//TODO: Need to make onTapped dynamic
|
|
|
|
|
class CustomerAppointmentSliderWidget extends StatelessWidget {
|
|
|
|
|
final List<AppointmentListModel> myUpComingAppointments;
|
|
|
|
|
bool isNeedToShowEmptyMessage;
|
|
|
|
|
Function()? onAppointmentClick;
|
|
|
|
|
Function(AppointmentListModel)? onAppointmentClick;
|
|
|
|
|
|
|
|
|
|
CustomerAppointmentSliderWidget({Key? key,
|
|
|
|
|
required this.myUpComingAppointments,
|
|
|
|
|
this.isNeedToShowEmptyMessage = false,
|
|
|
|
|
this.onAppointmentClick})
|
|
|
|
|
: super(key: key);
|
|
|
|
|
CustomerAppointmentSliderWidget({Key? key, this.onAppointmentClick}) : super(key: key);
|
|
|
|
|
|
|
|
|
|
@override
|
|
|
|
|
Widget build(BuildContext context) {
|
|
|
|
|
if (myUpComingAppointments.isEmpty) {
|
|
|
|
|
if (isNeedToShowEmptyMessage)
|
|
|
|
|
return "No Upcoming Appointment Available".toText().paddingAll(21);
|
|
|
|
|
return CustomAddButton(
|
|
|
|
|
needsBorder: true,
|
|
|
|
|
bgColor: MyColors.white,
|
|
|
|
|
onTap: () => context.read<DashboardVmCustomer>().onNavbarTapped(0),
|
|
|
|
|
text: "Add New Appointment",
|
|
|
|
|
icon: Container(
|
|
|
|
|
height: 24,
|
|
|
|
|
width: 24,
|
|
|
|
|
decoration: const BoxDecoration(
|
|
|
|
|
shape: BoxShape.circle, color: MyColors.darkTextColor),
|
|
|
|
|
child: const Icon(Icons.add, color: MyColors.white),
|
|
|
|
|
),
|
|
|
|
|
).padding(EdgeInsets.symmetric(vertical: 10, horizontal: 21));
|
|
|
|
|
return Container(
|
|
|
|
|
height: 86,
|
|
|
|
|
child: Row(
|
|
|
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
|
|
|
children: [
|
|
|
|
|
Container(
|
|
|
|
|
height: 24,
|
|
|
|
|
width: 24,
|
|
|
|
|
decoration: BoxDecoration(
|
|
|
|
|
shape: BoxShape.circle, color: MyColors.darkTextColor),
|
|
|
|
|
child: Icon(
|
|
|
|
|
Icons.add,
|
|
|
|
|
color: MyColors.white,
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
SizedBox(width: 10),
|
|
|
|
|
"Add New Appointment".toText(
|
|
|
|
|
fontSize: 15,
|
|
|
|
|
isBold: true,
|
|
|
|
|
color: MyColors.lightTextColor,
|
|
|
|
|
),
|
|
|
|
|
],
|
|
|
|
|
),
|
|
|
|
|
).onPress(() {}).toWhiteContainer(
|
|
|
|
|
width: double.infinity,
|
|
|
|
|
margin: EdgeInsets.symmetric(horizontal: 21, vertical: 10));
|
|
|
|
|
}
|
|
|
|
|
Widget getCorouselWidget(AppType appType, AppointmentsVM appointmentsVM) {
|
|
|
|
|
return CarouselSlider.builder(
|
|
|
|
|
options: CarouselOptions(
|
|
|
|
|
height: 140,
|
|
|
|
|
height: appType == AppType.provider ? 110 : 140,
|
|
|
|
|
viewportFraction: 1.0,
|
|
|
|
|
enlargeCenterPage: false,
|
|
|
|
|
enableInfiniteScroll: false,
|
|
|
|
|
),
|
|
|
|
|
itemCount: myUpComingAppointments.length,
|
|
|
|
|
itemBuilder: (BuildContext context, int itemIndex, int pageViewIndex) =>
|
|
|
|
|
BuildAppointmentContainerForCustomer(
|
|
|
|
|
isForHome: true,
|
|
|
|
|
appointmentListModel: myUpComingAppointments[itemIndex],
|
|
|
|
|
onTapped: isNeedToShowEmptyMessage
|
|
|
|
|
? onAppointmentClick!
|
|
|
|
|
: () =>
|
|
|
|
|
navigateWithName(context, AppRoutes.appointmentDetailView,
|
|
|
|
|
arguments: myUpComingAppointments[itemIndex]),
|
|
|
|
|
),
|
|
|
|
|
itemCount: appointmentsVM.myUpComingAppointments.length,
|
|
|
|
|
itemBuilder: (BuildContext context, int itemIndex, int pageViewIndex) => BuildAppointmentContainerForCustomer(
|
|
|
|
|
isForHome: appType == AppType.provider,
|
|
|
|
|
appointmentListModel: appointmentsVM.myUpComingAppointments[itemIndex],
|
|
|
|
|
onTapped: () {
|
|
|
|
|
if (appType == AppType.provider) {
|
|
|
|
|
onAppointmentClick!(appointmentsVM.myUpComingAppointments[itemIndex]);
|
|
|
|
|
} else {
|
|
|
|
|
navigateWithName(context, AppRoutes.appointmentDetailView, arguments: appointmentsVM.myUpComingAppointments[itemIndex]);
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
),
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@override
|
|
|
|
|
Widget build(BuildContext context) {
|
|
|
|
|
return Consumer(builder: (BuildContext context, AppointmentsVM model, Widget? child) {
|
|
|
|
|
if (model.state == ViewState.busy) {
|
|
|
|
|
return const Center(child: CircularProgressIndicator());
|
|
|
|
|
} else {
|
|
|
|
|
if (AppState().currentAppType == AppType.provider) {
|
|
|
|
|
if (model.myUpComingAppointments.isEmpty) {
|
|
|
|
|
return "No Upcoming Appointment Available".toText().paddingAll(21);
|
|
|
|
|
} else {
|
|
|
|
|
return getCorouselWidget(AppState().currentAppType, model);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
if (model.myUpComingAppointments.isEmpty) {
|
|
|
|
|
return CustomAddButton(
|
|
|
|
|
needsBorder: true,
|
|
|
|
|
bgColor: MyColors.white,
|
|
|
|
|
onTap: () => context.read<DashboardVmCustomer>().onNavbarTapped(0),
|
|
|
|
|
text: "Add New Appointment",
|
|
|
|
|
icon: Container(
|
|
|
|
|
height: 24,
|
|
|
|
|
width: 24,
|
|
|
|
|
decoration: const BoxDecoration(shape: BoxShape.circle, color: MyColors.darkTextColor),
|
|
|
|
|
child: const Icon(Icons.add, color: MyColors.white),
|
|
|
|
|
),
|
|
|
|
|
).padding(EdgeInsets.symmetric(vertical: 10, horizontal: 21));
|
|
|
|
|
} else {
|
|
|
|
|
return getCorouselWidget(AppState().currentAppType, model);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// if (myUpComingAppointments.isEmpty) {
|
|
|
|
|
// if (isNeedToShowEmptyMessage)
|
|
|
|
|
// return "No Upcoming Appointment Available".toText().paddingAll(21);
|
|
|
|
|
// return CustomAddButton(
|
|
|
|
|
// needsBorder: true,
|
|
|
|
|
// bgColor: MyColors.white,
|
|
|
|
|
// onTap: () => context.read<DashboardVmCustomer>().onNavbarTapped(0),
|
|
|
|
|
// text: "Add New Appointment",
|
|
|
|
|
// icon: Container(
|
|
|
|
|
// height: 24,
|
|
|
|
|
// width: 24,
|
|
|
|
|
// decoration: const BoxDecoration(
|
|
|
|
|
// shape: BoxShape.circle, color: MyColors.darkTextColor),
|
|
|
|
|
// child: const Icon(Icons.add, color: MyColors.white),
|
|
|
|
|
// ),
|
|
|
|
|
// ).padding(EdgeInsets.symmetric(vertical: 10, horizontal: 21));
|
|
|
|
|
// return Container(
|
|
|
|
|
// height: 86,
|
|
|
|
|
// child: Row(
|
|
|
|
|
// mainAxisAlignment: MainAxisAlignment.center,
|
|
|
|
|
// children: [
|
|
|
|
|
// Container(
|
|
|
|
|
// height: 24,
|
|
|
|
|
// width: 24,
|
|
|
|
|
// decoration: BoxDecoration(
|
|
|
|
|
// shape: BoxShape.circle, color: MyColors.darkTextColor),
|
|
|
|
|
// child: Icon(
|
|
|
|
|
// Icons.add,
|
|
|
|
|
// color: MyColors.white,
|
|
|
|
|
// ),
|
|
|
|
|
// ),
|
|
|
|
|
// SizedBox(width: 10),
|
|
|
|
|
// "Add New Appointment".toText(
|
|
|
|
|
// fontSize: 15,
|
|
|
|
|
// isBold: true,
|
|
|
|
|
// color: MyColors.lightTextColor,
|
|
|
|
|
// ),
|
|
|
|
|
// ],
|
|
|
|
|
// ),
|
|
|
|
|
// ).onPress(() {}).toWhiteContainer(
|
|
|
|
|
// width: double.infinity,
|
|
|
|
|
// margin: EdgeInsets.symmetric(horizontal: 21, vertical: 10));
|
|
|
|
|
// }
|
|
|
|
|
// return CarouselSlider.builder(
|
|
|
|
|
// options: CarouselOptions(
|
|
|
|
|
// height: 140,
|
|
|
|
|
// viewportFraction: 1.0,
|
|
|
|
|
// enlargeCenterPage: false,
|
|
|
|
|
// enableInfiniteScroll: false,
|
|
|
|
|
// ),
|
|
|
|
|
// itemCount: myUpComingAppointments.length,
|
|
|
|
|
// itemBuilder: (BuildContext context, int itemIndex, int pageViewIndex) => BuildAppointmentContainerForCustomer(
|
|
|
|
|
// isForHome: true,
|
|
|
|
|
// appointmentListModel: myUpComingAppointments[itemIndex],
|
|
|
|
|
// onTapped: isNeedToShowEmptyMessage ? onAppointmentClick! : () => navigateWithName(context, AppRoutes.appointmentDetailView, arguments: myUpComingAppointments[itemIndex]),
|
|
|
|
|
// ),
|
|
|
|
|
// );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class BuildAppointmentContainerForCustomer extends StatelessWidget {
|
|
|
|
|
final bool? isForHome;
|
|
|
|
|
final AppointmentListModel? appointmentListModel;
|
|
|
|
|
final Function() onTapped;
|
|
|
|
|
final Function()? onTapped;
|
|
|
|
|
|
|
|
|
|
const BuildAppointmentContainerForCustomer({Key? key,
|
|
|
|
|
this.isForHome = false,
|
|
|
|
|
required this.onTapped,
|
|
|
|
|
required this.appointmentListModel})
|
|
|
|
|
: super(key: key);
|
|
|
|
|
const BuildAppointmentContainerForCustomer({Key? key, this.isForHome = false, this.onTapped, required this.appointmentListModel}) : super(key: key);
|
|
|
|
|
|
|
|
|
|
Widget showServices(String title, String icon, {bool isMoreText = false}) {
|
|
|
|
|
return Row(
|
|
|
|
|
@ -121,18 +162,15 @@ class BuildAppointmentContainerForCustomer extends StatelessWidget {
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
List<Widget> buildServicesFromAppointment(
|
|
|
|
|
{required AppointmentListModel appointmentListModel}) {
|
|
|
|
|
if (appointmentListModel.appointmentServicesList == null ||
|
|
|
|
|
appointmentListModel.appointmentServicesList!.isEmpty) {
|
|
|
|
|
List<Widget> buildServicesFromAppointment({required AppointmentListModel appointmentListModel}) {
|
|
|
|
|
if (appointmentListModel.appointmentServicesList == null || appointmentListModel.appointmentServicesList!.isEmpty) {
|
|
|
|
|
return [SizedBox()];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (appointmentListModel.appointmentServicesList!.length == 1) {
|
|
|
|
|
return [
|
|
|
|
|
showServices(
|
|
|
|
|
appointmentListModel
|
|
|
|
|
.appointmentServicesList![0].providerServiceDescription,
|
|
|
|
|
appointmentListModel.appointmentServicesList![0].providerServiceDescription,
|
|
|
|
|
MyAssets.modificationsIcon,
|
|
|
|
|
)
|
|
|
|
|
];
|
|
|
|
|
@ -140,11 +178,7 @@ class BuildAppointmentContainerForCustomer extends StatelessWidget {
|
|
|
|
|
|
|
|
|
|
List<Widget> servicesList = List.generate(
|
|
|
|
|
2,
|
|
|
|
|
(index) =>
|
|
|
|
|
showServices(
|
|
|
|
|
appointmentListModel
|
|
|
|
|
.appointmentServicesList![index].providerServiceDescription,
|
|
|
|
|
MyAssets.modificationsIcon),
|
|
|
|
|
(index) => showServices(appointmentListModel.appointmentServicesList![index].providerServiceDescription, MyAssets.modificationsIcon),
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
if (appointmentListModel.appointmentServicesList!.length > 1) {
|
|
|
|
|
@ -170,33 +204,30 @@ class BuildAppointmentContainerForCustomer extends StatelessWidget {
|
|
|
|
|
children: [
|
|
|
|
|
isForHome != null && isForHome!
|
|
|
|
|
? Image.asset(
|
|
|
|
|
MyAssets.bnCar,
|
|
|
|
|
width: 56,
|
|
|
|
|
height: 56,
|
|
|
|
|
fit: BoxFit.fill,
|
|
|
|
|
).toCircle(borderRadius: 100)
|
|
|
|
|
MyAssets.bnCar,
|
|
|
|
|
width: 56,
|
|
|
|
|
height: 56,
|
|
|
|
|
fit: BoxFit.fill,
|
|
|
|
|
).toCircle(borderRadius: 100)
|
|
|
|
|
: Image.asset(
|
|
|
|
|
MyAssets.bnCar,
|
|
|
|
|
width: 80,
|
|
|
|
|
height: 85,
|
|
|
|
|
fit: BoxFit.cover,
|
|
|
|
|
),
|
|
|
|
|
MyAssets.bnCar,
|
|
|
|
|
width: 80,
|
|
|
|
|
height: 85,
|
|
|
|
|
fit: BoxFit.cover,
|
|
|
|
|
),
|
|
|
|
|
8.width,
|
|
|
|
|
Expanded(
|
|
|
|
|
child: Column(
|
|
|
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
|
|
mainAxisAlignment: MainAxisAlignment.start,
|
|
|
|
|
children: [
|
|
|
|
|
(appointmentListModel!.providerName ?? "").toText(
|
|
|
|
|
color: MyColors.black, isBold: true, fontSize: 16),
|
|
|
|
|
(AppState().currentAppType == AppType.provider ? appointmentListModel!.customerName ?? "" : appointmentListModel!.branchName ?? "")
|
|
|
|
|
.toText(color: MyColors.black, isBold: true, fontSize: 16),
|
|
|
|
|
Row(
|
|
|
|
|
children: [
|
|
|
|
|
MyAssets.miniClock.buildSvg(height: 12),
|
|
|
|
|
2.width,
|
|
|
|
|
"${appointmentListModel!.duration ??
|
|
|
|
|
""} ${appointmentListModel!.appointmentDate!
|
|
|
|
|
.toFormattedDateWithoutTime()}"
|
|
|
|
|
.toText(
|
|
|
|
|
"${appointmentListModel!.duration ?? ""} ${appointmentListModel!.appointmentDate!.toFormattedDateWithoutTime()}".toText(
|
|
|
|
|
color: MyColors.lightTextColor,
|
|
|
|
|
fontSize: 12,
|
|
|
|
|
),
|
|
|
|
|
@ -205,42 +236,38 @@ class BuildAppointmentContainerForCustomer extends StatelessWidget {
|
|
|
|
|
9.height,
|
|
|
|
|
isForHome != null && isForHome!
|
|
|
|
|
? Row(
|
|
|
|
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
|
|
|
crossAxisAlignment: CrossAxisAlignment.end,
|
|
|
|
|
children: [
|
|
|
|
|
"Appointment Details".toText(
|
|
|
|
|
color: MyColors.primaryColor,
|
|
|
|
|
isUnderLine: true,
|
|
|
|
|
isBold: true,
|
|
|
|
|
fontSize: 14,
|
|
|
|
|
),
|
|
|
|
|
const Icon(Icons.arrow_forward),
|
|
|
|
|
],
|
|
|
|
|
)
|
|
|
|
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
|
|
|
crossAxisAlignment: CrossAxisAlignment.end,
|
|
|
|
|
children: [
|
|
|
|
|
"Appointment Details".toText(
|
|
|
|
|
color: MyColors.primaryColor,
|
|
|
|
|
isUnderLine: true,
|
|
|
|
|
isBold: true,
|
|
|
|
|
fontSize: 14,
|
|
|
|
|
),
|
|
|
|
|
const Icon(Icons.arrow_forward),
|
|
|
|
|
],
|
|
|
|
|
)
|
|
|
|
|
: Row(
|
|
|
|
|
crossAxisAlignment: CrossAxisAlignment.end,
|
|
|
|
|
children: [
|
|
|
|
|
Expanded(
|
|
|
|
|
child: Column(
|
|
|
|
|
children: buildServicesFromAppointment(
|
|
|
|
|
appointmentListModel:
|
|
|
|
|
appointmentListModel!),
|
|
|
|
|
crossAxisAlignment: CrossAxisAlignment.end,
|
|
|
|
|
children: [
|
|
|
|
|
Expanded(
|
|
|
|
|
child: Column(
|
|
|
|
|
children: buildServicesFromAppointment(appointmentListModel: appointmentListModel!),
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
const Icon(
|
|
|
|
|
Icons.arrow_forward,
|
|
|
|
|
),
|
|
|
|
|
],
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
const Icon(
|
|
|
|
|
Icons.arrow_forward,
|
|
|
|
|
),
|
|
|
|
|
],
|
|
|
|
|
),
|
|
|
|
|
],
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
],
|
|
|
|
|
),
|
|
|
|
|
],
|
|
|
|
|
)
|
|
|
|
|
.onPress(onTapped)
|
|
|
|
|
.toWhiteContainer(width: double.infinity, allPading: 12),
|
|
|
|
|
).onPress(onTapped!).toWhiteContainer(width: double.infinity, allPading: 12),
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|