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.
HMG_Patient_App_New/lib/presentation/e_referral/new_referral.dart

433 lines
18 KiB
Dart

// dart
// File: lib/presentation/e_referral/new_referral_page.dart
import 'dart:io';
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_export.dart';
import 'package:hmg_patient_app_new/core/app_state.dart';
import 'package:hmg_patient_app_new/core/common_models/nationality_country_model.dart';
import 'package:hmg_patient_app_new/core/dependencies.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/authentication/authentication_view_model.dart';
import 'package:hmg_patient_app_new/features/hmg_services/models/create_e_referral_model.dart';
import 'package:hmg_patient_app_new/generated/locale_keys.g.dart';
import 'package:hmg_patient_app_new/theme/colors.dart';
import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart';
import 'package:hmg_patient_app_new/widgets/dropdown/dropdown_widget.dart';
import 'package:hmg_patient_app_new/widgets/image_picker.dart';
import 'package:hmg_patient_app_new/widgets/input_widget.dart';
import 'package:provider/provider.dart';
class NewReferralPage extends StatefulWidget {
final Function(VoidCallback) onNextStep;
const NewReferralPage({super.key, required this.onNextStep});
@override
State<NewReferralPage> createState() => NewReferralPageState();
}
class NewReferralPageState extends State<NewReferralPage> {
final PageController _pageController = PageController();
int pageIndex = 0;
int _tabIndex = 0;
bool isPatientInsured =false;
final TextEditingController _nameController = TextEditingController();
final TextEditingController _phoneController = TextEditingController();
String _country = 'Saudi Arabia';
String? _relationship;
List<EReferralAttachment> medicalReportImages = [];
List<EReferralAttachment> insuredPatientImages = [];
void nextPressed() {
if (pageIndex < 2) {
_pageController.nextPage(duration: const Duration(milliseconds: 300), curve: Curves.easeInOut);
} else {
// submit logic
}
}
@override
initState() {
super.initState();
widget.onNextStep((){
nextPressed();
});
}
Widget _progressStep({required String title, required bool active, bool showDivider = true}) {
final Color activeColor = active ? AppColors.primaryRedColor : Colors.grey.shade400;
return Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
CircleAvatar(
radius: 13,
backgroundColor: active ? activeColor : Colors.grey.shade300,
child: Icon(Icons.check, size: 14, color: Colors.white),
),
if (showDivider)
Padding(
padding: const EdgeInsets.symmetric(horizontal: 8.0),
child: Divider(thickness: 1),
),
],
),
const SizedBox(height: 6),
Text(title, style: const TextStyle(fontSize: 11, fontWeight: FontWeight.w600)),
const SizedBox(height: 6),
Container(
padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 4),
decoration: BoxDecoration(
color: active ? activeColor.withOpacity(0.15) : Colors.grey.shade100,
borderRadius: BorderRadius.circular(6),
),
child: Text(active ? 'Active' : 'Inactive',
style: TextStyle(fontSize: 9, color: active ? activeColor : Colors.grey)),
),
],
),
);
}
Widget _requesterForm() {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 24.0),
child: ListView(
physics: const BouncingScrollPhysics(),
children: [
const SizedBox(height: 12),
const Text('Referral requester information',
style: TextStyle(fontWeight: FontWeight.w700, fontSize: 16)).paddingSymmetrical(4.h, 0.h),
const SizedBox(height: 12),
TextInputWidget(
controller: _nameController,
padding: const EdgeInsets.symmetric(horizontal: 16.0),
hintText: 'Enter Referral Requester Name*', labelText: 'Requester Name',
).paddingSymmetrical(0.h, 4.h),
Selector<AuthenticationViewModel, ({List<NationalityCountries>? countriesList, NationalityCountries? selectedCountry, bool isArabic})>(
selector: (context, authViewModel) {
final appState = getIt.get<AppState>();
return (
countriesList: authViewModel.countriesList,
selectedCountry: authViewModel.pickedCountryByUAEUser,
isArabic: appState.isArabic(),
);
},
shouldRebuild: (previous, next) => previous.countriesList != next.countriesList || previous.selectedCountry != next.selectedCountry || previous.isArabic != next.isArabic,
builder: (context, data, child) {
final authVM = context.read<AuthenticationViewModel>();
return DropdownWidget(
labelText: LocaleKeys.country.tr(),
hintText:_country,
isEnable: true,
dropdownItems: (data.countriesList ?? []).map((e) => data.isArabic ? e.nameN ?? "" : e.name ?? "").toList(),
selectedValue: data.selectedCountry != null
? data.isArabic
? data.selectedCountry!.nameN ?? ""
: data.selectedCountry!.name ?? ""
: "",
onChange: authVM.onUAEUserCountrySelection,
hasSelectionCustomIcon: true,
labelColor: AppColors.textColor,
padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 16),
selectionCustomIcon: AppAssets.arrow_down,
leadingIcon: AppAssets.globe,
).withVerticalPadding(8);
},
).paddingSymmetrical(0.h, 4.h),
TextInputWidget(
labelText: LocaleKeys.mobileNumber.tr(),
hintText: LocaleKeys.mobileNumber.tr(),
controller: null,
isEnable: true,
prefix: null,
isAllowLeadingIcon: true,
labelColor: AppColors.textColor, padding: const EdgeInsets.symmetric(horizontal: 16.0),
isReadOnly: true,
leadingIcon: AppAssets.call).paddingSymmetrical(0.h, 4.h),
Selector<AuthenticationViewModel, ({List<NationalityCountries>? countriesList, NationalityCountries? selectedCountry, bool isArabic})>(
selector: (context, authViewModel) {
final appState = getIt.get<AppState>();
return (
countriesList: authViewModel.countriesList,
selectedCountry: authViewModel.pickedCountryByUAEUser,
isArabic: appState.isArabic(),
);
},
shouldRebuild: (previous, next) => previous.countriesList != next.countriesList || previous.selectedCountry != next.selectedCountry || previous.isArabic != next.isArabic,
builder: (context, data, child) {
final authVM = context.read<AuthenticationViewModel>();
return DropdownWidget(
labelText: "Relationship",
hintText: "Relationship*".needTranslation,
isEnable: true,
dropdownItems: (data.countriesList ?? []).map((e) => data.isArabic ? e.nameN ?? "" : e.name ?? "").toList(),
selectedValue: data.selectedCountry != null
? data.isArabic
? data.selectedCountry!.nameN ?? ""
: data.selectedCountry!.name ?? ""
: "",
onChange: authVM.onUAEUserCountrySelection,
hasSelectionCustomIcon: true,
labelColor: AppColors.textColor,
padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 16),
selectionCustomIcon: AppAssets.arrow_down,
leadingIcon: AppAssets.globe,
).withVerticalPadding(8);
},
).paddingSymmetrical(0.h, 4.h),
const SizedBox(height: 120),
],
),
);
}
Widget _patientInformation(){
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0),
child: ListView(
physics: const BouncingScrollPhysics(),
children: [
const SizedBox(height: 12),
'Patient information'.toText16(weight: FontWeight.bold).paddingSymmetrical(4.h, 0.h),
const SizedBox(height: 12),
TextInputWidget(
controller: _nameController,
padding: const EdgeInsets.symmetric(horizontal: 16.0),
hintText: 'Enter Identification Number*', labelText: 'Identification Number ',
).paddingSymmetrical(0.h, 4.h),
TextInputWidget(
controller: _nameController,
padding: const EdgeInsets.symmetric(horizontal: 16.0),
hintText: 'Patient Name*', labelText: 'Name',
).paddingSymmetrical(0.h, 4.h),
Selector<AuthenticationViewModel, ({List<NationalityCountries>? countriesList, NationalityCountries? selectedCountry, bool isArabic})>(
selector: (context, authViewModel) {
final appState = getIt.get<AppState>();
return (
countriesList: authViewModel.countriesList,
selectedCountry: authViewModel.pickedCountryByUAEUser,
isArabic: appState.isArabic(),
);
},
shouldRebuild: (previous, next) => previous.countriesList != next.countriesList || previous.selectedCountry != next.selectedCountry || previous.isArabic != next.isArabic,
builder: (context, data, child) {
final authVM = context.read<AuthenticationViewModel>();
return DropdownWidget(
labelText: LocaleKeys.country.tr(),
hintText:_country,
isEnable: true,
dropdownItems: (data.countriesList ?? []).map((e) => data.isArabic ? e.nameN ?? "" : e.name ?? "").toList(),
selectedValue: data.selectedCountry != null
? data.isArabic
? data.selectedCountry!.nameN ?? ""
: data.selectedCountry!.name ?? ""
: "",
onChange: authVM.onUAEUserCountrySelection,
hasSelectionCustomIcon: true,
labelColor: AppColors.textColor,
padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 16),
selectionCustomIcon: AppAssets.arrow_down,
leadingIcon: AppAssets.globe,
).withVerticalPadding(8);
},
).paddingSymmetrical(0.h, 4.h),
'Where the patient located'.needTranslation.toText16(weight: FontWeight.bold).paddingSymmetrical(4.h, 0.h),
Selector<AuthenticationViewModel, ({List<NationalityCountries>? countriesList, NationalityCountries? selectedCountry, bool isArabic})>(
selector: (context, authViewModel) {
final appState = getIt.get<AppState>();
return (
countriesList: authViewModel.countriesList,
selectedCountry: authViewModel.pickedCountryByUAEUser,
isArabic: appState.isArabic(),
);
},
shouldRebuild: (previous, next) => previous.countriesList != next.countriesList || previous.selectedCountry != next.selectedCountry || previous.isArabic != next.isArabic,
builder: (context, data, child) {
final authVM = context.read<AuthenticationViewModel>();
return DropdownWidget(
labelText: LocaleKeys.country.tr(),
hintText:_country,
isEnable: true,
dropdownItems: (data.countriesList ?? []).map((e) => data.isArabic ? e.nameN ?? "" : e.name ?? "").toList(),
selectedValue: data.selectedCountry != null
? data.isArabic
? data.selectedCountry!.nameN ?? ""
: data.selectedCountry!.name ?? ""
: "",
onChange: authVM.onUAEUserCountrySelection,
hasSelectionCustomIcon: true,
labelColor: AppColors.textColor,
padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 16),
selectionCustomIcon: AppAssets.arrow_down,
leadingIcon: AppAssets.globe,
).withVerticalPadding(8);
},
).paddingSymmetrical(0.h, 4.h),
]));
}
Widget _otherDetails() {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0),
child: ListView(
physics: const BouncingScrollPhysics(),
children: [
const SizedBox(height: 12),
'Other Details'.toText16(weight: FontWeight.bold).paddingSymmetrical(4.h, 0.h),
const SizedBox(height: 12),
InkWell(child: TextInputWidget(
controller: _nameController,
padding: const EdgeInsets.symmetric(horizontal: 16.0),
hintText: 'Medical Report', labelText: 'Select Attachment',
suffix: Icon(Icons.attachment),
isReadOnly: true,
),
onTap: (){
ImageOptions.showImageOptionsNew(
context,
true,
(String image, File file) {
setState(() {
EReferralAttachment eReferralAttachment = new EReferralAttachment(fileName: 'image ${medicalReportImages.length + 1}.png', base64String: image);
medicalReportImages.add(eReferralAttachment);
});
},
);
},
).paddingSymmetrical(0.h, 4.h),
Selector<AuthenticationViewModel, ({List<NationalityCountries>? countriesList, NationalityCountries? selectedCountry, bool isArabic})>(
selector: (context, authViewModel) {
final appState = getIt.get<AppState>();
return (
countriesList: authViewModel.countriesList,
selectedCountry: authViewModel.pickedCountryByUAEUser,
isArabic: appState.isArabic(),
);
},
shouldRebuild: (previous, next) => previous.countriesList != next.countriesList || previous.selectedCountry != next.selectedCountry || previous.isArabic != next.isArabic,
builder: (context, data, child) {
final authVM = context.read<AuthenticationViewModel>();
return DropdownWidget(
labelText: LocaleKeys.branch.tr(),
hintText:_country,
isEnable: true,
dropdownItems: (data.countriesList ?? []).map((e) => data.isArabic ? e.nameN ?? "" : e.name ?? "").toList(),
selectedValue: data.selectedCountry != null
? data.isArabic
? data.selectedCountry!.nameN ?? ""
: data.selectedCountry!.name ?? ""
: "",
onChange: authVM.onUAEUserCountrySelection,
hasSelectionCustomIcon: true,
labelColor: AppColors.textColor,
padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 16),
selectionCustomIcon: AppAssets.arrow_down,
leadingIcon: AppAssets.hospital,
).withVerticalPadding(8);
},
).paddingSymmetrical(0.h, 4.h),
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Row(
children: [
Checkbox(
value: isPatientInsured,
activeColor: AppColors.primaryRedColor,
onChanged: (bool? newValue) {
setState(() {
isPatientInsured = newValue!;
});
}),
Padding(
padding: const EdgeInsets.all(5.0),
child: Text(
"Patient is Insured".needTranslation,
style: TextStyle(fontSize: 14, fontWeight: FontWeight.w600),
),
),
],
),
],
).paddingSymmetrical(0.h, 4.h),
isPatientInsured? InkWell(child: TextInputWidget(
controller: _nameController,
padding: const EdgeInsets.symmetric(horizontal: 16.0),
hintText: 'Insurance Document', labelText: 'Select Attachment',
suffix: Icon(Icons.attachment),
isReadOnly: true,
)) : SizedBox(),
]));
}
@override
Widget build(BuildContext context) {
final bool step0Active = pageIndex == 0;
final bool step1Active = pageIndex == 1;
final bool step2Active = pageIndex == 2;
return SizedBox(
height: MediaQuery
.of(context)
.size
.height, // constrain height
child: Column(
children: [
const SizedBox(height: 8),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 24.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
_progressStep(title: 'Requester Info', active: step0Active),
_progressStep(title: 'Patient Information', active: step1Active),
_progressStep(
title: 'Other details', active: step2Active, showDivider: false),
],
),
),
Expanded(
child: PageView(
controller: _pageController,
physics: const NeverScrollableScrollPhysics(),
onPageChanged: (i) => setState(() => pageIndex = i),
children: [
_requesterForm(),
_patientInformation(),
// const Center(child: Text('Patient Info - step 2 (placeholder)')),
_otherDetails(),
],
),
),
],
),
);
}
}