immediate livecare consultation implementation contd.
parent
093e645f60
commit
2f4d6f5553
@ -0,0 +1 @@
|
||||
{"nm":"Comp 1","ddd":0,"h":100,"w":100,"meta":{"g":"@lottiefiles/toolkit-js 0.33.2"},"layers":[{"ty":4,"nm":"Shape Layer 2","sr":1,"st":0,"op":300,"ip":0,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":0,"k":[5.277,-32.723,0],"ix":1},"s":{"a":0,"k":[4.91,4.91,100],"ix":6},"sk":{"a":0,"k":0},"p":{"a":0,"k":[50.2,50.18,0],"ix":2},"r":{"a":0,"k":0,"ix":10},"sa":{"a":0,"k":0},"o":{"a":0,"k":100,"ix":11}},"ef":[],"shapes":[{"ty":"gr","bm":0,"hd":false,"mn":"ADBE Vector Group","nm":"Ellipse 2","ix":1,"cix":2,"np":3,"it":[{"ty":"el","bm":0,"hd":false,"mn":"ADBE Vector Shape - Ellipse","nm":"Ellipse Path 1","d":1,"p":{"a":0,"k":[0,0],"ix":3},"s":{"a":0,"k":[102.555,102.555],"ix":2}},{"ty":"fl","bm":0,"hd":false,"mn":"ADBE Vector Graphic - Fill","nm":"Fill 1","c":{"a":0,"k":[0.0941,0.7608,0.451],"ix":4},"r":1,"o":{"a":0,"k":100,"ix":5}},{"ty":"tr","a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"sk":{"a":0,"k":0,"ix":4},"p":{"a":0,"k":[3.277,-34.527],"ix":2},"r":{"a":0,"k":0,"ix":6},"sa":{"a":0,"k":0,"ix":5},"o":{"a":0,"k":100,"ix":7}}]},{"ty":"gr","bm":0,"hd":false,"mn":"ADBE Vector Group","nm":"Ellipse 1","ix":2,"cix":2,"np":3,"it":[{"ty":"el","bm":0,"hd":false,"mn":"ADBE Vector Shape - Ellipse","nm":"Ellipse Path 1","d":1,"p":{"a":0,"k":[0,0],"ix":3},"s":{"a":0,"k":[102.555,102.555],"ix":2}},{"ty":"fl","bm":0,"hd":false,"mn":"ADBE Vector Graphic - Fill","nm":"Fill 1","c":{"a":0,"k":[0.0941,0.7608,0.451],"ix":4},"r":1,"o":{"a":0,"k":100,"ix":5}},{"ty":"tr","a":{"a":0,"k":[0,0],"ix":1},"s":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[100,100],"t":0},{"s":[295,295],"t":60}],"ix":3},"sk":{"a":0,"k":0,"ix":4},"p":{"a":0,"k":[3.277,-34.527],"ix":2},"r":{"a":0,"k":0,"ix":6},"sa":{"a":0,"k":0,"ix":5},"o":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[100],"t":0},{"s":[0],"t":60}],"ix":7}}]}],"ind":1}],"v":"5.5.7","fr":60,"op":61,"ip":0,"assets":[]}
|
||||
@ -0,0 +1,4 @@
|
||||
<svg width="19" height="19" viewBox="0 0 19 19" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<circle cx="9.5" cy="9.5" r="6.5" fill="#18C273"/>
|
||||
<circle cx="9.5" cy="9.5" r="8" stroke="#18C273" stroke-opacity="0.31" stroke-width="3"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 252 B |
@ -0,0 +1,97 @@
|
||||
class GetLiveCareClinicListResponseModel {
|
||||
int? iD;
|
||||
int? serviceID;
|
||||
String? serviceName;
|
||||
String? serviceNameN;
|
||||
int? clinicID;
|
||||
int? age;
|
||||
bool? isCheckAgeBelow;
|
||||
int? gender;
|
||||
bool? isActive;
|
||||
String? createdOn;
|
||||
String? createdBy;
|
||||
int? isOnline;
|
||||
bool? projectOutSA;
|
||||
List<ShiftTimings>? shiftTimings;
|
||||
|
||||
GetLiveCareClinicListResponseModel(
|
||||
{this.iD,
|
||||
this.serviceID,
|
||||
this.serviceName,
|
||||
this.serviceNameN,
|
||||
this.clinicID,
|
||||
this.age,
|
||||
this.isCheckAgeBelow,
|
||||
this.gender,
|
||||
this.isActive,
|
||||
this.createdOn,
|
||||
this.createdBy,
|
||||
this.isOnline,
|
||||
this.projectOutSA,
|
||||
this.shiftTimings});
|
||||
|
||||
GetLiveCareClinicListResponseModel.fromJson(Map<String, dynamic> json) {
|
||||
iD = json['ID'];
|
||||
serviceID = json['ServiceID'];
|
||||
serviceName = json['ServiceName'];
|
||||
serviceNameN = json['ServiceNameN'];
|
||||
clinicID = json['ClinicID'];
|
||||
age = json['Age'];
|
||||
isCheckAgeBelow = json['IsCheckAgeBelow'];
|
||||
gender = json['Gender'];
|
||||
isActive = json['IsActive'];
|
||||
createdOn = json['CreatedOn'];
|
||||
createdBy = json['CreatedBy'];
|
||||
isOnline = json['IsOnline'];
|
||||
projectOutSA = json['ProjectOutSA'];
|
||||
if (json['ShiftTimings'] != null) {
|
||||
shiftTimings = <ShiftTimings>[];
|
||||
json['ShiftTimings'].forEach((v) {
|
||||
shiftTimings!.add(new ShiftTimings.fromJson(v));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final Map<String, dynamic> data = Map<String, dynamic>();
|
||||
data['ID'] = this.iD;
|
||||
data['ServiceID'] = this.serviceID;
|
||||
data['ServiceName'] = this.serviceName;
|
||||
data['ServiceNameN'] = this.serviceNameN;
|
||||
data['ClinicID'] = this.clinicID;
|
||||
data['Age'] = this.age;
|
||||
data['IsCheckAgeBelow'] = this.isCheckAgeBelow;
|
||||
data['Gender'] = this.gender;
|
||||
data['IsActive'] = this.isActive;
|
||||
data['CreatedOn'] = this.createdOn;
|
||||
data['CreatedBy'] = this.createdBy;
|
||||
data['IsOnline'] = this.isOnline;
|
||||
data['ProjectOutSA'] = this.projectOutSA;
|
||||
if (this.shiftTimings != null) {
|
||||
data['ShiftTimings'] = this.shiftTimings!.map((v) => v.toJson()).toList();
|
||||
}
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
class ShiftTimings {
|
||||
String? endTime;
|
||||
int? shiftID;
|
||||
String? startTime;
|
||||
|
||||
ShiftTimings({this.endTime, this.shiftID, this.startTime});
|
||||
|
||||
ShiftTimings.fromJson(Map<String, dynamic> json) {
|
||||
endTime = json['EndTime'];
|
||||
shiftID = json['ShiftID'];
|
||||
startTime = json['StartTime'];
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final Map<String, dynamic> data = Map<String, dynamic>();
|
||||
data['EndTime'] = this.endTime;
|
||||
data['ShiftID'] = this.shiftID;
|
||||
data['StartTime'] = this.startTime;
|
||||
return data;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,158 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_staggered_animations/flutter_staggered_animations.dart';
|
||||
import 'package:hmg_patient_app_new/core/app_state.dart';
|
||||
import 'package:hmg_patient_app_new/core/dependencies.dart';
|
||||
import 'package:hmg_patient_app_new/core/utils/size_utils.dart';
|
||||
import 'package:hmg_patient_app_new/core/utils/utils.dart';
|
||||
import 'package:hmg_patient_app_new/extensions/string_extensions.dart';
|
||||
import 'package:hmg_patient_app_new/extensions/widget_extensions.dart';
|
||||
import 'package:hmg_patient_app_new/features/book_appointments/book_appointments_view_model.dart';
|
||||
import 'package:hmg_patient_app_new/features/book_appointments/models/resp_models/get_clinic_list_response_model.dart';
|
||||
import 'package:hmg_patient_app_new/features/book_appointments/models/resp_models/get_livecare_clinics_response_model.dart';
|
||||
import 'package:hmg_patient_app_new/features/book_appointments/models/resp_models/get_livecare_immediate_clinics_response_model.dart';
|
||||
import 'package:hmg_patient_app_new/presentation/book_appointment/livecare/widgets/select_livecare_call_type.dart';
|
||||
import 'package:hmg_patient_app_new/presentation/book_appointment/widgets/clinic_card.dart';
|
||||
import 'package:hmg_patient_app_new/presentation/book_appointment/widgets/livecare_clinic_card.dart';
|
||||
import 'package:hmg_patient_app_new/theme/colors.dart';
|
||||
import 'package:hmg_patient_app_new/widgets/appbar/collapsing_list_view.dart';
|
||||
import 'package:hmg_patient_app_new/widgets/common_bottom_sheet.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class SelectImmediateLiveCareClinicPage extends StatefulWidget {
|
||||
const SelectImmediateLiveCareClinicPage({super.key});
|
||||
|
||||
@override
|
||||
State<SelectImmediateLiveCareClinicPage> createState() => _SelectImmediateLiveCareClinicPageState();
|
||||
}
|
||||
|
||||
class _SelectImmediateLiveCareClinicPageState extends State<SelectImmediateLiveCareClinicPage> {
|
||||
TextEditingController searchEditingController = TextEditingController();
|
||||
FocusNode textFocusNode = FocusNode();
|
||||
late AppState appState;
|
||||
late BookAppointmentsViewModel bookAppointmentsViewModel;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
scheduleMicrotask(() {
|
||||
bookAppointmentsViewModel.getLiveCareImmediateClinicsList();
|
||||
});
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
textFocusNode.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
bookAppointmentsViewModel = Provider.of<BookAppointmentsViewModel>(context, listen: false);
|
||||
appState = getIt.get<AppState>();
|
||||
return Scaffold(
|
||||
backgroundColor: AppColors.bgScaffoldColor,
|
||||
body: CollapsingListView(
|
||||
title: "Select LiveCare Clinic".needTranslation,
|
||||
child: SingleChildScrollView(
|
||||
child: Padding(
|
||||
padding: EdgeInsets.all(24.h),
|
||||
child: Consumer<BookAppointmentsViewModel>(builder: (context, bookAppointmentsVM, child) {
|
||||
return Column(
|
||||
children: [
|
||||
// SizedBox(height: 16.h),
|
||||
// TextInputWidget(
|
||||
// labelText: LocaleKeys.search.tr(context: context),
|
||||
// hintText: LocaleKeys.clinicName.tr(context: context),
|
||||
// controller: searchEditingController,
|
||||
// isEnable: true,
|
||||
// prefix: null,
|
||||
// autoFocus: false,
|
||||
// isBorderAllowed: false,
|
||||
// keyboardType: TextInputType.text,
|
||||
// focusNode: textFocusNode,
|
||||
// suffix: searchEditingController.text.isNotEmpty
|
||||
// ? GestureDetector(
|
||||
// onTap: () {
|
||||
// searchEditingController.clear();
|
||||
// bookAppointmentsViewModel.filterClinics("");
|
||||
// textFocusNode.unfocus();
|
||||
// },
|
||||
// child: Utils.buildSvgWithAssets(icon: AppAssets.close_bottom_sheet_icon, width: 20.h, height: 20.h, fit: BoxFit.scaleDown),
|
||||
// )
|
||||
// : null,
|
||||
// onChange: (value) {
|
||||
// bookAppointmentsViewModel.filterClinics(value!);
|
||||
// },
|
||||
// padding: EdgeInsets.symmetric(
|
||||
// vertical: ResponsiveExtension(10).h,
|
||||
// horizontal: ResponsiveExtension(15).h,
|
||||
// ),
|
||||
// ),
|
||||
ListView.separated(
|
||||
padding: EdgeInsets.only(top: 16.h),
|
||||
shrinkWrap: true,
|
||||
physics: NeverScrollableScrollPhysics(),
|
||||
itemCount: bookAppointmentsVM.isImmediateLiveCareClinicsLoading ? 5 : bookAppointmentsVM.immediateLiveCareClinicsList.length,
|
||||
itemBuilder: (context, index) {
|
||||
return bookAppointmentsVM.isImmediateLiveCareClinicsLoading
|
||||
? ClinicCard(
|
||||
bookAppointmentsVM: bookAppointmentsVM,
|
||||
liveCareClinicsResponseModel: GetLiveCareClinicsResponseModel(),
|
||||
clinicsListResponseModel: GetClinicsListResponseModel(),
|
||||
isLoading: bookAppointmentsVM.isImmediateLiveCareClinicsLoading,
|
||||
)
|
||||
: AnimationConfiguration.staggeredList(
|
||||
position: index,
|
||||
duration: const Duration(milliseconds: 500),
|
||||
child: SlideAnimation(
|
||||
verticalOffset: 100.0,
|
||||
child: FadeInAnimation(
|
||||
child: AnimatedContainer(
|
||||
duration: Duration(milliseconds: 300),
|
||||
curve: Curves.easeInOut,
|
||||
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.h, hasShadow: true),
|
||||
child: LiveCareClinicCard(
|
||||
bookAppointmentsVM: bookAppointmentsVM,
|
||||
liveCareClinicListResponseModel: bookAppointmentsVM.immediateLiveCareClinicsList[index],
|
||||
isLoading: bookAppointmentsVM.isImmediateLiveCareClinicsLoading,
|
||||
).onPress(() {
|
||||
onImmediateLiveCareClinicSelected(bookAppointmentsVM.immediateLiveCareClinicsList[index]);
|
||||
}),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
separatorBuilder: (BuildContext cxt, int index) => SizedBox(height: 16.h),
|
||||
),
|
||||
],
|
||||
);
|
||||
}),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
onImmediateLiveCareClinicSelected(GetLiveCareClinicListResponseModel liveCareClinic) {
|
||||
//TODO: add implementation to show clinic schedule
|
||||
if (liveCareClinic.isOnline == 1) {
|
||||
showCommonBottomSheetWithoutHeight(context,
|
||||
child: SelectLiveCareCallType(bookAppointmentsViewModel: bookAppointmentsViewModel),
|
||||
callBackFunc: () {},
|
||||
title: "Select LiveCare call type".needTranslation,
|
||||
isCloseButtonVisible: true,
|
||||
isFullScreen: false);
|
||||
} else {
|
||||
showCommonBottomSheetWithoutHeight(context,
|
||||
child: Utils.getErrorWidget(
|
||||
loadingText: "The selected clinic is only available between ${liveCareClinic.shiftTimings!.first.startTime} & ${liveCareClinic.shiftTimings!.first.endTime} hours.".needTranslation),
|
||||
callBackFunc: () {},
|
||||
title: "",
|
||||
isCloseButtonVisible: true,
|
||||
isFullScreen: false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,65 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:hmg_patient_app_new/core/app_assets.dart';
|
||||
import 'package:hmg_patient_app_new/core/utils/size_utils.dart';
|
||||
import 'package:hmg_patient_app_new/extensions/string_extensions.dart';
|
||||
import 'package:hmg_patient_app_new/extensions/widget_extensions.dart';
|
||||
import 'package:hmg_patient_app_new/features/book_appointments/book_appointments_view_model.dart';
|
||||
import 'package:hmg_patient_app_new/presentation/medical_file/widgets/medical_file_card.dart';
|
||||
import 'package:hmg_patient_app_new/theme/colors.dart';
|
||||
|
||||
class SelectLiveCareCallType extends StatelessWidget {
|
||||
SelectLiveCareCallType({super.key, required this.bookAppointmentsViewModel});
|
||||
|
||||
BookAppointmentsViewModel bookAppointmentsViewModel;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
//TODO: Replace with actual icons
|
||||
return GridView(
|
||||
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
||||
crossAxisCount: 3,
|
||||
crossAxisSpacing: 16,
|
||||
mainAxisSpacing: 16,
|
||||
mainAxisExtent: 130,
|
||||
),
|
||||
physics: NeverScrollableScrollPhysics(),
|
||||
padding: EdgeInsets.zero,
|
||||
shrinkWrap: true,
|
||||
children: [
|
||||
MedicalFileCard(
|
||||
label: "Video Call".needTranslation,
|
||||
textColor: AppColors.blackColor,
|
||||
backgroundColor: AppColors.whiteColor,
|
||||
svgIcon: AppAssets.eye_result_icon,
|
||||
isLargeText: true,
|
||||
iconSize: 36.h,
|
||||
).onPress(() {
|
||||
Navigator.of(context).pop();
|
||||
bookAppointmentsViewModel.setLiveCareSelectedCallType(1);
|
||||
}),
|
||||
MedicalFileCard(
|
||||
label: "Audio Call".needTranslation,
|
||||
textColor: AppColors.blackColor,
|
||||
backgroundColor: AppColors.whiteColor,
|
||||
svgIcon: AppAssets.allergy_info_icon,
|
||||
isLargeText: true,
|
||||
iconSize: 36.h,
|
||||
).onPress(() {
|
||||
Navigator.of(context).pop();
|
||||
bookAppointmentsViewModel.setLiveCareSelectedCallType(2);
|
||||
}),
|
||||
MedicalFileCard(
|
||||
label: "Phone Call".needTranslation,
|
||||
textColor: AppColors.blackColor,
|
||||
backgroundColor: AppColors.whiteColor,
|
||||
svgIcon: AppAssets.vaccine_info_icon,
|
||||
isLargeText: true,
|
||||
iconSize: 36.h,
|
||||
).onPress(() {
|
||||
Navigator.of(context).pop();
|
||||
bookAppointmentsViewModel.setLiveCareSelectedCallType(3);
|
||||
}),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,66 @@
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:hmg_patient_app_new/core/app_assets.dart';
|
||||
import 'package:hmg_patient_app_new/core/app_state.dart';
|
||||
import 'package:hmg_patient_app_new/core/dependencies.dart';
|
||||
import 'package:hmg_patient_app_new/core/utils/size_utils.dart';
|
||||
import 'package:hmg_patient_app_new/core/utils/utils.dart';
|
||||
import 'package:hmg_patient_app_new/extensions/string_extensions.dart';
|
||||
import 'package:hmg_patient_app_new/extensions/widget_extensions.dart';
|
||||
import 'package:hmg_patient_app_new/features/book_appointments/book_appointments_view_model.dart';
|
||||
import 'package:hmg_patient_app_new/features/book_appointments/models/resp_models/get_livecare_immediate_clinics_response_model.dart';
|
||||
import 'package:hmg_patient_app_new/generated/locale_keys.g.dart';
|
||||
import 'package:hmg_patient_app_new/theme/colors.dart';
|
||||
|
||||
class LiveCareClinicCard extends StatelessWidget {
|
||||
LiveCareClinicCard({super.key, required this.liveCareClinicListResponseModel, required this.isLoading, required this.bookAppointmentsVM});
|
||||
|
||||
GetLiveCareClinicListResponseModel liveCareClinicListResponseModel;
|
||||
bool isLoading;
|
||||
BookAppointmentsViewModel bookAppointmentsVM;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
AppState appState = getIt.get<AppState>();
|
||||
return Container(
|
||||
padding: EdgeInsets.all(16.h),
|
||||
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
|
||||
color: AppColors.whiteColor,
|
||||
borderRadius: 24.h,
|
||||
hasShadow: false,
|
||||
),
|
||||
child: Column(
|
||||
children: [
|
||||
Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
|
||||
Utils.buildSvgWithAssets(icon: AppAssets.generic_clinic_icon, width: 24.h, height: 24.h, fit: BoxFit.contain).toShimmer2(isShow: isLoading),
|
||||
Column(
|
||||
children: [
|
||||
Utils.buildSvgWithAssets(
|
||||
icon: AppAssets.livecare_online_icon,
|
||||
width: 16.h,
|
||||
height: 16.h,
|
||||
fit: BoxFit.contain,
|
||||
iconColor: liveCareClinicListResponseModel.isOnline == 1 ? AppColors.successColor : AppColors.primaryRedColor)
|
||||
.toShimmer2(isShow: isLoading),
|
||||
SizedBox(height: 4.h),
|
||||
liveCareClinicListResponseModel.isOnline == 1
|
||||
? LocaleKeys.online.tr(context: context).toText10(isBold: true, color: AppColors.successColor).toShimmer2(isShow: isLoading)
|
||||
: "Offline".toText10(isBold: true, color: AppColors.primaryRedColor).toShimmer2(isShow: isLoading),
|
||||
],
|
||||
),
|
||||
]),
|
||||
SizedBox(height: 8.h),
|
||||
Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
|
||||
Expanded(
|
||||
child: (isLoading ? "Cardiology" : (appState.isArabic() ? liveCareClinicListResponseModel.serviceNameN : liveCareClinicListResponseModel.serviceName))!
|
||||
.toText16(isBold: true)
|
||||
.toShimmer2(isShow: isLoading)),
|
||||
Transform.flip(
|
||||
flipX: appState.isArabic() ? true : false,
|
||||
child: Utils.buildSvgWithAssets(icon: AppAssets.forward_arrow_icon, width: 15.h, height: 15.h, fit: BoxFit.contain, iconColor: AppColors.textColor).toShimmer2(isShow: isLoading)),
|
||||
]),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue