aDDED cUSTOM cALENDER
parent
5bc5ca8954
commit
120dc86309
@ -1,9 +1,160 @@
|
||||
import 'package:car_customer_app/view_models/appointments_view_model.dart';
|
||||
import 'package:car_customer_app/views/appointments/widgets/appointment_service_pick_bottom_sheet.dart';
|
||||
import 'package:car_customer_app/views/appointments/widgets/custom_calender_widget.dart';
|
||||
import 'package:flutter/material.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/service_schedule_model.dart';
|
||||
import 'package:mc_common_app/models/services/item_model.dart';
|
||||
import 'package:mc_common_app/models/widgets_models.dart';
|
||||
import 'package:mc_common_app/theme/colors.dart';
|
||||
import 'package:mc_common_app/utils/navigator.dart';
|
||||
import 'package:mc_common_app/views/advertisement/custom_add_button.dart';
|
||||
import 'package:mc_common_app/widgets/button/show_fill_button.dart';
|
||||
import 'package:mc_common_app/widgets/common_widgets/app_bar.dart';
|
||||
import 'package:mc_common_app/widgets/common_widgets/info_bottom_sheet.dart';
|
||||
import 'package:mc_common_app/widgets/common_widgets/time_slots.dart';
|
||||
import 'package:mc_common_app/widgets/dropdown/dropdow_field.dart';
|
||||
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class BookAppointmentSchedulesView extends StatelessWidget {
|
||||
const BookAppointmentSchedulesView({super.key});
|
||||
BookAppointmentSchedulesView({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return const Placeholder();
|
||||
return Scaffold(
|
||||
appBar: CustomAppBar(
|
||||
title: "Book Appointment",
|
||||
isRemoveBackButton: false,
|
||||
isDrawerEnabled: false,
|
||||
actions: [MyAssets.searchIcon.buildSvg().paddingOnly(right: 21)],
|
||||
onBackButtonTapped: () => Navigator.pop(context),
|
||||
),
|
||||
body: Consumer(
|
||||
builder: (BuildContext context, AppointmentsVM appointmentsVM, Widget? child) {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
21.height,
|
||||
ListView.builder(
|
||||
shrinkWrap: true,
|
||||
itemCount: appointmentsVM.serviceAppointmentScheduleList.length,
|
||||
itemBuilder: (BuildContext context, int scheduleIndex) {
|
||||
ServiceAppointmentScheduleModel scheduleData = appointmentsVM.serviceAppointmentScheduleList[scheduleIndex];
|
||||
return ExpansionTile(
|
||||
tilePadding: EdgeInsets.symmetric(horizontal: 21, vertical: 10),
|
||||
childrenPadding: EdgeInsets.only(left: 16, bottom: 10, right: 16),
|
||||
title: Column(
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: "Schedule ${scheduleIndex + 1}".toText(fontSize: 20, isBold: true),
|
||||
),
|
||||
],
|
||||
),
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
"Service Location: ".toText(fontSize: 12, color: MyColors.lightTextColor, isBold: true),
|
||||
("${scheduleData.appointmentType == 2 ? "Home" : "Workshop"}").toText(fontSize: 12, isBold: true).expand(),
|
||||
],
|
||||
),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
5.height,
|
||||
ListView.builder(
|
||||
physics: NeverScrollableScrollPhysics(),
|
||||
shrinkWrap: true,
|
||||
itemCount: appointmentsVM.servicesInSchedule.length,
|
||||
itemBuilder: (BuildContext context, int serviceIndex) {
|
||||
DropValue selectedService = appointmentsVM.servicesInSchedule[serviceIndex];
|
||||
return Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: ("${serviceIndex + 1}. ${selectedService.value}").toText(fontSize: 15, isBold: true, color: MyColors.lightTextColor),
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
children: [
|
||||
Column(
|
||||
children: [
|
||||
if (true) ...[
|
||||
// SizedBox(
|
||||
// width: double.infinity,
|
||||
// child: BuildDateSlotsForAppointment(
|
||||
// customDateSlots: scheduleData.customTimeDateSlotList ?? [],
|
||||
// onPressed: (dateIndex) {
|
||||
// appointmentsVM.updateSelectedAppointmentDate(scheduleIndex: scheduleIndex, dateIndex: dateIndex);
|
||||
// },
|
||||
// ),
|
||||
// ),
|
||||
CustomCalenderWidget(customTimeDateSlotList: scheduleData.customTimeDateSlotList ?? []),
|
||||
],
|
||||
if (appointmentsVM.serviceAppointmentScheduleList[scheduleIndex].selectedDateIndex != null) ...[
|
||||
5.height,
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
("Available Slots").toText(fontSize: 14, isBold: true),
|
||||
],
|
||||
),
|
||||
5.height,
|
||||
SizedBox(
|
||||
width: double.infinity,
|
||||
child: BuildTimeSlots(
|
||||
timeSlots: appointmentsVM.serviceAppointmentScheduleList[scheduleIndex]
|
||||
.customTimeDateSlotList![appointmentsVM.serviceAppointmentScheduleList[scheduleIndex].selectedDateIndex!].availableSlots ??
|
||||
[],
|
||||
onPressed: (slotIndex) {
|
||||
appointmentsVM.updateSelectedAppointmentSlotByDate(scheduleIndex: scheduleIndex, slotIndex: slotIndex);
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
],
|
||||
).toWhiteContainer(width: double.infinity, margin: const EdgeInsets.symmetric(horizontal: 21, vertical: 10));
|
||||
},
|
||||
).expand(),
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: ShowFillButton(
|
||||
txtColor: MyColors.black,
|
||||
maxHeight: 55,
|
||||
title: "Cancel",
|
||||
onPressed: () {},
|
||||
backgroundColor: MyColors.greyButtonColor,
|
||||
),
|
||||
),
|
||||
12.width,
|
||||
Expanded(
|
||||
child: ShowFillButton(
|
||||
maxHeight: 55,
|
||||
title: "Review",
|
||||
onPressed: () {
|
||||
appointmentsVM.onReviewButtonPressed(context);
|
||||
},
|
||||
backgroundColor: MyColors.darkPrimaryColor,
|
||||
),
|
||||
)
|
||||
],
|
||||
).paddingAll(21)
|
||||
],
|
||||
);
|
||||
},
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,215 @@
|
||||
import 'dart:developer';
|
||||
|
||||
import 'package:car_customer_app/view_models/appointments_view_model.dart';
|
||||
import 'package:flutter/material.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/service_schedule_model.dart';
|
||||
import 'package:mc_common_app/theme/colors.dart';
|
||||
import 'package:mc_common_app/widgets/dropdown/dropdow_field.dart';
|
||||
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
|
||||
import 'package:table_calendar/table_calendar.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
|
||||
class CustomCalenderWidget extends StatefulWidget {
|
||||
final List<CustomTimeDateSlotModel>? customTimeDateSlotList;
|
||||
|
||||
const CustomCalenderWidget({super.key, required this.customTimeDateSlotList});
|
||||
|
||||
@override
|
||||
State<CustomCalenderWidget> createState() => _CustomCalenderWidgetState();
|
||||
}
|
||||
|
||||
class _CustomCalenderWidgetState extends State<CustomCalenderWidget> {
|
||||
List<DateTime> allDates = [];
|
||||
List<DropValue> allMonths = [];
|
||||
List<DateTime> datesInSelectedMonth = [];
|
||||
CalendarFormat _calendarFormat = CalendarFormat.month;
|
||||
|
||||
late int selectedMonth;
|
||||
late int selectedYear;
|
||||
|
||||
DateTime? _selectedDay;
|
||||
|
||||
DateTime _focusedDay = DateTime.now();
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
populateDateList();
|
||||
}
|
||||
|
||||
populateDateList() {
|
||||
for (var value in widget.customTimeDateSlotList!) {
|
||||
DateTime dt = DateFormat('dd MMMM, yyyy').parse(value.date!.date);
|
||||
// TODO: THIS COMPARISON NEEDS TO BE FIXED!!!!!
|
||||
// TODO: BECAUSE WE CAN ONLY VALUE IN DROPDOWN, SO SUBVALUE IS OF NO USE!!
|
||||
|
||||
DropValue dv = DropValue(dt.month, "${dt.month.getMonthNameByNumber()}, ${dt.year}", "");
|
||||
allDates.add(dt);
|
||||
|
||||
if (!ifMonthAlreadyThere(dv)) {
|
||||
allMonths.add(dv);
|
||||
}
|
||||
}
|
||||
|
||||
selectedMonth = allDates.first.month;
|
||||
selectedYear = allDates.first.year;
|
||||
datesInSelectedMonth = allDates.where((element) => element.month == selectedMonth).toList();
|
||||
}
|
||||
|
||||
bool ifMonthAlreadyThere(DropValue monthDate) {
|
||||
int index = allMonths.indexWhere((element) => element.id == monthDate.id && element.subValue == monthDate.subValue);
|
||||
if (index == -1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ifDateAlreadyThere(DateTime dt) {
|
||||
int index = allDates.indexWhere((element) => dt.month == element.month && dt.year == element.year);
|
||||
if (index == -1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Consumer(
|
||||
builder: (BuildContext context, AppointmentsVM appointmentsVM, Widget? child) {
|
||||
return Column(
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Expanded(
|
||||
child: Builder(builder: (context) {
|
||||
return DropdownField(
|
||||
(DropValue value) {
|
||||
setState(() {
|
||||
selectedYear = int.parse(value.value.split(',')[1]);
|
||||
selectedMonth = value.value.split(',')[0].getMonthNumberByName();
|
||||
});
|
||||
},
|
||||
list: allMonths,
|
||||
// dropdownValue: DropValue(1, "${selectedMonth.getMonthNameByNumber()}jhvk,", "${selectedYear}"),
|
||||
hint: "${selectedMonth.getMonthNameByNumber()}, $selectedYear",
|
||||
errorValue: "",
|
||||
showAppointmentPickerVariant: true,
|
||||
);
|
||||
}),
|
||||
),
|
||||
Spacer(),
|
||||
Icon(
|
||||
Icons.calendar_today,
|
||||
color: Colors.black,
|
||||
size: 18,
|
||||
).paddingOnly(right: 10)
|
||||
],
|
||||
).paddingOnly(left: 6, right: 0),
|
||||
TableCalendar(
|
||||
headerVisible: false,
|
||||
firstDay: datesInSelectedMonth.first,
|
||||
lastDay: datesInSelectedMonth.last,
|
||||
focusedDay: _focusedDay,
|
||||
calendarFormat: _calendarFormat,
|
||||
weekendDays: [DateTime.friday, DateTime.saturday],
|
||||
daysOfWeekHeight: 30,
|
||||
availableGestures: AvailableGestures.none,
|
||||
daysOfWeekStyle: DaysOfWeekStyle(
|
||||
weekdayStyle: TextStyle(fontSize: 14, color: MyColors.black),
|
||||
weekendStyle: TextStyle(fontSize: 14, color: MyColors.black.withOpacity(0.5)),
|
||||
),
|
||||
calendarBuilders: CalendarBuilders(
|
||||
todayBuilder: (BuildContext context, DateTime dateTime1, DateTime dateTime2) {
|
||||
return Container(
|
||||
height: 50,
|
||||
width: 50,
|
||||
margin: EdgeInsets.all(5),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.blueAccent.withOpacity(0.4),
|
||||
border: Border.all(color: Colors.orange, width: 2),
|
||||
shape: BoxShape.circle,
|
||||
),
|
||||
alignment: Alignment.center,
|
||||
child: Text(
|
||||
dateTime1.day.toString(),
|
||||
),
|
||||
);
|
||||
},
|
||||
selectedBuilder: (BuildContext context, DateTime dateTime1, DateTime dateTime2) {
|
||||
return Container(
|
||||
height: 50,
|
||||
width: 50,
|
||||
margin: EdgeInsets.all(5),
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
color: MyColors.darkIconColor,
|
||||
),
|
||||
alignment: Alignment.center,
|
||||
child: Text(
|
||||
dateTime2.day.toString(),
|
||||
style: TextStyle(color: MyColors.white),
|
||||
),
|
||||
);
|
||||
},
|
||||
defaultBuilder: (BuildContext context, DateTime dateTime1, DateTime dateTime2) {
|
||||
return Container(
|
||||
height: 50,
|
||||
width: 50,
|
||||
margin: EdgeInsets.all(5),
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(color: Colors.orange, width: 2),
|
||||
shape: BoxShape.circle,
|
||||
),
|
||||
alignment: Alignment.center,
|
||||
child: Text(
|
||||
dateTime1.day.toString(),
|
||||
),
|
||||
);
|
||||
},
|
||||
disabledBuilder: (BuildContext context, DateTime dateTime1, DateTime selectedDt) {
|
||||
return Container(
|
||||
height: 50,
|
||||
width: 50,
|
||||
margin: EdgeInsets.all(5),
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(color: Colors.grey),
|
||||
shape: BoxShape.circle,
|
||||
),
|
||||
alignment: Alignment.center,
|
||||
child: Text(
|
||||
dateTime1.day.toString(),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
headerStyle: HeaderStyle(formatButtonVisible: false),
|
||||
selectedDayPredicate: (day) {
|
||||
// Use `selectedDayPredicate` to determine which day is currently selected.
|
||||
// If this returns true, then `day` will be marked as selected.
|
||||
|
||||
// Using `isSameDay` is recommended to disregard
|
||||
// the time-part of compared DateTime objects.
|
||||
return isSameDay(_selectedDay, day);
|
||||
},
|
||||
onDaySelected: (selectedDay, focusedDay) {
|
||||
if (!isSameDay(_selectedDay, selectedDay)) {
|
||||
// Call `setState()` when updating the selected day
|
||||
setState(() {
|
||||
_selectedDay = selectedDay;
|
||||
_focusedDay = selectedDay;
|
||||
});
|
||||
}
|
||||
},
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue