You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
PatientApp-KKUMC/lib/pages/BookAppointment/components/DocAvailableAppointments.dart

431 lines
14 KiB
Dart

import 'package:diplomaticquarterapp/config/shared_pref_kay.dart';
import 'package:diplomaticquarterapp/models/Appointments/DoctorListResponse.dart';
import 'package:diplomaticquarterapp/models/Appointments/FreeSlot.dart';
import 'package:diplomaticquarterapp/models/Appointments/timeSlot.dart';
import 'package:diplomaticquarterapp/services/appointment_services/GetDoctorsList.dart';
import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart';
import 'package:diplomaticquarterapp/uitl/app_toast.dart';
import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:table_calendar/table_calendar.dart';
import '../../../uitl/date_uitl.dart';
class DocAvailableAppointments extends StatefulWidget {
DoctorList doctor;
static bool areSlotsAvailable = false;
static bool areAppointmentsAvailable = false;
static DateTime selectedAppoDateTime;
static String selectedDate;
static String selectedTime;
bool isLiveCareAppointment;
DocAvailableAppointments(
{@required this.doctor, @required this.isLiveCareAppointment});
@override
_DocAvailableAppointmentsState createState() =>
_DocAvailableAppointmentsState();
}
class _DocAvailableAppointmentsState extends State<DocAvailableAppointments>
with TickerProviderStateMixin {
Map<DateTime, List> _events;
AnimationController _animationController;
CalendarController _calendarController;
AppSharedPreferences sharedPref = new AppSharedPreferences();
var selectedDate = "";
dynamic selectedDateJSON;
dynamic jsonFreeSlots;
List<TimeSlot> docFreeSlots = [];
List<TimeSlot> dayEvents = [];
int selectedButtonIndex = 0;
dynamic freeSlotsResponse;
ScrollController _scrollController;
var language;
@override
void initState() {
// TODO: implement initState
super.initState();
final _selectedDay = DateTime.now();
_scrollController = new ScrollController();
_events = {
_selectedDay: ['Event A0']
};
WidgetsBinding.instance.addPostFrameCallback((_) async {
getCurrentLanguage();
if (widget.isLiveCareAppointment)
getDoctorScheduledFreeSlots(context, widget.doctor);
else {
getDoctorFreeSlots(context, widget.doctor);
}
});
_calendarController = CalendarController();
_animationController = AnimationController(
vsync: this,
duration: const Duration(milliseconds: 50),
);
_animationController.forward();
}
@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.getWeekDayMonthDayYearDateFormatted(day, language);
openTimeSlotsPickerForDate(day, docFreeSlots);
DocAvailableAppointments.selectedDate = formatter.format(day);
print(DocAvailableAppointments.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 SingleChildScrollView(
child: Container(
decoration: BoxDecoration(
color: Colors.white, borderRadius: BorderRadius.circular(10.0)),
margin: EdgeInsets.all(20.0),
padding: EdgeInsets.only(bottom: 10.0, top: 10.0),
child: Column(
mainAxisSize: MainAxisSize.max,
children: <Widget>[
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: Color(0xff76cfb7), //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(),
],
),
),
);
}
Widget _buildTableCalendarWithBuilders() {
return TableCalendar(
locale: language == "en" ? 'en_US' : 'ar_SA',
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.black, fontSize: 14.0),
weekdayStyle: TextStyle().copyWith(color: Colors.black, fontSize: 14.0),
),
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: 5.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.transparent
: Color(0xff76cfb7),
),
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, _) {
final children = <Widget>[];
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<TimeSlot> 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)
DocAvailableAppointments.areSlotsAvailable = true;
else
DocAvailableAppointments.areSlotsAvailable = false;
selectedButtonIndex = 0;
DocAvailableAppointments.selectedTime =
dayEvents[selectedButtonIndex].isoTime;
// _scrollController.animateTo(0.0, duration: new Duration(seconds: 1), curve: Curves.ease);
});
}
Future<Map<DateTime, List>> _getJSONSlots() async {
Map<DateTime, List> _eventsParsed;
List<FreeSlot> 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(() {
DocAvailableAppointments.selectedDate = dateFormatter
.format(DateUtil.convertStringToDate(freeSlotsResponse[0]));
selectedDate = DateUtil.getWeekDayMonthDayYearDateFormatted(
DateUtil.convertStringToDate(freeSlotsResponse[0]), language);
selectedDateJSON = freeSlotsResponse[0];
});
openTimeSlotsPickerForDate(
DateUtil.convertStringToDate(selectedDateJSON), docFreeSlots);
_calendarController
.setFocusedDay(DateUtil.convertStringToDate(selectedDateJSON));
return _eventsParsed;
}
Widget getNormalButton(int index) {
return RaisedButton(
color: Colors.white,
textColor: new Color(0xFF60686b),
onPressed: () {
setState(() {
selectedButtonIndex = index;
DocAvailableAppointments.selectedTime = dayEvents[index].isoTime;
print(DocAvailableAppointments.selectedTime);
});
},
child: Text(dayEvents[index].isoTime,
style: TextStyle(fontSize: 16.0, fontWeight: FontWeight.bold)),
);
}
Widget getSelectedButton(int index) {
return RaisedButton(
color: Color(0xff76cfb7), //Color of the border
textColor: Colors.white,
onPressed: () {
setState(() {
selectedButtonIndex = index;
DocAvailableAppointments.selectedTime = dayEvents[index].isoTime;
print(DocAvailableAppointments.selectedTime);
});
},
child: Text(dayEvents[index].isoTime,
style: TextStyle(fontSize: 16.0, fontWeight: FontWeight.bold)),
);
}
getDoctorFreeSlots(context, DoctorList docObject) {
GifLoaderDialogUtils.showMyDialog(context);
DoctorsListService service = new DoctorsListService();
service
.getDoctorFreeSlots(docObject.doctorID, docObject.clinicID,
docObject.projectID, context)
.then((res) {
GifLoaderDialogUtils.hideDialog(context);
if (res['MessageStatus'] == 1) {
if (res['FreeTimeSlots'].length != 0) {
DocAvailableAppointments.areAppointmentsAvailable = true;
freeSlotsResponse = res['FreeTimeSlots'];
print("res['FreeTimeSlots']");
print(res['FreeTimeSlots'].length);
_getJSONSlots().then((value) => {
setState(() => {_events.clear(), _events = value})
});
} else {
DocAvailableAppointments.areAppointmentsAvailable = false;
}
} else {
AppToast.showErrorToast(message: res['ErrorEndUserMessage']);
}
}).catchError((err) {
GifLoaderDialogUtils.hideDialog(context);
AppToast.showErrorToast(message: err);
print(err);
});
}
getDoctorScheduledFreeSlots(context, DoctorList docObject) {
GifLoaderDialogUtils.showMyDialog(context);
DoctorsListService service = new DoctorsListService();
service
.getDoctorScheduledFreeSlots(docObject.doctorID, docObject.clinicID,
docObject.projectID, docObject.serviceID, context)
.then((res) {
GifLoaderDialogUtils.hideDialog(context);
if (res['MessageStatus'] == 1) {
if (res['PatientER_DoctorFreeSlots'].length != 0) {
DocAvailableAppointments.areAppointmentsAvailable = true;
freeSlotsResponse = res['PatientER_DoctorFreeSlots'];
print("res['PatientER_DoctorFreeSlots']");
print(res['PatientER_DoctorFreeSlots'].length);
_getJSONSlots().then((value) => {
setState(() => {_events.clear(), _events = value})
});
} else {
DocAvailableAppointments.areAppointmentsAvailable = false;
}
} else {
AppToast.showErrorToast(message: res['ErrorEndUserMessage']);
}
}).catchError((err) {
GifLoaderDialogUtils.hideDialog(context);
AppToast.showErrorToast(message: err);
print(err);
});
}
getCurrentLanguage() async {
var languageID =
await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar');
setState(() {
this.language = languageID;
});
}
Widget _buildEventsMarker(DateTime date, List events) {
return Container(
decoration: BoxDecoration(
shape: BoxShape.circle,
color: _calendarController.isSelected(date)
? Color(0xffB8382C)
: _calendarController.isToday(date)
? Colors.brown[300]
: Color(0xff76cfb7),
),
width: 40.0,
height: 40.0,
child: Center(
child: Text(
'${date.day}',
style: TextStyle().copyWith(
color: Colors.white,
fontSize: 14.0,
),
),
),
);
}
}