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/CovidDriveThru/CovidTestProceduresResponse.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/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/buttons/defaultButton.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:flutter_svg/flutter_svg.dart ' ;
import ' package:intl/intl.dart ' ;
import ' package:provider/provider.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 ;
CovidTestProceduresResponse selectedProcedure ;
int selectedClinicID ;
int selectedDoctorID ;
var language ;
PatientShareResponse patientShareResponse ;
CovidTimeSlots ( { @ required this . projectID , @ required this . selectedProcedure } ) ;
@ override
_CovidTimeSlotsState createState ( ) = > _CovidTimeSlotsState ( ) ;
}
class _CovidTimeSlotsState extends State < CovidTimeSlots > 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 ;
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 , List events , 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 ) ;
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 ) {
projectViewModel = Provider . of ( context ) ;
return AppScaffold (
appBarTitle: TranslationBase . of ( context ) . covidTest ,
isShowAppBar: true ,
showNewAppBar: true ,
showNewAppBarTitle: true ,
body: SingleChildScrollView (
child: Container (
margin: EdgeInsets . fromLTRB ( 15.0 , 15.0 , 15.0 , 0.0 ) ,
child: Column (
crossAxisAlignment: CrossAxisAlignment . start ,
children: < Widget > [
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: < Widget > [
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: < Widget > [
Container (
margin: EdgeInsets . only ( left: 20.0 , right: 20.0 , top: 20.0 ) ,
child: Text ( TranslationBase . of ( context ) . covidTest , 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 ( TranslationBase . of ( context ) . driveThru , style: TextStyle ( color: Colors . white , fontSize: 24.0 ) ) ,
) ,
] ,
) ,
] ,
) ,
) ,
Container (
child: Column (
crossAxisAlignment: CrossAxisAlignment . start ,
mainAxisSize: MainAxisSize . max ,
children: < Widget > [
_buildTableCalendarWithBuilders ( projectViewModel ) ,
Padding (
padding: const EdgeInsets . only ( left: 16 , right: 16 , bottom: 16 ) ,
child: Text ( selectedDate , style: TextStyle ( fontSize: 16.0 , fontWeight: FontWeight . w600 , letterSpacing: - 0.64 ) ) ,
) ,
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 ) ? 16 : 5.0 , left: index = = 0 ? 16 : 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.18 ,
child: index = = selectedButtonIndex ? getSelectedButton ( index ) : getNormalButton ( index ) ) ,
) ;
} ,
) ,
) ,
] ,
) ,
) ,
SizedBox (
height: 10.0 ,
) ,
if ( CovidTimeSlots . areSlotsAvailable )
Container (
color: Colors . grey [ 100 ] ,
margin: EdgeInsets . all ( 10.0 ) ,
child: DefaultButton (
TranslationBase . of ( context ) . bookNow ,
( ) {
bookCovidTestAppointment ( ) ;
} ,
) ,
) ,
] ,
) ,
) ,
) ,
) ;
}
Widget _buildTableCalendarWithBuilders ( ProjectViewModel projectViewModel ) {
return Card (
shape: cardRadius ( 12 ) ,
margin: EdgeInsets . all ( 16 ) ,
clipBehavior: Clip . antiAlias ,
child: Padding (
padding: const EdgeInsets . only ( bottom: 12 ) ,
child: TableCalendar (
locale: projectViewModel . isArabic ? ' ar_SA ' : ' 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 . black , fontSize: 11.0 , fontWeight: FontWeight . w600 ) ,
weekdayStyle: TextStyle ( ) . copyWith ( color: Colors . black , fontSize: 11.0 , fontWeight: FontWeight . w600 ) ,
) ,
headerStyle: HeaderStyle ( centerHeaderTitle: true , formatButtonVisible: false , titleTextStyle: TextStyle ( fontSize: 16 , letterSpacing: - 0.64 , fontWeight: FontWeight . w600 ) ) ,
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: 14.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 , holidays ) {
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 , projectViewModel ) ;
_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 )
CovidTimeSlots . areSlotsAvailable = true ;
else
CovidTimeSlots . areSlotsAvailable = false ;
selectedButtonIndex = 0 ;
CovidTimeSlots . selectedTime = dayEvents [ selectedButtonIndex ] . isoTime ;
} ) ;
}
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 ] [ ' 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 . getWeekDayMonthDayYearDateFormatted ( DateUtil . convertStringToDate ( freeSlotsResponse [ 0 ] [ ' FreeTimeSlots ' ] ) , projectViewModel . isArabic ? " ar " : " en " ) ;
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: 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: 14.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 ;
} ) ;
} ,
child: Text ( dayEvents [ index ] . isoTime , style: TextStyle ( fontSize: 12.0 ) ) ,
) ;
}
Widget getSelectedButton ( int index ) {
return RaisedButton (
color: CustomColors . green ,
//Color of the border
textColor: Colors . white ,
elevation: 0 ,
onPressed: ( ) {
setState ( ( ) {
selectedButtonIndex = index ;
CovidTimeSlots . selectedTime = dayEvents [ index ] . isoTime ;
} ) ;
} ,
child: Text ( dayEvents [ index ] . isoTime , style: TextStyle ( fontSize: 12.0 ) ) ,
) ;
}
bookCovidTestAppointment ( ) {
var messageEn = " This Appointment is being booked for patient " +
projectViewModel . user . firstName +
" " +
projectViewModel . user . lastName +
" , Having file number " +
projectViewModel . user . patientID . toString ( ) +
" . Please confirm! " ;
var messageAr =
" يتم حجز هذا الموعد المراجع " + projectViewModel . user . firstName + " " + projectViewModel . user . lastName + " , وجود رقم الملف " + projectViewModel . 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 ;
insertAppointmentCovidTest ( context , docObject ) ;
} ,
cancelFunction: ( ) = > { } ) ;
dialog . showAlertDialog ( context ) ;
}
insertAppointmentCovidTest ( context , DoctorList docObject ) {
DoctorsListService service = new DoctorsListService ( ) ;
AppoitmentAllHistoryResultList appo ;
service
. insertAppointment ( docObject . doctorID , docObject . clinicID , docObject . projectID , CovidTimeSlots . selectedTime , CovidTimeSlots . selectedDate , context , widget . selectedProcedure . procedureID )
. then ( ( res ) {
if ( res [ ' MessageStatus ' ] = = 1 ) {
AppToast . showSuccessToast ( message: " Appointment Booked Successfully " ) ;
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 ) ;
} ) ;
}
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 ) {
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 ) ;
navigateToPaymentAlert ( ) ;
} ) . catchError ( ( err ) {
GifLoaderDialogUtils . hideDialog ( context ) ;
print ( err ) ;
} ) ;
}
navigateToPaymentAlert ( ) {
Navigator . push (
context ,
FadePage (
page: CovidPaymentAlert ( patientShareResponse: widget . patientShareResponse ) ,
) ,
) ;
}
getCovidFreeSlots ( BuildContext context , int projectID ) {
CovidTimeSlots . areSlotsAvailable = false ;
CovidDriveThruService service = new CovidDriveThruService ( ) ;
GifLoaderDialogUtils . showMyDialog ( context ) ;
service . getCovidFreeSlots ( context , projectID ) . then ( ( res ) {
GifLoaderDialogUtils . hideDialog ( context ) ;
if ( res [ ' MessageStatus ' ] = = 1 ) {
if ( res [ ' COVID19_FreeTimeSlots ' ] . length ! = 0 ) {
CovidTimeSlots . areSlotsAvailable = true ;
freeSlotsResponse = res [ ' COVID19_FreeTimeSlots ' ] ;
_getJSONSlots ( ) . then ( ( value ) = > {
setState ( ( ) = > { widget . selectedClinicID = freeSlotsResponse [ 0 ] [ ' ClinicID ' ] , widget . selectedDoctorID = freeSlotsResponse [ 0 ] [ ' DoctorID ' ] , _events . clear ( ) , _events = value } )
} ) ;
} else {
CovidTimeSlots . areSlotsAvailable = false ;
}
} else {
GifLoaderDialogUtils . hideDialog ( context ) ;
AppToast . showErrorToast ( message: res [ ' ErrorEndUserMessage ' ] ) ;
}
} ) . catchError ( ( err ) {
print ( err ) ;
} ) ;
}
}