make register patient feature

merge-requests/865/head
mosazaid 4 years ago
parent 52e5b86f6c
commit 7b8312fe26

Binary file not shown.

After

Width:  |  Height:  |  Size: 969 B

@ -710,5 +710,7 @@ const Map<String, Map<String, String>> localizedValues = {
"ar":"نوع الطلب"},
"special": {"en": "Special", "ar": "خاص"},
"allClinic": {"en": "All Clinics", "ar": "جميع العيادات"} ,
"operationReports": {"en": "Operation Reports", "ar": "تقارير العملية"}
"operationReports": {"en": "Operation Reports", "ar": "تقارير العملية"},
"registerNewPatient": {"en": "Register\nNew Patient", "ar": "تسجيل\n مريض جديد"},
"registeraPatient": {"en": "Register a Patient", "ar": "تسجيل المريض"},
};

@ -0,0 +1,5 @@
import 'package:doctor_app_flutter/core/service/base/base_service.dart';
class PatientRegisterService extends BaseService{
}

@ -0,0 +1,8 @@
import 'package:doctor_app_flutter/core/service/patient/PatientRegisterService.dart';
import 'package:doctor_app_flutter/core/viewModel/base_view_model.dart';
import '../../locator.dart';
class PatientRegisterViewModel extends BaseViewModel {
PatientRegisterService _service = locator<PatientRegisterService>();
}

@ -23,6 +23,7 @@ import 'core/service/patient/DischargedPatientService.dart';
import 'core/service/patient/LiveCarePatientServices.dart';
import 'core/service/patient/MyReferralPatientService.dart';
import 'core/service/patient/PatientMuseService.dart';
import 'core/service/patient/PatientRegisterService.dart';
import 'core/service/patient/ReferralService.dart';
import 'core/service/patient/out_patient_service.dart';
import 'core/service/patient/patient-doctor-referral-service.dart';
@ -49,6 +50,7 @@ import 'core/viewModel/InsuranceViewModel.dart';
import 'core/viewModel/LiveCarePatientViewModel.dart';
import 'core/viewModel/PatientMedicalReportViewModel.dart';
import 'core/viewModel/PatientMuseViewModel.dart';
import 'core/viewModel/PatientRegisterViewModel.dart';
import 'core/viewModel/PatientSearchViewModel.dart';
import 'core/viewModel/SOAP_view_model.dart';
import 'core/viewModel/doctor_replay_view_model.dart';
@ -103,6 +105,7 @@ void setupLocator() {
locator.registerLazySingleton(() => VideoCallService());
locator.registerLazySingleton(() => AnalyticsService());
locator.registerLazySingleton(() => OperationReportService());
locator.registerLazySingleton(() => PatientRegisterService());
/// View Model
locator.registerFactory(() => DoctorReplayViewModel());
@ -132,4 +135,5 @@ void setupLocator() {
locator.registerFactory(() => PatientMedicalReportViewModel());
locator.registerFactory(() => ScanQrViewModel());
locator.registerFactory(() => OperationReportViewModel());
locator.registerFactory(() => PatientRegisterViewModel());
}

@ -6,6 +6,7 @@ import 'package:flutter/material.dart';
class HomePatientCard extends StatelessWidget {
final Color backgroundColor;
final IconData cardIcon;
final String cardIconImage;
final Color backgroundIconColor;
final String text;
final Color textColor;
@ -15,11 +16,12 @@ class HomePatientCard extends StatelessWidget {
HomePatientCard({
@required this.backgroundColor,
@required this.backgroundIconColor,
@required this.cardIcon,
this.cardIcon,
this.cardIconImage,
@required this.text,
@required this.textColor,
@required this.onTap,
this.iconSize = 30,
this.iconSize = 30,
});
@override
@ -38,24 +40,41 @@ class HomePatientCard extends StatelessWidget {
children: [
Container(
margin: EdgeInsets.only(top: 18, left: 10),
color:Colors.transparent,
child: Icon(
cardIcon,
size: iconSize * 2,
color: backgroundIconColor,
),
color: Colors.transparent,
child: cardIcon != null
? Icon(
cardIcon,
size: iconSize * 2,
color: backgroundIconColor,
)
: IconButton(
icon: Image.asset(
'assets/images/patient_register.png',
width: iconSize * 2,
height: iconSize * 2,
fit: BoxFit.fill,
),
iconSize: iconSize * 2,
color: backgroundIconColor,
onPressed: () => null,
),
),
Container(
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Icon(
cardIcon,
size: iconSize,
color: textColor,
),
cardIcon != null
? Icon(
cardIcon,
size: iconSize,
color: textColor,
)
: Image.asset(
cardIconImage,
height: iconSize,
width: iconSize,
),
SizedBox(
height: 4,
),

@ -16,6 +16,7 @@ import 'package:doctor_app_flutter/screens/patients/In_patient/in_patient_screen
import 'package:doctor_app_flutter/screens/patients/out_patient/out_patient_screen.dart';
import 'package:doctor_app_flutter/screens/patients/patient_search/patient_search_screen.dart';
import 'package:doctor_app_flutter/screens/patients/profile/referral/patient_referral_screen.dart';
import 'package:doctor_app_flutter/screens/patients/register_patient/RegisterPatientPage.dart';
import 'package:doctor_app_flutter/util/date-utils.dart';
import 'package:doctor_app_flutter/util/dr_app_toast_msg.dart';
import 'package:doctor_app_flutter/util/translations_delegate_base.dart';
@ -254,8 +255,8 @@ class _HomeScreenState extends State<HomeScreen> {
else
Container(
child: ErrorMessage(
error: model.error,
)),
error: model.error,
)),
FractionallySizedBox(
// widthFactor: 0.90,
child: Container(
@ -313,7 +314,6 @@ class _HomeScreenState extends State<HomeScreen> {
),
)
]),
]),
),
);
@ -396,6 +396,23 @@ class _HomeScreenState extends State<HomeScreen> {
));
changeColorIndex();
patientCards.add(HomePatientCard(
backgroundColor: backgroundColors[colorIndex],
backgroundIconColor: backgroundIconColors[colorIndex],
cardIconImage: 'assets/images/patient_register.png',
textColor: textColors[colorIndex],
text: TranslationBase.of(context).registerNewPatient,
onTap: () {
Navigator.push(
context,
FadePage(
page: RegisterPatientPage(),
),
);
},
));
changeColorIndex();
patientCards.add(HomePatientCard(
backgroundColor: backgroundColors[colorIndex],
backgroundIconColor: backgroundIconColors[colorIndex],

@ -16,8 +16,9 @@ class PageStepperWidget extends StatelessWidget {
final int stepsCount;
final int currentStepIndex;
final Size screenSize;
final List<String> stepsTitles;
PageStepperWidget({this.stepsCount, this.currentStepIndex, this.screenSize});
PageStepperWidget({this.stepsCount, this.currentStepIndex, this.screenSize, this.stepsTitles});
@override
Widget build(BuildContext context) {
@ -33,10 +34,10 @@ class PageStepperWidget extends StatelessWidget {
for (int i = 1; i <= stepsCount; i++)
if (i == currentStepIndex)
StepWidget(i, true, i == stepsCount, i < currentStepIndex,
dividerWidth)
dividerWidth, stepsTitles: stepsTitles,)
else
StepWidget(i, false, i == stepsCount, i < currentStepIndex,
dividerWidth)
dividerWidth, stepsTitles: stepsTitles,)
],
)
],
@ -52,9 +53,10 @@ class StepWidget extends StatelessWidget {
final bool isFinalStep;
final bool isStepFinish;
final double dividerWidth;
final List<String> stepsTitles;
StepWidget(this.index, this.isInProgress, this.isFinalStep, this.isStepFinish,
this.dividerWidth);
this.dividerWidth, {this.stepsTitles});
@override
Widget build(BuildContext context) {
@ -106,7 +108,7 @@ class StepWidget extends StatelessWidget {
height: 8,
),
AppText(
"${TranslationBase.of(context).step} $index",
stepsTitles == null ? "${TranslationBase.of(context).step} $index" : "${stepsTitles[index - 1]}",
fontWeight: FontWeight.bold,
color: status == StepStatus.Locked ? Color(0xFF969696) : Colors.black,
fontFamily: 'Poppins',

@ -0,0 +1,212 @@
import 'package:doctor_app_flutter/core/viewModel/PatientRegisterViewModel.dart';
import 'package:doctor_app_flutter/screens/base/base_view.dart';
import 'package:doctor_app_flutter/screens/patients/In_patient/InPatientHeader.dart';
import 'package:doctor_app_flutter/screens/patients/patient_search/patient_search_header.dart';
import 'package:doctor_app_flutter/screens/patients/profile/UCAF/page-stepper-widget.dart';
import 'package:doctor_app_flutter/util/translations_delegate_base.dart';
import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart';
import 'package:doctor_app_flutter/widgets/shared/buttons/app_buttons_widget.dart';
import 'package:flutter/material.dart';
import 'RegisterSearchPatientPage.dart';
class RegisterPatientPage extends StatefulWidget {
const RegisterPatientPage({Key key}) : super(key: key);
@override
_RegisterPatientPageState createState() => _RegisterPatientPageState();
}
class _RegisterPatientPageState extends State<RegisterPatientPage>
with TickerProviderStateMixin {
PageController _controller;
int _currentIndex = 0;
bool _isLoading = false;
changePageViewIndex(pageIndex, {isChangeState = true}) {
if (pageIndex != _currentIndex && isChangeState) changeLoadingState(true);
_controller.jumpToPage(pageIndex);
setState(() {
_currentIndex = pageIndex;
});
}
void changeLoadingState(bool isLoading) {
setState(() {
_isLoading = isLoading;
});
}
@override
void initState() {
_controller = new PageController();
super.initState();
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
final screenSize = MediaQuery.of(context).size;
return BaseView<PatientRegisterViewModel>(
builder: (_, model, w) => AppScaffold(
baseViewModel: model,
isShowAppBar: true,
isLoading: _isLoading,
appBar: PatientSearchHeader(
title: TranslationBase.of(context).registeraPatient,
),
body: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: Container(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(
height: 10,
),
PageStepperWidget(
stepsCount: 3,
currentStepIndex: _currentIndex + 1,
screenSize: screenSize,
stepsTitles: [
"Search",
"Activation",
"Confirmation",
],
),
SizedBox(
height: 10,
),
Expanded(
child: Container(
color: Theme.of(context).scaffoldBackgroundColor,
child: PageView(
physics: NeverScrollableScrollPhysics(),
controller: _controller,
onPageChanged: (index) {
setState(() {
_currentIndex = index;
});
},
scrollDirection: Axis.horizontal,
children: <Widget>[
RegisterSearchPatientPage(),
]),
),
),
],
),
)),
_isLoading
? Container(
height: 0,
)
: pagerButtons(model),
],
),
),
);
}
Widget pagerButtons(PatientRegisterViewModel model) {
switch (_currentIndex) {
case 2:
return Container(
margin: EdgeInsets.symmetric(vertical: 16, horizontal: 16),
child: Row(
children: [
Expanded(
child: Container(
child: AppButton(
title: TranslationBase.of(context).cancel,
hasBorder: true,
vPadding: 12,
hPadding: 8,
borderColor: Color(0xFFeaeaea),
color: Color(0xFFeaeaea),
fontColor: Colors.black,
fontSize: 2.2,
onPressed: () {
Navigator.of(context).pop();
},
),
),
),
SizedBox(
width: 8,
),
Expanded(
child: Container(
child: AppButton(
title: TranslationBase.of(context).noteConfirm,
hasBorder: true,
vPadding: 12,
hPadding: 8,
borderColor: Color(0xFF359846),
color: Color(0xFF359846),
fontColor: Colors.white,
fontSize: 2.0,
onPressed: () {},
),
),
),
],
),
);
default:
return Container(
color: Colors.white,
padding: EdgeInsets.symmetric(vertical: 16, horizontal: 16),
child: Row(
children: [
Expanded(
child: Container(
child: AppButton(
title: TranslationBase.of(context).cancel,
hasBorder: true,
vPadding: 12,
hPadding: 8,
borderColor: Color(0xFFeaeaea),
color: Color(0xFFeaeaea),
fontColor: Colors.black,
fontSize: 2.2,
onPressed: () {
Navigator.of(context).pop();
},
),
),
),
SizedBox(
width: 8,
),
Expanded(
child: Container(
child: AppButton(
title: TranslationBase.of(context).next,
hasBorder: true,
vPadding: 12,
hPadding: 8,
borderColor: Color(0xFFB8382B),
color: Color(0xFFB8382B),
fontColor: Colors.white,
fontSize: 2.0,
onPressed: () {
changePageViewIndex(_currentIndex + 1);
},
),
),
),
],
),
);
}
}
}

@ -0,0 +1,201 @@
import 'package:doctor_app_flutter/config/size_config.dart';
import 'package:doctor_app_flutter/core/enum/viewstate.dart';
import 'package:doctor_app_flutter/core/viewModel/PatientRegisterViewModel.dart';
import 'package:doctor_app_flutter/screens/base/base_view.dart';
import 'package:doctor_app_flutter/util/date-utils.dart';
import 'package:doctor_app_flutter/util/dr_app_toast_msg.dart';
import 'package:doctor_app_flutter/util/translations_delegate_base.dart';
import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart';
import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart';
import 'package:doctor_app_flutter/widgets/shared/dialogs/dailog-list-select.dart';
import 'package:doctor_app_flutter/widgets/shared/loader/gif_loader_dialog_utils.dart';
import 'package:doctor_app_flutter/widgets/shared/text_fields/app-textfield-custom.dart';
import 'package:flutter/material.dart';
class RegisterSearchPatientPage extends StatefulWidget {
const RegisterSearchPatientPage({Key key}) : super(key: key);
@override
_RegisterSearchPatientPageState createState() =>
_RegisterSearchPatientPageState();
}
class _RegisterSearchPatientPageState extends State<RegisterSearchPatientPage> {
String countryError;
dynamic _selectedCountry;
final _phoneController = TextEditingController();
String phoneError;
final _idController = TextEditingController();
String idError;
DateTime _birthDate;
String birthdateError;
@override
Widget build(BuildContext context) {
final screenSize = MediaQuery.of(context).size;
return BaseView<PatientRegisterViewModel>(
builder: (_, model, w) => AppScaffold(
baseViewModel: model,
isShowAppBar: false,
body: Column(
children: [
Expanded(
child: Container(
width: double.infinity,
margin: EdgeInsets.all(16.0),
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
AppText(
"Please enter mobile number or Identification number",
fontFamily: 'Poppins',
fontSize: SizeConfig.textMultiplier * 2.2,
fontWeight: FontWeight.w800,
),
SizedBox(
height: 10,
),
AppTextFieldCustom(
height: screenSize.height * 0.075,
hintText: "Country",
isTextFieldHasSuffix: true,
validationError: countryError,
dropDownText: _selectedCountry != null
? _selectedCountry['nameEn']
: null,
enabled: false,
/*onClick: model.dietTypesList != null && model.dietTypesList.length > 0
? () {
openListDialogField('nameEn', 'id', model.dietTypesList, (selectedValue) {
setState(() {
_selectedCountry = selectedValue;
});
});
}
: () async {
GifLoaderDialogUtils.showMyDialog(context);
await model
.getDietTypes(patient.patientId)
.then((_) => GifLoaderDialogUtils.hideDialog(context));
if (model.state == ViewState.Idle && model.dietTypesList.length > 0) {
openListDialogField('nameEn', 'id', model.dietTypesList, (selectedValue) {
setState(() {
_selectedCountry = selectedValue;
});
});
} else if (model.state == ViewState.ErrorLocal) {
DrAppToastMsg.showErrorToast(model.error);
} else {
DrAppToastMsg.showErrorToast("Empty List");
}
},*/
),
SizedBox(
height: 10,
),
AppTextFieldCustom(
height: screenSize.height * 0.075,
hintText: "Phone Number",
inputType: TextInputType.phone,
controller: _phoneController,
validationError: phoneError,
),
SizedBox(
height: 10,
),
AppTextFieldCustom(
height: screenSize.height * 0.075,
hintText: "ID Number",
inputType: TextInputType.phone,
controller: _idController,
validationError: idError,
),
SizedBox(
height: 12,
),
AppText(
"Calender",
fontSize: SizeConfig.textMultiplier * 1.8,
fontWeight: FontWeight.w800,
),
SizedBox(
height: 10,
),
AppTextFieldCustom(
height: screenSize.height * 0.075,
hintText: "Birthdate",
dropDownText: _birthDate != null
? "${AppDateUtils.convertStringToDateFormat(_birthDate.toString(), "yyyy-MM-dd")}"
: null,
enabled: false,
isTextFieldHasSuffix: true,
validationError: birthdateError,
suffixIcon: IconButton(
icon: Icon(
Icons.calendar_today,
color: Colors.black,
),
onPressed: null,
),
onClick: () {
if (_birthDate == null) {
_birthDate = DateTime.now();
}
_selectDate(context, _birthDate, (picked) {
setState(() {
_birthDate = picked;
});
});
},
),
],
),
),
),
),
],
),
),
);
}
Future _selectDate(BuildContext context, DateTime dateTime,
Function(DateTime picked) updateDate) async {
final DateTime picked = await showDatePicker(
context: context,
initialDate: dateTime,
firstDate: DateTime.now(),
lastDate: DateTime(2040),
initialEntryMode: DatePickerEntryMode.calendar,
);
if (picked != null && picked != dateTime) {
updateDate(picked);
}
}
void openListDialogField(String attributeName, String attributeValueId,
List<dynamic> list, Function(dynamic selectedValue) okFunction) {
ListSelectDialog dialog = ListSelectDialog(
list: list,
attributeName: attributeName,
attributeValueId: attributeValueId,
usingSearch: true,
okText: TranslationBase.of(context).ok,
okFunction: (selectedValue) {
okFunction(selectedValue);
},
);
showDialog(
barrierDismissible: false,
context: context,
builder: (BuildContext context) {
return dialog;
},
);
}
}

@ -1106,6 +1106,8 @@ class TranslationBase {
String get requestType => localizedValues['requestType'][locale.languageCode];
String get allClinic => localizedValues['allClinic'][locale.languageCode];
String get notReplied => localizedValues['notReplied'][locale.languageCode];
String get registerNewPatient => localizedValues['registerNewPatient'][locale.languageCode];
String get registeraPatient => localizedValues['registeraPatient'][locale.languageCode];
}

@ -146,6 +146,7 @@ class _AppTextFieldCustomState extends State<AppTextFieldCustom> {
? TextAlign.right
: TextAlign.left,
focusNode: _focusNode,
textAlignVertical: TextAlignVertical.center,
decoration: TextFieldsUtils
.textFieldSelectorDecoration(
widget.hintText, null, true),

Loading…
Cancel
Save