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/pages/Covid-DriveThru/covid-payment-alert.dart'; import 'package:diplomaticquarterapp/services/appointment_services/GetDoctorsList.dart'; import 'package:diplomaticquarterapp/services/covid-drivethru/covid-drivethru.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/translations_delegate_base.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:flutter_svg/flutter_svg.dart'; import 'package:intl/intl.dart'; import 'package:smart_progress_bar/smart_progress_bar.dart'; import 'package:table_calendar/table_calendar.dart'; class CovidTimeSlots extends StatefulWidget { int projectID; static bool areSlotsAvailable = false; static DateTime selectedAppoDateTime; static String selectedDate; static String selectedTime; int selectedClinicID; int selectedDoctorID; PatientShareResponse patientShareResponse; CovidTimeSlots({@required this.projectID}); @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; @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, List events) { final DateFormat formatter = DateFormat('yyyy-MM-dd'); setState(() { this.selectedDate = DateUtil.getMonthDayYearDateFormatted(day); openTimeSlotsPickerForDate(day, docFreeSlots); CovidTimeSlots.selectedDate = formatter.format(day); print(CovidTimeSlots.selectedDate); }); } void _onVisibleDaysChanged( DateTime first, DateTime last, CalendarFormat format) { print('CALLBACK: _onVisibleDaysChanged'); } void _onCalendarCreated( DateTime first, DateTime last, CalendarFormat format) { print('CALLBACK: _onCalendarCreated'); } @override Widget build(BuildContext context) { return AppScaffold( appBarTitle: "COVID-19 TEST", isShowAppBar: true, body: SingleChildScrollView( child: Container( margin: EdgeInsets.fromLTRB(15.0, 15.0, 15.0, 0.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( height: 150.0, decoration: BoxDecoration( image: DecorationImage( image: AssetImage( "assets/images/new-design/covid-19-big-banner-bg.png"), fit: BoxFit.fill, ), color: Colors.white.withOpacity(0.3), borderRadius: BorderRadius.all(Radius.circular(10))), child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( margin: EdgeInsets.only(left: 15.0, right: 15.0, top: 30.0), child: SvgPicture.asset( 'assets/images/new-design/covid-19-car.svg', width: 90.0, height: 90.0), ), Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( margin: EdgeInsets.only( left: 20.0, right: 20.0, top: 40.0), child: Text("COVID-19 TEST", style: TextStyle( color: Colors.white, fontWeight: FontWeight.bold, fontSize: 24.0)), ), Container( margin: EdgeInsets.only( left: 20.0, right: 20.0, top: 10.0), child: Text("Drive-Thru", style: TextStyle( color: Colors.white, fontSize: 24.0)), ), ], ), ], ), ), Container( decoration: BoxDecoration( borderRadius: BorderRadius.circular(10.0), color: Colors.white), margin: EdgeInsets.fromLTRB(0.0, 20.0, 0.0, 5.0), padding: EdgeInsets.fromLTRB(20.0, 0.0, 20.0, 20.0), width: MediaQuery.of(context).size.width, height: MediaQuery.of(context).size.height * 0.65, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( margin: EdgeInsets.all(10.0), child: Text( "Kindly select one of the available appointments from below: ", style: TextStyle(color: Colors.black, fontSize: 16.0)), ), Container( margin: EdgeInsets.only(top: 10.0), alignment: Alignment.center, child: Text(selectedDate, style: TextStyle( fontSize: 18.0, fontWeight: FontWeight.bold)), ), Container( height: 50, margin: EdgeInsets.all(20.0), child: ListView.builder( controller: _scrollController, scrollDirection: Axis.horizontal, itemCount: dayEvents.length, itemBuilder: (context, index) { return Container( margin: EdgeInsets.only(right: 10.0), child: ButtonTheme( shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(5.0), side: BorderSide( color: Colors.blue[400], //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)), ); }, ), ), _buildTableCalendarWithBuilders(), ], ), ), SizedBox( height: 100.0, ), ], ), ), ), bottomSheet: Container( margin: EdgeInsets.all(10.0), child: Flex( direction: Axis.horizontal, children: [ Expanded( flex: 1, child: Container( margin: EdgeInsets.fromLTRB(10.0, 0.0, 5.0, 0.0), child: ButtonTheme( shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(10.0), ), minWidth: MediaQuery.of(context).size.width * 0.7, height: 45.0, child: RaisedButton( color: new Color(0xFF60686b), textColor: Colors.white, disabledTextColor: Colors.white, disabledColor: Colors.grey[500], onPressed: () { bookCovidTestAppointment(); }, child: Text("BOOK", style: TextStyle(fontSize: 18.0)), ), ), ), ), ], ), ), ); } Widget _buildTableCalendarWithBuilders() { return TableCalendar( locale: 'en_US', calendarController: _calendarController, events: _events, initialCalendarFormat: CalendarFormat.month, startDay: DateTime.now(), formatAnimation: FormatAnimation.slide, startingDayOfWeek: StartingDayOfWeek.sunday, weekendDays: [DateTime.friday, DateTime.saturday], availableGestures: AvailableGestures.horizontalSwipe, availableCalendarFormats: const { CalendarFormat.month: '', CalendarFormat.week: '', }, calendarStyle: CalendarStyle( outsideDaysVisible: false, weekendStyle: TextStyle().copyWith(color: Colors.blue[800]), holidayStyle: TextStyle().copyWith(color: Colors.blue[800]), ), daysOfWeekStyle: DaysOfWeekStyle( weekendStyle: TextStyle().copyWith(color: Colors.blue[600]), ), headerStyle: HeaderStyle( centerHeaderTitle: true, formatButtonVisible: false, ), builders: CalendarBuilders( selectedDayBuilder: (context, date, _) { return FadeTransition( opacity: Tween(begin: 0.0, end: 1.0).animate(_animationController), child: Container( margin: const EdgeInsets.all(4.0), padding: const EdgeInsets.only(top: 5.0, left: 6.0), color: Colors.transparent, width: 0, height: 0, child: Text( '${date.day}', style: TextStyle().copyWith(fontSize: 16.0), ), ), ); }, todayDayBuilder: (context, date, _) { return Container( decoration: BoxDecoration( shape: BoxShape.circle, color: _calendarController.isSelected(date) ? Colors.green[400] : _calendarController.isToday(date) ? Colors.brown[300] : Colors.blue[400], ), width: 40.0, height: 40.0, child: Center( child: Text( '${date.day}', style: TextStyle().copyWith( color: Colors.white, fontSize: 14.0, ), ), ), ); }, markersBuilder: (context, date, events, holidays) { final children = []; if (events.isNotEmpty) { children.add( Positioned( right: 4, bottom: 4, child: _buildEventsMarker(date, events), ), ); } return children; }, ), onDaySelected: (date, event, _) { _onDaySelected( date, event, ); _animationController.forward(from: 0.0); }, onVisibleDaysChanged: _onVisibleDaysChanged, onCalendarCreated: _onCalendarCreated, ); } 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; else CovidTimeSlots.areSlotsAvailable = false; selectedButtonIndex = 0; CovidTimeSlots.selectedTime = dayEvents[selectedButtonIndex].isoTime; }); } 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 .setFocusedDay(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], ), width: 40.0, height: 40.0, child: Center( child: Text( '${date.day}', style: TextStyle().copyWith( color: Colors.white, fontSize: 14.0, ), ), ), ); } Widget getNormalButton(int index) { return RaisedButton( color: Colors.white, textColor: new Color(0xFF60686b), onPressed: () { setState(() { selectedButtonIndex = index; CovidTimeSlots.selectedTime = dayEvents[index].isoTime; print(CovidTimeSlots.selectedTime); }); }, child: Text(dayEvents[index].isoTime, style: TextStyle(fontSize: 16.0, fontWeight: FontWeight.bold)), ); } Widget getSelectedButton(int index) { return RaisedButton( color: Colors.blue[400], textColor: Colors.white, onPressed: () { setState(() { selectedButtonIndex = index; CovidTimeSlots.selectedTime = dayEvents[index].isoTime; print(CovidTimeSlots.selectedTime); }); }, child: Text(dayEvents[index].isoTime, style: TextStyle(fontSize: 16.0, fontWeight: FontWeight.bold)), ); } bookCovidTestAppointment() { // Navigator.push(context, // MaterialPageRoute(builder: (context) => CovidPaymentAlert())); DoctorList docObject = new DoctorList(); docObject.doctorID = widget.selectedDoctorID; docObject.clinicID = widget.selectedClinicID; docObject.projectID = widget.projectID; insertAppointmentCovidTest(context, docObject); } insertAppointmentCovidTest(context, DoctorList docObject) { DoctorsListService service = new DoctorsListService(); AppoitmentAllHistoryResultList appo; service .insertAppointment( docObject.doctorID, docObject.clinicID, docObject.projectID, CovidTimeSlots.selectedTime, CovidTimeSlots.selectedDate, context) .then((res) { print(res); if (res['MessageStatus'] == 1) { AppToast.showSuccessToast(message: "Appointment Booked Successfully"); Future.delayed(new Duration(milliseconds: 1800), () { getPatientShare(context, res['AppointmentNo'], docObject.clinicID, docObject.projectID, docObject); }); } else { 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); print(err); }).showProgressBar( text: "Loading", backgroundColor: Colors.blue.withOpacity(0.6)); } cancelAppointment(DoctorList docObject, AppoitmentAllHistoryResultList appo, BuildContext context) { ConfirmDialog.closeAlertDialog(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 { AppToast.showErrorToast(message: res['ErrorEndUserMessage']); } }).catchError((err) { print(err); }).showProgressBar( text: "Loading", backgroundColor: Colors.blue.withOpacity(0.6)); } getPatientShare(context, String appointmentNo, int clinicID, int projectID, DoctorList docObject) { DoctorsListService service = new DoctorsListService(); service .getPatientShare(appointmentNo, clinicID, projectID, context) .then((res) { print(res); widget.patientShareResponse = new PatientShareResponse.fromJson(res); }) .catchError((err) { print(err); }) .showProgressBar( text: "Loading", backgroundColor: Colors.blue.withOpacity(0.6)) .then((value) { navigateToPaymentAlert(); }); } navigateToPaymentAlert() { Navigator.push( context, MaterialPageRoute( builder: (context) => CovidPaymentAlert( patientShareResponse: widget.patientShareResponse))); } getCovidFreeSlots(BuildContext context, int projectID) { CovidDriveThruService service = new CovidDriveThruService(); service.getCovidFreeSlots(context, projectID).then((res) { print(res['COVID19_FreeTimeSlots']); if (res['MessageStatus'] == 1) { if (res['COVID19_FreeTimeSlots'].length != 0) { freeSlotsResponse = res['COVID19_FreeTimeSlots']; print(res['COVID19_FreeTimeSlots'].length); _getJSONSlots().then((value) => { setState(() => { widget.selectedClinicID = freeSlotsResponse[0]['ClinicID'], widget.selectedDoctorID = freeSlotsResponse[0]['DoctorID'], _events.clear(), _events = value }) }); } else {} } else { AppToast.showErrorToast(message: res['ErrorEndUserMessage']); } }).catchError((err) { print(err); }).showProgressBar( text: "Loading", backgroundColor: Colors.blue.withOpacity(0.6)); } }