From 0a653a61f264e7e4a4cba79b9507a0608eeb08a9 Mon Sep 17 00:00:00 2001 From: Sultan khan Date: Thu, 18 Sep 2025 16:27:22 +0300 Subject: [PATCH] family file bottomsheet added --- lib/core/api_consts.dart | 2 +- .../medical_file/medical_file_repo.dart | 2 +- .../medical_file/medical_file_view_model.dart | 7 +- lib/widgets/my_family/my_Family.dart | 171 +++++++++++++----- lib/widgets/my_family/my_family_sheet.dart | 3 + 5 files changed, 141 insertions(+), 44 deletions(-) diff --git a/lib/core/api_consts.dart b/lib/core/api_consts.dart index 51cdb54..efdde41 100644 --- a/lib/core/api_consts.dart +++ b/lib/core/api_consts.dart @@ -727,7 +727,7 @@ const FAMILY_FILES= 'Services/Authentication.svc/REST/GetAllSharedRecordsByStatu class ApiConsts { static const maxSmallScreen = 660; - static AppEnvironmentTypeEnum appEnvironmentType = AppEnvironmentTypeEnum.uat; + static AppEnvironmentTypeEnum appEnvironmentType = AppEnvironmentTypeEnum.preProd; // static String baseUrl = 'https://uat.hmgwebservices.com/'; // HIS API URL UAT diff --git a/lib/features/medical_file/medical_file_repo.dart b/lib/features/medical_file/medical_file_repo.dart index 546c18b..69c45f3 100644 --- a/lib/features/medical_file/medical_file_repo.dart +++ b/lib/features/medical_file/medical_file_repo.dart @@ -281,7 +281,7 @@ class MedicalFileRepoImp implements MedicalFileRepo { Failure? failure; await apiClient.post( FAMILY_FILES, - body: {}, + body: {"Status":3}, onFailure: (error, statusCode, {messageStatus, failureType}) { failure = failureType; }, diff --git a/lib/features/medical_file/medical_file_view_model.dart b/lib/features/medical_file/medical_file_view_model.dart index 045f40e..5ffb52e 100644 --- a/lib/features/medical_file/medical_file_view_model.dart +++ b/lib/features/medical_file/medical_file_view_model.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.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/features/authentication/models/resp_models/authenticated_user_resp_model.dart'; import 'package:hmg_patient_app_new/features/medical_file/medical_file_repo.dart'; @@ -35,7 +36,7 @@ class MedicalFileViewModel extends ChangeNotifier { int selectedMedicalReportsTabIndex = 0; static final DialogService _dialogService = getIt.get(); - + AppState _appState = getIt(); MedicalFileViewModel({required this.medicalFileRepo, required this.errorHandlerService}); initMedicalFileProvider() { @@ -239,7 +240,11 @@ class MedicalFileViewModel extends ChangeNotifier { if (apiResponse.messageStatus == 2) { _dialogService.showErrorBottomSheet(message: apiResponse.errorMessage!, onOkPressed: () {}); } else if (apiResponse.messageStatus == 1) { + patientFamilyFiles = apiResponse.data!; + patientFamilyFiles.insert(0, + FamilyFileResponseModelLists(patientId: _appState.getAuthenticatedUser()!.patientId, patientName: '${_appState.getAuthenticatedUser()!.firstName!} ${_appState.getAuthenticatedUser()!.lastName!}', isActive: true, gender:_appState.getAuthenticatedUser()!.gender!, responseId: _appState.getAuthenticatedUser()!.patientId ), + ); notifyListeners(); if (onSuccess != null) { onSuccess(apiResponse); diff --git a/lib/widgets/my_family/my_Family.dart b/lib/widgets/my_family/my_Family.dart index f5dc1c0..2bcdf1a 100644 --- a/lib/widgets/my_family/my_Family.dart +++ b/lib/widgets/my_family/my_Family.dart @@ -1,47 +1,136 @@ import 'package:flutter/material.dart'; -import 'package:flutter_svg/flutter_svg.dart'; -import 'package:hmg_patient_app_new/core/app_assets.dart'; -import 'package:hmg_patient_app_new/features/medical_file/models/family_file_response_model.dart'; + import 'package:flutter_svg/flutter_svg.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/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/medical_file/models/family_file_response_model.dart'; + import 'package:hmg_patient_app_new/theme/colors.dart'; + import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart'; -class ProfileSelector extends StatelessWidget { - final List profiles; - final Function(FamilyFileResponseModelLists ) onSelect; + class ProfileSelector extends StatelessWidget { + final List profiles; + final Function(FamilyFileResponseModelLists) onSelect; - const ProfileSelector({ - Key? key, - required this.profiles, - required this.onSelect, - }) : super(key: key); - @override - Widget build(BuildContext context) { - return Column( - mainAxisSize: MainAxisSize.min, - children: profiles.map((profile) { - return ListTile( - leading: CircleAvatar( - radius: 22, - backgroundImage: profile.genderImage != null && - profile.genderImage.toString().isNotEmpty - ? NetworkImage(profile.genderImage!) - : AssetImage( - profile.gender == 1 - ? AppAssets.male_img - : AppAssets.femaleImg) - as ImageProvider, - ), - title: Text( - profile.patientName ?? "Unknown", - style: const TextStyle(fontWeight: FontWeight.w600), - ), - subtitle: Text( - profile.relationship ?? "Self", - style: const TextStyle(color: Colors.grey), + const ProfileSelector({ + Key? key, + required this.profiles, + required this.onSelect, + }) : super(key: key); + + + @override + Widget build(BuildContext context) { + final double screenHeight = MediaQuery.of(context).size.height; + int? activeProfileId = Utils.appState.getAuthenticatedUser()?.patientId; + return SizedBox( + height: screenHeight * 0.6, + child: SingleChildScrollView( + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + const Text( + "Please select a profile", + style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold), + ), + const SizedBox(height: 6), + const Text( + "Switch from the below list of medical file", + style: TextStyle(fontSize: 14, color: Colors.grey), + textAlign: TextAlign.center, + ), + const SizedBox(height: 20), + + // ✅ GridView inside scroll + GridView.builder( + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + itemCount: profiles.length, + gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 2, + crossAxisSpacing: 10, + mainAxisSpacing: 10, + childAspectRatio: 0.75, + ), + itemBuilder: (context, index) { + final profile = profiles[index]; + final isActive = + (profile.responseId == activeProfileId); + return Container( + padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 8), + decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + color: isActive ? Colors.grey.shade100 : AppColors.whiteColor, // Lighter background for active + borderRadius: 24, + ), + child: Opacity( + opacity: isActive ? 0.5 : 1.0, // Fade all content if active + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + const SizedBox(height: 5), + Container( + height: 80, + width: 78, + decoration: BoxDecoration( + shape: BoxShape.circle, + image: DecorationImage( + image: AssetImage( + profile.gender == 1 + ? AppAssets.male_img + : AppAssets.femaleImg, + ), + fit: BoxFit.cover, + ), + ), + ), + const SizedBox(height: 8), + (profile.patientName ?? "Unknown").toText14( + isBold: true, + maxlines: 1, + isCenter: true, + ), + const SizedBox(height: 4), + Text( + "Relation: ${profile.relationship ?? "N/A"}", + style: const TextStyle( + fontSize: 12, + color: Colors.grey, + ), + textAlign: TextAlign.center, + ), + const SizedBox(height: 5), + if (isActive) + CustomButton( + height: 36, + onPressed: (){}, // Disabled + text: 'Active', + backgroundColor: Colors.grey.shade200, + borderColor: Colors.grey.shade200, + textColor: Colors.black, + fontSize: 13, + ).paddingOnly(top: 8, bottom: 4) + else + CustomButton( + height: 36, + onPressed: () => onSelect(profile), + text: 'Select', + backgroundColor: const Color(0xffFEE9EA), + borderColor: const Color(0xffFEE9EA), + textColor: const Color(0xffED1C2B), + fontSize: 13, + ).paddingOnly(top: 8, bottom: 4), + ], + ), + ), + ); + }, + ), + ], ), - trailing: const Icon(Icons.arrow_forward_ios, size: 16), - onTap: () => onSelect(profile), - ); - }).toList(), - ); + ), + ); + } + } -} diff --git a/lib/widgets/my_family/my_family_sheet.dart b/lib/widgets/my_family/my_family_sheet.dart index 57aa7bc..9c2ce38 100644 --- a/lib/widgets/my_family/my_family_sheet.dart +++ b/lib/widgets/my_family/my_family_sheet.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:hmg_patient_app_new/core/utils/utils.dart'; import 'package:hmg_patient_app_new/features/medical_file/models/family_file_response_model.dart'; import '../common_bottom_sheet.dart'; import 'my_Family.dart'; @@ -7,7 +8,9 @@ import 'my_Family.dart'; showCommonBottomSheetWithoutHeight( context, title: 'Select Profile', + child: ProfileSelector(profiles: familyLists, onSelect: (profile) { + Navigator.of(context).pop(); // Close the bottom sheet onSelect(profile); // Call the onSelect callback }), callBackFunc: () {},