import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/models/Appointments/AppoimentAllHistoryResultList.dart'; import 'package:diplomaticquarterapp/models/Appointments/DoctorListResponse.dart'; import 'package:diplomaticquarterapp/models/Appointments/FreeSlot.dart'; import 'package:diplomaticquarterapp/models/Appointments/PatientShareResposne.dart'; import 'package:diplomaticquarterapp/models/Appointments/timeSlot.dart'; import 'package:diplomaticquarterapp/models/Appointments/toDoCountProviderModel.dart'; import 'package:diplomaticquarterapp/models/CovidDriveThru/CovidTestProceduresResponse.dart'; import 'package:diplomaticquarterapp/models/CovidDriveThru/DriveThroughTestingCenterModel.dart'; import 'package:diplomaticquarterapp/pages/Covid-DriveThru/covid-payment-alert.dart'; import 'package:diplomaticquarterapp/services/appointment_services/GetDoctorsList.dart'; import 'package:diplomaticquarterapp/services/clinic_services/get_clinic_service.dart'; import 'package:diplomaticquarterapp/services/covid-drivethru/covid-drivethru.dart'; import 'package:diplomaticquarterapp/theme/colors.dart'; import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/uitl/utils_new.dart'; import 'package:diplomaticquarterapp/widgets/dialogs/confirm_dialog.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; import 'package:provider/provider.dart'; import 'package:syncfusion_flutter_calendar/calendar.dart'; class CovidTimeSlots extends StatefulWidget { int projectID; static bool areSlotsAvailable = false; static DateTime selectedAppoDateTime; static String selectedDate; static String selectedTime; CovidTestProceduresResponse selectedProcedure; DriveThroughTestingCenterModel selectedProject; int selectedClinicID; int selectedDoctorID; var language; PatientShareResponse patientShareResponse; CovidTimeSlots({@required this.projectID, @required this.selectedProcedure, @required this.selectedProject}); @override _CovidTimeSlotsState createState() => _CovidTimeSlotsState(); } class _CovidTimeSlotsState extends State with TickerProviderStateMixin { Map _events; AnimationController _animationController; CalendarController _calendarController; AppSharedPreferences sharedPref = new AppSharedPreferences(); var selectedDate = ""; dynamic selectedDateJSON; dynamic jsonFreeSlots; List docFreeSlots = []; List dayEvents = []; int selectedButtonIndex = 0; dynamic freeSlotsResponse; ScrollController _scrollController; ToDoCountProviderModel toDoProvider; ProjectViewModel projectViewModel; @override void initState() { final _selectedDay = DateTime.now(); widget.patientShareResponse = new PatientShareResponse(); _scrollController = new ScrollController(); _events = { _selectedDay: ['Event A0'] }; WidgetsBinding.instance.addPostFrameCallback((_) => getCovidFreeSlots(context, widget.projectID)); _calendarController = CalendarController(); _animationController = AnimationController( vsync: this, duration: const Duration(milliseconds: 50), ); _animationController.forward(); super.initState(); } @override void dispose() { _animationController.dispose(); _calendarController.dispose(); super.dispose(); } void _onDaySelected(DateTime day, ProjectViewModel projectViewModel) { final DateFormat formatter = DateFormat('yyyy-MM-dd'); setState(() { this.selectedDate = DateUtil.getWeekDayMonthDayYearDateFormatted(day, projectViewModel.isArabic ? "ar" : "en"); openTimeSlotsPickerForDate(day, docFreeSlots); CovidTimeSlots.selectedDate = formatter.format(day); _calendarController.selectedDate = day; print(CovidTimeSlots.selectedDate); }); } @override Widget build(BuildContext context) { projectViewModel = Provider.of(context); toDoProvider = Provider.of(context); return AppScaffold( appBarTitle: TranslationBase.of(context).covidTest, isShowAppBar: true, showNewAppBar: true, showNewAppBarTitle: true, backgroundColor: CustomColors.appBackgroudGrey2Color, body: Column( children: [ Expanded( child: SingleChildScrollView( child: Container( margin: EdgeInsets.fromLTRB(15.0, 15.0, 15.0, 0.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.max, children: [ Text( TranslationBase.of(context).selectAppo, style: TextStyle( color: Colors.black, fontSize: 16.0, letterSpacing: -0.64, fontWeight: FontWeight.w600, ), ), mHeight(12), Container( decoration: cardRadius(12), child: _buildTableCalendarWithBuilders(projectViewModel), ), mHeight(12), Text( selectedDate, style: TextStyle( fontSize: 16.0, fontWeight: FontWeight.bold, letterSpacing: -0.64, ), ), mHeight(8), CovidTimeSlots.areSlotsAvailable ? Container( height: 40, child: ListView.builder( controller: _scrollController, scrollDirection: Axis.horizontal, itemCount: dayEvents.length, itemBuilder: (context, index) { return Container( margin: EdgeInsets.only(right: (index == dayEvents.length - 1) ? 0 : 5.0, left: index == 0 ? 0 : 5), child: ButtonTheme( shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(5.0), side: BorderSide( color: index == selectedButtonIndex ? CustomColors.green : Colors.black, //Color of the border style: BorderStyle.solid, //Style of the border width: 1.5, //width of the border ), ), minWidth: MediaQuery.of(context).size.width * 0.2, child: index == selectedButtonIndex ? getSelectedButton(index) : getNormalButton(index)), ); }, ), ) : Center( child: Padding( padding: const EdgeInsets.only(left: 12.0, right: 12.0), child: Text(TranslationBase.of(context).noSlotsError, style: TextStyle(fontSize: 14.0, fontWeight: FontWeight.w600, letterSpacing: -0.46, color: CustomColors.grey)), )), ], ), ), SizedBox( height: 100.0, ), ], ), ), ), ), Container( margin: EdgeInsets.zero, decoration: cardRadius(0), child: Container( width: double.infinity, padding: EdgeInsets.all(12), child: ButtonTheme( shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(10.0), ), minWidth: MediaQuery.of(context).size.width * 0.7, height: 45.0, child: RaisedButton( color: CustomColors.green, textColor: Colors.white, disabledTextColor: Colors.white, elevation: 0, disabledColor: Colors.grey[500], onPressed: () { bookCovidTestAppointment(); }, child: Text( TranslationBase.of(context).bookAppo, style: TextStyle( fontSize: 16.0, letterSpacing: -0.64, ), ), ), ), ), ) ], ), ); } Widget _buildTableCalendarWithBuilders(ProjectViewModel projectViewModel) { return SfCalendar( controller: _calendarController, minDate: DateTime.now(), showNavigationArrow: true, headerStyle: CalendarHeaderStyle(textAlign: TextAlign.center, textStyle: TextStyle(fontSize: 14.0, fontWeight: FontWeight.w600, letterSpacing: -0.46)), viewHeaderStyle: ViewHeaderStyle(dayTextStyle: TextStyle(fontSize: 12.0, fontWeight: FontWeight.w600, letterSpacing: -0.46, color: CustomColors.black)), view: CalendarView.month, todayHighlightColor: CustomColors.green, selectionDecoration: containerColorRadiusBorderWidthCircular(Colors.transparent, 4, CustomColors.green, 2.5), cellBorderColor: Colors.white, dataSource: MeetingDataSource(_getDataSource()), monthViewSettings: const MonthViewSettings(appointmentDisplayMode: MonthAppointmentDisplayMode.indicator, showTrailingAndLeadingDates: false, appointmentDisplayCount: 1), onTap: (CalendarTapDetails details) { _calendarController.selectedDate = details.date; _onDaySelected(details.date, projectViewModel); }, ); } List _getDataSource() { final List meetings = []; _events.forEach((key, value) { final DateTime startTime = DateTime(key.year, key.month, key.day, 9, 0, 0); final DateTime endTime = startTime.add(const Duration(minutes: 20)); meetings.add(Meeting("", startTime, endTime, CustomColors.green, false)); }); return meetings; } openTimeSlotsPickerForDate(DateTime dateStart, List freeSlots) { dayEvents.clear(); DateTime dateStartObj = new DateTime(dateStart.year, dateStart.month, dateStart.day, 0, 0, 0, 0, 0); freeSlots.forEach((v) { if (v.start == dateStartObj) dayEvents.add(v); }); setState(() { if (dayEvents.length != 0) { CovidTimeSlots.areSlotsAvailable = true; selectedButtonIndex = 0; CovidTimeSlots.selectedTime = dayEvents[selectedButtonIndex].isoTime; } else CovidTimeSlots.areSlotsAvailable = false; }); } Future> _getJSONSlots() async { Map _eventsParsed; List slotsList = []; DateTime date; final DateFormat formatter = DateFormat('HH:mm'); final DateFormat dateFormatter = DateFormat('yyyy-MM-dd'); for (var i = 0; i < freeSlotsResponse.length; i++) { date = DateUtil.convertStringToDate(freeSlotsResponse[i]['FreeTimeSlots']); slotsList.add(FreeSlot(date, ['slot'])); docFreeSlots.add(TimeSlot(isoTime: formatter.format(date), start: new DateTime(date.year, date.month, date.day, 0, 0, 0, 0), end: date)); } _eventsParsed = Map.fromIterable(slotsList, key: (e) => e.slot, value: (e) => e.event); setState(() { CovidTimeSlots.selectedDate = dateFormatter.format(DateUtil.convertStringToDate(freeSlotsResponse[0]['FreeTimeSlots'])); selectedDate = DateUtil.getMonthDayYearDateFormatted(DateUtil.convertStringToDate(freeSlotsResponse[0]['FreeTimeSlots'])); selectedDateJSON = freeSlotsResponse[0]['FreeTimeSlots']; }); openTimeSlotsPickerForDate(DateUtil.convertStringToDate(selectedDateJSON), docFreeSlots); _calendarController.selectedDate = DateUtil.convertStringToDate(selectedDateJSON); return _eventsParsed; } // Widget _buildEventsMarker(DateTime date, List events) { // return Container( // // decoration: BoxDecoration( // // shape: BoxShape.circle, // // color: _calendarController.isSelected(date) // // ? Colors.green[400] // // : _calendarController.isToday(date) // // ? Colors.brown[300] // // : Colors.blue[400], // // ), // // decoration: containerColorRadiusBorderWidth( // _calendarController.isSelected(date) // ? CustomColors.green // : _calendarController.isToday(date) // ? CustomColors.green.withOpacity(0.5) // : Colors.white, // 200, // _calendarController.isSelected(date) ? CustomColors.green : Colors.black, // 2), // width: 40.0, // height: 40.0, // child: Center( // child: Text( // '${date.day}', // style: TextStyle().copyWith( // color: _calendarController.isSelected(date) ? Colors.white : Colors.black, // fontSize: 13.0, // ), // ), // ), // ); // } Widget getNormalButton(int index) { return RaisedButton( color: Colors.white, elevation: 0, textColor: new Color(0xFF60686b), onPressed: () { setState(() { selectedButtonIndex = index; CovidTimeSlots.selectedTime = dayEvents[index].isoTime; print(CovidTimeSlots.selectedTime); }); }, child: Text(dayEvents[index].isoTime, style: TextStyle(fontSize: 12.0, fontWeight: FontWeight.bold)), ); } Widget getSelectedButton(int index) { return RaisedButton( color: CustomColors.green, //Color of the border elevation: 0, textColor: Colors.white, onPressed: () { setState(() { selectedButtonIndex = index; CovidTimeSlots.selectedTime = dayEvents[index].isoTime; print(CovidTimeSlots.selectedTime); }); }, child: Text(dayEvents[index].isoTime, style: TextStyle(fontSize: 12.0, fontWeight: FontWeight.bold)), ); } bookCovidTestAppointment() { if (CovidTimeSlots.areSlotsAvailable) { var messageEn = "This Appointment is being booked for patient " + projectViewModel.authenticatedUserObject.user.firstName + " " + projectViewModel.authenticatedUserObject.user.lastName + ", Having file number " + projectViewModel.authenticatedUserObject.user.patientID.toString() + ". Please confirm!"; var messageAr = "يتم حجز هذا الموعد المراجع " + projectViewModel.authenticatedUserObject.user.firstName + " " + projectViewModel.authenticatedUserObject.user.lastName + ", وجود رقم الملف " + projectViewModel.authenticatedUserObject.user.patientID.toString() + ". يرجى تأكيد!"; ConfirmDialog dialog = new ConfirmDialog( context: context, confirmMessage: projectViewModel.isArabic ? messageAr : messageEn, okText: TranslationBase.of(context).confirm, cancelText: TranslationBase.of(context).cancel_nocaps, okFunction: () { GifLoaderDialogUtils.showMyDialog(context); DoctorList docObject = new DoctorList(); docObject.doctorID = widget.selectedDoctorID; docObject.clinicID = widget.selectedClinicID; docObject.projectID = widget.projectID; insertCovidQuestionnaire(context, docObject); }, cancelFunction: () => {}); dialog.showAlertDialog(context); } else { AppToast.showErrorToast(message: TranslationBase.of(context).selectSlot); } } insertCovidQuestionnaire(context, DoctorList docObject) async { DoctorsListService service = new DoctorsListService(); List qa = await sharedPref.getObject(COVID_QA_LIST); service.insertCovidQuestionnaire(qa, widget.projectID, widget.selectedProject.testTypeEnum, widget.selectedProject.testProcedureEnum).then((res) { insertAppointmentCovidTest(context, docObject); }).catchError((err) { print(err); }); } updateCovidQuestionnaire(context, String appoNo) async { DoctorsListService service = new DoctorsListService(); service.updateCovidQuestionnaire(appoNo, widget.projectID, widget.selectedProject.testTypeEnum, widget.selectedProject.testProcedureEnum).then((res) { }).catchError((err) { print(err); }); } insertAppointmentCovidTest(context, DoctorList docObject) { DoctorsListService service = new DoctorsListService(); AppoitmentAllHistoryResultList appo; service .insertAppointment(docObject.doctorID, docObject.clinicID, docObject.projectID, CovidTimeSlots.selectedTime, CovidTimeSlots.selectedDate, 0, context, widget.selectedProcedure.procedureID, widget.selectedProject.testTypeEnum, widget.selectedProject.testProcedureEnum) .then((res) { if (res['MessageStatus'] == 1) { AppToast.showSuccessToast(message: TranslationBase.of(context).bookedSuccess); getToDoCount(); getPatientShare(context, res['AppointmentNo'], docObject.clinicID, docObject.projectID, docObject); } else { GifLoaderDialogUtils.hideDialog(context); appo = new AppoitmentAllHistoryResultList(); appo.appointmentNo = res['SameClinicApptList'][0]['AppointmentNo']; appo.clinicID = res['SameClinicApptList'][0]['DoctorID']; appo.projectID = res['SameClinicApptList'][0]['ProjectID']; appo.endTime = res['SameClinicApptList'][0]['EndTime']; appo.startTime = res['SameClinicApptList'][0]['StartTime']; appo.doctorID = res['SameClinicApptList'][0]['DoctorID']; appo.isLiveCareAppointment = false; appo.originalClinicID = 0; appo.originalProjectID = 0; appo.appointmentDate = res['SameClinicApptList'][0]['AppointmentDate']; ConfirmDialog dialog = new ConfirmDialog( context: context, confirmMessage: res['ErrorEndUserMessage'], okText: TranslationBase.of(context).confirm, cancelText: TranslationBase.of(context).cancel_nocaps, okFunction: () => {cancelAppointment(docObject, appo, context)}, cancelFunction: () => {}); dialog.showAlertDialog(context); } }).catchError((err) { AppToast.showErrorToast(message: err); GifLoaderDialogUtils.hideDialog(context); print(err); }); } getToDoCount() { toDoProvider.setState(0, true, toDoProvider.notificationsCount); ClinicListService service = new ClinicListService(); service.getActiveAppointmentNo(context).then((res) { print(res['AppointmentActiveNumber']); if (res['MessageStatus'] == 1) { toDoProvider.setState(res['AppointmentActiveNumber'], true, toDoProvider.notificationsCount); } else {} }).catchError((err) { print(err); }); } cancelAppointment(DoctorList docObject, AppoitmentAllHistoryResultList appo, BuildContext context) { ConfirmDialog.closeAlertDialog(context); GifLoaderDialogUtils.showMyDialog(context); DoctorsListService service = new DoctorsListService(); service.cancelAppointment(appo, context).then((res) { if (res['MessageStatus'] == 1) { // Future.delayed(new Duration(milliseconds: 1500), () { insertAppointmentCovidTest(context, docObject); // }); } else { GifLoaderDialogUtils.hideDialog(context); AppToast.showErrorToast(message: res['ErrorEndUserMessage']); } }).catchError((err) { print(err); }); } getPatientShare(context, String appointmentNo, int clinicID, int projectID, DoctorList docObject) { DoctorsListService service = new DoctorsListService(); service.getPatientShare(appointmentNo, clinicID, projectID, context).then((res) { GifLoaderDialogUtils.hideDialog(context); print(res); widget.patientShareResponse = new PatientShareResponse.fromJson(res); updateCovidQuestionnaire(context, appointmentNo); navigateToPaymentAlert(); }).catchError((err) { GifLoaderDialogUtils.hideDialog(context); print(err); }); } navigateToPaymentAlert() { Navigator.push( context, FadePage( page: CovidPaymentAlert(patientShareResponse: widget.patientShareResponse), ), ); } getCovidFreeSlots(BuildContext context, int projectID) { CovidDriveThruService service = new CovidDriveThruService(); GifLoaderDialogUtils.showMyDialog(context); service.getCovidFreeSlots(context, projectID, widget.selectedProject.testTypeEnum, widget.selectedProject.testProcedureEnum).then((res) { GifLoaderDialogUtils.hideDialog(context); if (res['MessageStatus'] == 1) { if (res['COVID19_FreeTimeSlots'].length != 0) { freeSlotsResponse = res['COVID19_FreeTimeSlots']; _getJSONSlots().then((value) => { setState(() => {widget.selectedClinicID = freeSlotsResponse[0]['ClinicID'], widget.selectedDoctorID = freeSlotsResponse[0]['DoctorID'], _events.clear(), _events = value}) }); } else {} } else { GifLoaderDialogUtils.hideDialog(context); AppToast.showErrorToast(message: res['ErrorEndUserMessage']); } }).catchError((err) { GifLoaderDialogUtils.hideDialog(context); AppToast.showErrorToast(message: err.toString()); print(err); }); } } class MeetingDataSource extends CalendarDataSource { MeetingDataSource(List source) { appointments = source; } @override DateTime getStartTime(int index) { return _getMeetingData(index).from; } @override DateTime getEndTime(int index) { return _getMeetingData(index).to; } @override String getSubject(int index) { return _getMeetingData(index).eventName; } @override Color getColor(int index) { return _getMeetingData(index).background; } @override bool isAllDay(int index) { return _getMeetingData(index).isAllDay; } Meeting _getMeetingData(int index) { final dynamic meeting = appointments[index]; Meeting meetingData; if (meeting is Meeting) { meetingData = meeting; } return meetingData; } } class Meeting { Meeting(this.eventName, this.from, this.to, this.background, this.isAllDay); String eventName; DateTime from; DateTime to; Color background; bool isAllDay; }