From e498f4f0ad3202700c0851a7cdec5c6182f96aa4 Mon Sep 17 00:00:00 2001 From: yaso Date: Tue, 1 Oct 2024 12:38:10 +0200 Subject: [PATCH] home enhancement with layout buider --- .../lib/mih_packages/mih_home/MIH_Home.dart | 693 ++++++++++++++++++ .../mih_home/MIH_Profile_Getter.dart | 151 ++++ 2 files changed, 844 insertions(+) create mode 100644 Frontend/patient_manager/lib/mih_packages/mih_home/MIH_Home.dart create mode 100644 Frontend/patient_manager/lib/mih_packages/mih_home/MIH_Profile_Getter.dart diff --git a/Frontend/patient_manager/lib/mih_packages/mih_home/MIH_Home.dart b/Frontend/patient_manager/lib/mih_packages/mih_home/MIH_Home.dart new file mode 100644 index 00000000..ec25fb02 --- /dev/null +++ b/Frontend/patient_manager/lib/mih_packages/mih_home/MIH_Home.dart @@ -0,0 +1,693 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:google_nav_bar/google_nav_bar.dart'; +import 'package:patient_manager/mih_components/mih_layout/mih_action.dart'; +import 'package:patient_manager/mih_components/mih_layout/mih_body.dart'; +import 'package:patient_manager/mih_components/mih_layout/mih_header.dart'; +import 'package:patient_manager/mih_components/mih_layout/mih_layout_builder.dart'; +import 'package:patient_manager/mih_components/mih_layout/mih_tile.dart'; +import 'package:patient_manager/mih_components/mih_inputs_and_buttons/mih_search_input.dart'; +import 'package:patient_manager/mih_components/mih_layout/mih_app_drawer.dart'; +import 'package:patient_manager/mih_components/mih_layout/mih_window.dart'; +import 'package:patient_manager/mih_components/mih_pop_up_messages/mih_delete_message.dart'; +import 'package:patient_manager/mih_components/mih_pop_up_messages/mih_loading_circle.dart'; +import 'package:patient_manager/mih_components/mih_pop_up_messages/mih_warning_message.dart'; +import 'package:patient_manager/mih_components/mih_pop_up_messages/mih_error_message.dart'; +import 'package:patient_manager/mih_components/mih_pop_up_messages/mih_success_message.dart'; +import 'package:patient_manager/mih_env/env.dart'; +import 'package:patient_manager/main.dart'; +import 'package:patient_manager/mih_objects/app_user.dart'; +import 'package:patient_manager/mih_objects/arguments.dart'; +import 'package:patient_manager/mih_objects/business.dart'; +import 'package:patient_manager/mih_objects/business_user.dart'; + +class MIHHome extends StatefulWidget { + final AppUser signedInUser; + final BusinessUser? businessUser; + final Business? business; + final ImageProvider? propicFile; + const MIHHome({ + super.key, + required this.signedInUser, + required this.businessUser, + required this.business, + required this.propicFile, + }); + + @override + State createState() => _MIHHomeState(); +} + +class _MIHHomeState extends State { + final TextEditingController searchController = TextEditingController(); + final FocusNode _focusNode = FocusNode(); + late List persHTList = []; + late List busHTList = []; + late List> pbswitch; + late bool businessUserSwitch; + int _selectedIndex = 0; + String appSearch = ""; + final baseAPI = AppEnviroment.baseApiUrl; + + void setAppsNewPersonal(List tileList) { + if (widget.signedInUser.fname == "") { + tileList.add(MIHTile( + onTap: () { + Navigator.of(context).pushNamed('/user-profile', + arguments: AppProfileUpdateArguments( + widget.signedInUser, widget.propicFile)); + }, + tileName: "Setup Profie", + tileIcon: Icon( + Icons.perm_identity, + color: getSec(), + size: 200, + ), + p: getPrim(), + s: getSec(), + )); + } + } + + void setAppsNewBusiness(List tileList) { + tileList.add(MIHTile( + onTap: () { + Navigator.of(context).popAndPushNamed( + '/business-profile/set-up', + arguments: widget.signedInUser, + ); + }, + tileName: "Setup Business", + tileIcon: Icon( + Icons.add_business_outlined, + color: getSec(), + size: 200, + ), + p: getPrim(), + s: getSec(), + )); + } + + void setAppsPersonal(List tileList) { + ImageProvider logo = MzanziInnovationHub.of(context)!.theme.logoImage(); + tileList.add(MIHTile( + onTap: () { + Navigator.of(context).pushNamed( + '/user-profile', + arguments: + AppProfileUpdateArguments(widget.signedInUser, widget.propicFile), + ); + }, + tileName: "Mzansi Profile", + tileIcon: Image(image: logo), + p: getPrim(), + s: getSec(), + )); + tileList.add(MIHTile( + onTap: () { + Navigator.of(context).pushNamed('/patient-profile', + arguments: PatientViewArguments( + widget.signedInUser, null, null, null, "personal")); + }, + tileName: "Patient Profile", + tileIcon: Icon( + Icons.medication, + color: getSec(), + size: 200, + ), + p: getPrim(), + s: getSec(), + )); + tileList.add(MIHTile( + onTap: () { + Navigator.of(context).pushNamed( + '/access-review', + arguments: widget.signedInUser, + ); + }, + tileName: "Access Review", + tileIcon: Icon( + Icons.check_box_outlined, + color: getSec(), + size: 200, + ), + p: getPrim(), + s: getSec(), + )); + + tileList.add(MIHTile( + onTap: () { + Navigator.of(context).pushNamed( + '/about', + arguments: widget.signedInUser, + ); + }, + tileName: "About MIH", + tileIcon: Icon( + Icons.info_outline, + color: getSec(), + size: 200, + ), + p: getPrim(), + s: getSec(), + )); + } + + void setAppsBusiness(List tileList) { + // tileList.add(MIHTile( + // onTap: () { + // Navigator.of(context).pushNamed( + // '/business-profile', + // arguments: BusinessArguments( + // widget.signedInUser, + // widget.businessUser, + // widget.business, + // ), + // ); + // }, + // tileName: "Manage Business", + // tileIcon: Icon( + // Icons.business, + // color: getSec(), + // size: 200, + // ), + // p: getPrim(), + // s: getSec(), + // )); + //if (widget.businessUser!.access == "Full") { + tileList.add(MIHTile( + onTap: () { + Navigator.of(context).pushNamed( + '/business-profile/manage', + arguments: BusinessArguments( + widget.signedInUser, + widget.businessUser, + widget.business, + ), + ); + }, + tileName: "Business Profile", + tileIcon: Icon( + Icons.business, + color: getSec(), + size: 200, + ), + p: getPrim(), + s: getSec(), + )); + //} + if (widget.business!.type == "Doctors Office") { + tileList.add(MIHTile( + onTap: () { + Navigator.of(context).pushNamed( + '/patient-manager', + arguments: BusinessArguments( + widget.signedInUser, + widget.businessUser, + widget.business, + ), + ); + }, + tileName: "Manage Patient", + tileIcon: Icon( + Icons.medication, + color: getSec(), + size: 200, + ), + p: getPrim(), + s: getSec(), + )); + } + } + + void setAppsDev(List tileList) { + if (AppEnviroment.getEnv() == "Dev") { + tileList.add(MIHTile( + onTap: () { + showDialog( + context: context, + builder: (context) { + return const Mihloadingcircle(); + }, + ); + }, + tileName: "Loading - Dev", + tileIcon: Icon( + Icons.change_circle, + color: getSec(), + size: 200, + ), + p: getPrim(), + s: getSec(), + )); + tileList.add(MIHTile( + onTap: () { + Navigator.of(context).pushNamed( + '/business-profile/set-up', + arguments: widget.signedInUser, + ); + }, + tileName: "Setup Bus - Dev", + tileIcon: Icon( + Icons.add_business_outlined, + color: getSec(), + size: 200, + ), + p: getPrim(), + s: getSec(), + )); + tileList.add(MIHTile( + onTap: () { + Navigator.of(context).pushNamed('/patient-profile/set-up', + arguments: widget.signedInUser); + }, + tileName: "Add Pat - Dev", + tileIcon: Icon( + Icons.add_circle_outline, + color: getSec(), + size: 200, + ), + p: getPrim(), + s: getSec(), + )); + + tileList.add(MIHTile( + onTap: () { + showDialog( + context: context, + builder: (context) { + // return const MIHWarningMessage(warningType: "No Access"); + return const MIHWarningMessage(warningType: "Expired Access"); + }, + ); + }, + tileName: "Warn - Dev", + tileIcon: Icon( + Icons.warning_amber_rounded, + color: getSec(), + size: 200, + ), + p: getPrim(), + s: getSec(), + )); + tileList.add(MIHTile( + onTap: () { + showDialog( + context: context, + builder: (context) { + // return const MIHErrorMessage(errorType: "Input Error"); + // return const MIHErrorMessage(errorType: "Password Requirements"); + // return const MIHErrorMessage(errorType: "Invalid Username"); + // return const MIHErrorMessage(errorType: "Invalid Email"); + // return const MIHErrorMessage(errorType: "User Exists"); + // return const MIHErrorMessage(errorType: "Password Match"); + // return const MIHErrorMessage(errorType: "Invalid Credentials"); + return const MIHErrorMessage(errorType: "Internet Connection"); + }, + ); + }, + tileName: "Error - Dev", + tileIcon: Icon( + Icons.error_outline_outlined, + color: getSec(), + size: 200, + ), + p: getPrim(), + s: getSec(), + )); + tileList.add(MIHTile( + onTap: () { + showDialog( + context: context, + builder: (context) { + return const MIHSuccessMessage( + successType: "Success", + successMessage: + "Congratulations! Your account has been created successfully. You are log in and can start exploring.\n\nPlease note: more apps will appear once you update your profile."); + }, + ); + }, + tileName: "Success - Dev", + tileIcon: Icon( + Icons.check_circle_outline_outlined, + color: getSec(), + size: 200, + ), + p: getPrim(), + s: getSec(), + )); + + tileList.add(MIHTile( + onTap: () { + showDialog( + context: context, + builder: (context) { + // return MIHDeleteMessage(deleteType: "Note", onTap: () {}); + return MIHDeleteMessage(deleteType: "File", onTap: () {}); + }, + ); + }, + tileName: "Delete - Dev", + tileIcon: Icon( + Icons.delete_forever_outlined, + color: getSec(), + size: 200, + ), + p: getPrim(), + s: getSec(), + )); + tileList.add(MIHTile( + onTap: () { + showDialog( + barrierDismissible: false, + context: context, + builder: (context) { + // return const MIHErrorMessage(errorType: "Input Error"); + // return const MIHErrorMessage(errorType: "Password Requirements"); + // return const MIHErrorMessage(errorType: "Invalid Username"); + // return const MIHErrorMessage(errorType: "Invalid Email"); + // return const MIHErrorMessage(errorType: "User Exists"); + // return const MIHErrorMessage(errorType: "Password Match"); + // return const MIHErrorMessage(errorType: "Invalid Credentials"); + return MIHWindow( + fullscreen: false, + windowTitle: + "Test Window title that is too large for mobile devices", + windowBody: const [ + SizedBox( + height: 250, + ) + ], + windowTools: [ + IconButton( + onPressed: () { + //deleteFilePopUp(filePath, fileID); + }, + icon: Icon( + Icons.delete, + size: 35, + color: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + ), + ), + IconButton( + onPressed: () { + //deleteFilePopUp(filePath, fileID); + }, + icon: Icon( + Icons.wallet, + size: 35, + color: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + ), + ), + ], + onWindowTapClose: () { + Navigator.pop(context); + }, + ); + }, + ); + }, + tileName: "Window - Dev", + tileIcon: Icon( + Icons.window, + color: getSec(), + size: 200, + ), + p: getPrim(), + s: getSec(), + )); + } + } + + List searchApp(List appList, String searchString) { + if (searchString == "") { + return appList; + } else { + List temp = []; + for (var item in appList) { + if (item.tileName.toLowerCase().contains(appSearch.toLowerCase())) { + temp.add(item); + } + } + return temp; + } + } + + List> setApps( + List personalTileList, List businessTileList) { + if (widget.signedInUser.fname == "") { + setAppsNewPersonal(personalTileList); + } else if (widget.signedInUser.type == "personal") { + setAppsPersonal(personalTileList); + } else if (widget.businessUser == null) { + setAppsPersonal(personalTileList); + setAppsNewBusiness(businessTileList); + } else { + setAppsPersonal(personalTileList); + setAppsBusiness(businessTileList); + } + if (AppEnviroment.getEnv() == "Dev") { + setAppsDev(personalTileList); + setAppsDev(businessTileList); + } + return [personalTileList, businessTileList]; + } + + Color getPrim() { + return MzanziInnovationHub.of(context)!.theme.secondaryColor(); + } + + Color getSec() { + return MzanziInnovationHub.of(context)!.theme.primaryColor(); + } + + bool isBusinessUser(AppUser signedInUser) { + if (signedInUser.type == "personal") { + return false; + } else { + return true; + } + } + + String getHeading(int index) { + if (index == 0) { + return "Personal Apps"; + } else { + return "Business Apps"; + } + } + + void onDragStart(DragStartDetails startDrag) { + Scaffold.of(context).openDrawer(); + print(startDrag.globalPosition.dx); + } + + Widget getActionButton() { + return Builder(builder: (context) { + return MIHAction( + icon: const Icon(Icons.apps), + iconSize: 35, + onTap: () { + setState(() { + appSearch = ""; + searchController.clear(); + }); + //key.currentState.o + Scaffold.of(context).openDrawer(); + }, + ); + }); + } + + Widget getSecondaryActionButton() { + return Builder(builder: (context) { + return MIHAction( + icon: const Icon(Icons.notifications), + iconSize: 35, + onTap: () { + setState(() { + appSearch = ""; + searchController.clear(); + }); + //key.currentState.o + //Scaffold.of(context).openEndDrawer(); + }, + ); + }); + } + + MIHHeader getHeader() { + return const MIHHeader( + headerAlignment: MainAxisAlignment.center, + headerItems: [ + Text( + "Mzanzi Innovation Hub", + style: TextStyle( + fontWeight: FontWeight.bold, + fontSize: 20, + ), + ), + ], + ); + } + + MIHBody getBody(double width, double height) { + return MIHBody( + borderOn: false, + bodyItems: [ + Row( + mainAxisAlignment: MainAxisAlignment.center, + mainAxisSize: MainAxisSize.max, + children: [ + Flexible( + flex: 4, + child: KeyboardListener( + focusNode: _focusNode, + autofocus: true, + onKeyEvent: (event) async { + if (event is KeyDownEvent && + event.logicalKey == LogicalKeyboardKey.enter) { + setState(() { + appSearch = searchController.text; + }); + } + }, + child: SizedBox( + child: MIHSearchField( + controller: searchController, + hintText: "Search Mzansi Apps", + required: false, + editable: true, + onTap: () { + setState(() { + appSearch = searchController.text; + }); + }, + ), + ), + ), + ), + Flexible( + flex: 1, + child: IconButton( + //padding: const EdgeInsets.all(0), + onPressed: () { + setState(() { + appSearch = ""; + searchController.clear(); + }); + }, + icon: const Icon( + Icons.filter_alt_off, + size: 30, + ), + ), + ), + ], + ), + const SizedBox(height: 10), + GridView.builder( + shrinkWrap: true, + padding: EdgeInsets.only( + left: width / 10, + right: width / 10, + //bottom: height / 5, + top: 20, + ), + // physics: , + // shrinkWrap: true, + itemCount: searchApp(pbswitch[_selectedIndex], appSearch).length, + gridDelegate: const SliverGridDelegateWithMaxCrossAxisExtent( + mainAxisSpacing: 15, maxCrossAxisExtent: 200), + itemBuilder: (context, index) { + return searchApp(pbswitch[_selectedIndex], appSearch)[index]; + }, + ), + ], + ); + } + + MIHAppDrawer getActionDrawer() { + return MIHAppDrawer( + signedInUser: widget.signedInUser, + propicFile: widget.propicFile, + ); + } + + Widget getBottomNavBar() { + return Visibility( + visible: isBusinessUser(widget.signedInUser), + child: Padding( + padding: const EdgeInsets.all(15.0), + child: GNav( + //hoverColor: Colors.lightBlueAccent, + color: MzanziInnovationHub.of(context)!.theme.secondaryColor(), + iconSize: 35.0, + activeColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), + tabBackgroundColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + //gap: 20, + //padding: EdgeInsets.all(15), + tabs: [ + GButton( + icon: Icons.perm_identity, + text: "Personal", + onPressed: () { + setState(() { + _selectedIndex = 0; + }); + }, + ), + GButton( + icon: Icons.business_center, + text: "Business", + onPressed: () { + setState(() { + _selectedIndex = 1; + }); + }, + ), + ], + selectedIndex: _selectedIndex, + ), + ), + ); + } + + @override + void dispose() { + searchController.dispose(); + _focusNode.dispose(); + super.dispose(); + } + + @override + void initState() { + setState(() { + pbswitch = setApps(persHTList, busHTList); + businessUserSwitch = false; + }); + + super.initState(); + } + + @override + Widget build(BuildContext context) { + final Size size = MediaQuery.sizeOf(context); + final double width = size.width; + final double height = size.height; + return MIHLayoutBuilder( + actionButton: getActionButton(), + header: getHeader(), + secondaryActionButton: getSecondaryActionButton(), + body: getBody(width, height), + actionDrawer: getActionDrawer(), + secondaryActionDrawer: null, + bottomNavBar: getBottomNavBar(), + ); + } +} diff --git a/Frontend/patient_manager/lib/mih_packages/mih_home/MIH_Profile_Getter.dart b/Frontend/patient_manager/lib/mih_packages/mih_home/MIH_Profile_Getter.dart new file mode 100644 index 00000000..cf56e6e9 --- /dev/null +++ b/Frontend/patient_manager/lib/mih_packages/mih_home/MIH_Profile_Getter.dart @@ -0,0 +1,151 @@ +import 'dart:convert'; + +import 'package:flutter/material.dart'; +import 'package:patient_manager/mih_components/mih_pop_up_messages/mih_loading_circle.dart'; +import 'package:patient_manager/mih_env/env.dart'; +import 'package:patient_manager/mih_objects/app_user.dart'; +import 'package:patient_manager/mih_objects/arguments.dart'; +import 'package:patient_manager/mih_objects/business.dart'; +import 'package:patient_manager/mih_objects/business_user.dart'; +import 'package:patient_manager/mih_packages/mih_home/MIH_Home.dart'; +import 'package:supertokens_flutter/supertokens.dart'; +import 'package:supertokens_flutter/http.dart' as http; + +class MIHProfileGetter extends StatefulWidget { + const MIHProfileGetter({ + super.key, + }); + + @override + State createState() => _MIHProfileGetterState(); +} + +class _MIHProfileGetterState extends State { + String useremail = ""; + final baseAPI = AppEnviroment.baseApiUrl; + late Future profile; + + String proPicUrl = "empty"; + ImageProvider? propicFile; + + Future getProfile() async { + AppUser userData; + Business? busData; + BusinessUser? bUserData; + String userPic; + + // Get Userdata + var uid = await SuperTokens.getUserId(); + var responseUser = await http.get(Uri.parse("$baseAPI/user/$uid")); + if (responseUser.statusCode == 200) { + // print("here"); + String body = responseUser.body; + var decodedData = jsonDecode(body); + AppUser u = AppUser.fromJson(decodedData); + userData = u; + } else { + throw Exception( + "Error: GetUserData status code ${responseUser.statusCode}"); + } + + // Get BusinessUserdata + var responseBUser = + await http.get(Uri.parse("$baseAPI/business-user/$uid")); + if (responseBUser.statusCode == 200) { + String body = responseBUser.body; + var decodedData = jsonDecode(body); + BusinessUser business_User = BusinessUser.fromJson(decodedData); + bUserData = business_User; + } else { + bUserData = null; + } + + // Get Businessdata + var responseBusiness = + await http.get(Uri.parse("$baseAPI/business/app_id/$uid")); + if (responseBusiness.statusCode == 200) { + String body = responseBusiness.body; + var decodedData = jsonDecode(body); + Business business = Business.fromJson(decodedData); + busData = business; + } else { + busData = null; + } + + //get profile picture + if (userData.pro_pic_path == "") { + userPic = ""; + } + // else if (AppEnviroment.getEnv() == "Dev") { + // userPic = "${AppEnviroment.baseFileUrl}/mih/${userData.pro_pic_path}"; + // } + else { + var url = + "${AppEnviroment.baseApiUrl}/minio/pull/file/${AppEnviroment.getEnv()}/${userData.pro_pic_path}"; + var response = await http.get(Uri.parse(url)); + + if (response.statusCode == 200) { + String body = response.body; + var decodedData = jsonDecode(body); + + userPic = decodedData['minioURL']; + } else { + userPic = ""; + // throw Exception( + // "Error: GetUserData status code ${response.statusCode}"); + } + } + //print(userPic); + return HomeArguments(userData, bUserData, busData, userPic); + } + + ImageProvider? isPictureAvailable(String url) { + if (url == "") { + return const AssetImage('images/i-dont-know-2.png'); + } else if (url != "") { + return NetworkImage(url); + } else { + return null; + } + } + +// Dont know icons created by Freepik - Flaticon + @override + void dispose() { + // TODO: implement dispose + super.dispose(); + } + + @override + void initState() { + profile = getProfile(); + super.initState(); + } + + @override + Widget build(BuildContext context) { + return FutureBuilder( + future: profile, + builder: (BuildContext context, snapshot) { + if (snapshot.connectionState == ConnectionState.done) { + if (snapshot.hasData) { + return MIHHome( + signedInUser: snapshot.requireData.signedInUser, + businessUser: snapshot.data!.businessUser, + business: snapshot.data!.business, + propicFile: isPictureAvailable(snapshot.data!.profilePicUrl), + ); + } else { + return Center( + child: Text( + '${snapshot.error} occurred', + style: const TextStyle(fontSize: 18), + ), + ); + } + } + return const Mihloadingcircle(); + }, + ); + } +}