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/OBGyneProcedureListResponse.dart'; import 'package:diplomaticquarterapp/models/Appointments/timeSlot.dart'; import 'package:diplomaticquarterapp/models/Appointments/toDoCountProviderModel.dart'; import 'package:diplomaticquarterapp/pages/landing/landing_page.dart'; import 'package:diplomaticquarterapp/services/appointment_services/GetDoctorsList.dart'; import 'package:diplomaticquarterapp/services/clinic_services/get_clinic_service.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:flutter/material.dart'; import 'package:intl/intl.dart'; import 'package:provider/provider.dart'; import 'package:syncfusion_flutter_calendar/calendar.dart'; class ObGyneTimeSlots extends StatefulWidget { int projectID; static bool areSlotsAvailable = false; static DateTime selectedAppoDateTime; static String selectedDate; static String selectedTime; int selectedClinicID; int selectedDoctorID; OBGyneProcedureListResponse obGyneProcedureListResponse; var language; ObGyneTimeSlots({@required this.projectID, this.selectedClinicID, this.selectedDoctorID, this.obGyneProcedureListResponse}); @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(); _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); ObGyneTimeSlots.selectedDate = formatter.format(day); _calendarController.selectedDate = day; print(ObGyneTimeSlots.selectedDate); }); } @override Widget build(BuildContext context) { projectViewModel = Provider.of(context); toDoProvider = Provider.of(context); return AppScaffold( appBarTitle: TranslationBase.of(context).bookAppo, 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), ObGyneTimeSlots.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) { ObGyneTimeSlots.areSlotsAvailable = true; selectedButtonIndex = 0; ObGyneTimeSlots.selectedTime = dayEvents[selectedButtonIndex].isoTime; } else ObGyneTimeSlots.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]); 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(() { ObGyneTimeSlots.selectedDate = dateFormatter.format(DateUtil.convertStringToDate(freeSlotsResponse[0])); selectedDate = DateUtil.getMonthDayYearDateFormatted(DateUtil.convertStringToDate(freeSlotsResponse[0])); selectedDateJSON = freeSlotsResponse[0]; }); openTimeSlotsPickerForDate(DateUtil.convertStringToDate(selectedDateJSON), docFreeSlots); _calendarController.selectedDate = DateUtil.convertStringToDate(selectedDateJSON); return _eventsParsed; } Widget getNormalButton(int index) { return RaisedButton( color: Colors.white, elevation: 0, textColor: new Color(0xFF60686b), onPressed: () { setState(() { selectedButtonIndex = index; ObGyneTimeSlots.selectedTime = dayEvents[index].isoTime; print(ObGyneTimeSlots.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; ObGyneTimeSlots.selectedTime = dayEvents[index].isoTime; print(ObGyneTimeSlots.selectedTime); }); }, child: Text(dayEvents[index].isoTime, style: TextStyle(fontSize: 12.0, fontWeight: FontWeight.bold)), ); } bookCovidTestAppointment() { if (ObGyneTimeSlots.areSlotsAvailable) { GifLoaderDialogUtils.showMyDialog(context); DoctorList docObject = new DoctorList(); docObject.doctorID = widget.selectedDoctorID; docObject.clinicID = widget.selectedClinicID; docObject.projectID = widget.projectID; insertAppointmentCovidTest(context, docObject); } else { AppToast.showErrorToast(message: TranslationBase.of(context).selectSlot); } } // 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, ObGyneTimeSlots.selectedTime, ObGyneTimeSlots.selectedDate, 0, context, widget.obGyneProcedureListResponse.procedureId) .then((res) { if (res['MessageStatus'] == 1) { AppToast.showSuccessToast(message: TranslationBase.of(context).bookedSuccess); updateObGyneAppointment(res['AppointmentNo']); 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); }); } updateObGyneAppointment(String appoNo) { DoctorsListService service = new DoctorsListService(); service .updateObGyneAppointment(widget.obGyneProcedureListResponse.episodeID, int.parse(appoNo), widget.obGyneProcedureListResponse.orderNo, widget.obGyneProcedureListResponse.procedureId, widget.obGyneProcedureListResponse.lineItemNo, widget.obGyneProcedureListResponse.uniqueRowID) .then((res) {}) .catchError((err) { print(err); }); } getToDoCount() { toDoProvider.setState(0, true, toDoProvider.notificationsCount); ClinicListService service = new ClinicListService(); service.getActiveAppointmentNo(context).then((res) { GifLoaderDialogUtils.hideDialog(context); print(res['AppointmentActiveNumber']); if (res['MessageStatus'] == 1) { toDoProvider.setState(res['AppointmentActiveNumber'], true, toDoProvider.notificationsCount); } else {} Navigator.pushAndRemoveUntil( context, MaterialPageRoute(builder: (context) => LandingPage()), (Route route) => false, ); }).catchError((err) { GifLoaderDialogUtils.hideDialog(context); 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) { DoctorsListService service = new DoctorsListService(); GifLoaderDialogUtils.showMyDialog(context); service.getDoctorFreeSlots(widget.selectedDoctorID, widget.selectedClinicID, widget.projectID, context).then((res) { GifLoaderDialogUtils.hideDialog(context); if (res['MessageStatus'] == 1) { if (res['FreeTimeSlots'].length != 0) { print(res['FreeTimeSlots']); freeSlotsResponse = res['FreeTimeSlots']; _getJSONSlots().then((value) => { setState(() => { _events.clear(), _events = value, // if (widget.doctorSchedule != null) // {_onDaySelected(DateUtil.convertStringToDate(widget.doctorSchedule['Date'])), _calendarController.selectedDate = DateUtil.convertStringToDate(widget.doctorSchedule['Date'])} }) }); } 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; }