diff --git a/Frontend/lib/main.dart b/Frontend/lib/main.dart index bffb4a3d..018c35ea 100644 --- a/Frontend/lib/main.dart +++ b/Frontend/lib/main.dart @@ -5,6 +5,7 @@ import 'package:mzansi_innovation_hub/mih_components/mih_providers/mih_authentic import 'package:mzansi_innovation_hub/mih_components/mih_providers/mih_banner_ad_provider.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_providers/mih_calculator_provider.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_providers/mih_mine_sweeper_provider.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_providers/mzansi_profile_provider.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_providers/mzansi_wallet_provider.dart'; import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart'; import 'package:provider/provider.dart'; @@ -78,6 +79,9 @@ class _MzansiInnovationHubState extends State { ChangeNotifierProvider( create: (context) => MihAuthenticationProvider(), ), + ChangeNotifierProvider( + create: (context) => MzansiProfileProvider(), + ), ChangeNotifierProvider( create: (context) => MzansiWalletProvider(), ), diff --git a/Frontend/lib/mih_components/mih_package_components/mih_image_display.dart b/Frontend/lib/mih_components/mih_package_components/mih_image_display.dart index c33fe4f7..6d6d3145 100644 --- a/Frontend/lib/mih_components/mih_package_components/mih_image_display.dart +++ b/Frontend/lib/mih_components/mih_package_components/mih_image_display.dart @@ -32,19 +32,8 @@ class _MihImageDisplayState extends State { late ImageProvider? imagePreview; ImageProvider? getImage() { - Color dark = const Color(0XFF3A4454); if (widget.imageFile == null) { - if (MihColors.getSecondaryColor( - MzansiInnovationHub.of(context)!.theme.mode == "Dark") == - dark) { - print("here in light icon"); - return const AssetImage( - 'lib/mih_components/mih_package_components/assets/images/i-dont-know-dark.png'); - } else { - print("here in dark icon"); - return const AssetImage( - 'lib/mih_components/mih_package_components/assets/images/i-dont-know-light.png'); - } + return null; } else { return widget.imageFile; } @@ -69,9 +58,12 @@ class _MihImageDisplayState extends State { child: Stack( alignment: Alignment.center, children: [ - ClipRRect( - borderRadius: BorderRadius.circular(widget.width * 0.1), - child: Image(image: imagePreview!), + Visibility( + visible: imagePreview != null, + child: ClipRRect( + borderRadius: BorderRadius.circular(widget.width * 0.1), + child: Image(image: imagePreview!), + ), ), Visibility( visible: widget.editable, diff --git a/Frontend/lib/mih_components/mih_providers/mih_calendar_provider.dart b/Frontend/lib/mih_components/mih_providers/mih_calendar_provider.dart new file mode 100644 index 00000000..7b80ab62 --- /dev/null +++ b/Frontend/lib/mih_components/mih_providers/mih_calendar_provider.dart @@ -0,0 +1,14 @@ +import 'package:flutter/foundation.dart'; + +class MihCalendarProvider extends ChangeNotifier { + int toolIndex; + + MihCalendarProvider({ + this.toolIndex = 0, + }); + + void setToolIndex(int index) { + toolIndex = index; + notifyListeners(); + } +} diff --git a/Frontend/lib/mih_components/mih_providers/mih_mine_sweeper_provider.dart b/Frontend/lib/mih_components/mih_providers/mih_mine_sweeper_provider.dart new file mode 100644 index 00000000..1d881fd9 --- /dev/null +++ b/Frontend/lib/mih_components/mih_providers/mih_mine_sweeper_provider.dart @@ -0,0 +1,35 @@ +import 'package:flutter/widgets.dart'; + +class MihMineSweeperProvider extends ChangeNotifier { + int toolIndex; + int rowCount; + int columnCount; + int totalMines; + + MihMineSweeperProvider({ + this.toolIndex = 0, + this.rowCount = 10, + this.columnCount = 10, + this.totalMines = 15, + }); + + void setToolIndex(int index) { + toolIndex = index; + notifyListeners(); + } + + void setRowCount(int rowCount) { + this.rowCount = rowCount; + notifyListeners(); + } + + void setCoulmnCount(int columnCount) { + this.columnCount = columnCount; + notifyListeners(); + } + + void setTotalMines(int totalMines) { + this.totalMines = totalMines; + notifyListeners(); + } +} diff --git a/Frontend/lib/mih_components/mih_providers/mzansi_profile_provider.dart b/Frontend/lib/mih_components/mih_providers/mzansi_profile_provider.dart new file mode 100644 index 00000000..8941a0a9 --- /dev/null +++ b/Frontend/lib/mih_components/mih_providers/mzansi_profile_provider.dart @@ -0,0 +1,102 @@ +import 'package:flutter/material.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_objects/app_user.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_objects/business.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_objects/business_employee.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_objects/business_user.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_objects/user_consent.dart'; + +class MzansiProfileProvider extends ChangeNotifier { + bool personalHome; + int personalIndex; + int businessIndex; + AppUser? user; + String? userProfilePicUrl; + ImageProvider? userProfilePicture; + Business? business; + String? businessProfilePicUrl; + ImageProvider? businessProfilePicture; + BusinessUser? businessUser; + String? businessUserSignatureUrl; + ImageProvider? businessUserSignature; + UserConsent? userConsent; + List? employeeList; + + MzansiProfileProvider({ + this.personalHome = true, + this.personalIndex = 0, + this.businessIndex = 0, + }); + + void reset() { + personalHome = true; + personalIndex = 0; + businessIndex = 0; + user = null; + userProfilePicUrl = null; + userProfilePicture = null; + business = null; + businessProfilePicUrl = null; + businessProfilePicture = null; + businessUser = null; + businessUserSignatureUrl = null; + businessUserSignature = null; + userConsent = null; + } + + void setPersonalIndex(int index) { + personalIndex = index; + notifyListeners(); + } + + void setBusinessIndex(int index) { + businessIndex = index; + notifyListeners(); + } + + void setUser({ + required AppUser newUser, + }) { + user = newUser; + notifyListeners(); + } + + void setUserProfilePicUrl(String url) { + userProfilePicUrl = url; + userProfilePicture = url.isNotEmpty ? NetworkImage(url) : null; + notifyListeners(); + } + + void setBusiness({ + Business? newBusiness, + }) { + business = newBusiness; + notifyListeners(); + } + + void setBusinessProfilePicUrl(String url) { + businessProfilePicUrl = url; + businessProfilePicture = url.isNotEmpty ? NetworkImage(url) : null; + notifyListeners(); + } + + void setBusinessUser({required BusinessUser newBusinessUser}) { + businessUser = newBusinessUser; + notifyListeners(); + } + + void setBusinessUserSignatureUrl(String url) { + businessUserSignatureUrl = url; + businessUserSignature = url.isNotEmpty ? NetworkImage(url) : null; + notifyListeners(); + } + + void setUserConsent(UserConsent? newUserConsent) { + userConsent = newUserConsent; + notifyListeners(); + } + + void setEmployeeList({required List employeeList}) { + this.employeeList = employeeList; + notifyListeners(); + } +} diff --git a/Frontend/lib/mih_config/mih_colors.dart b/Frontend/lib/mih_config/mih_colors.dart index 6c69d0a9..398736af 100644 --- a/Frontend/lib/mih_config/mih_colors.dart +++ b/Frontend/lib/mih_config/mih_colors.dart @@ -37,7 +37,7 @@ class MihColors { if (darkMode == true) { return const Color(0xff8ae290); } else { - return const Color(0xffB0F2B4); + return const Color(0xFF41B349); } } @@ -63,7 +63,7 @@ class MihColors { return const Color(0xffd69d7d); } else { // Add a different shade of pink for light mode - return const Color(0xffd69d7d); + return const Color(0xFFBD7145); } } @@ -81,7 +81,7 @@ class MihColors { return const Color(0xff6e7dcc); } else { // Add a different shade of pink for light mode - return const Color(0xff6e7dcc); + return const Color(0xFF5567C0); } } @@ -90,7 +90,7 @@ class MihColors { return const Color(0xffb682e7); } else { // Add a different shade of pink for light mode - return const Color(0xffb682e7); + return const Color(0xFF9857D4); } } } diff --git a/Frontend/lib/mih_config/mih_go_router.dart b/Frontend/lib/mih_config/mih_go_router.dart index 856d61ff..25743e6d 100644 --- a/Frontend/lib/mih_config/mih_go_router.dart +++ b/Frontend/lib/mih_config/mih_go_router.dart @@ -4,6 +4,7 @@ import 'package:mzansi_innovation_hub/mih_components/mih_layout/mih_print_prevew import 'package:mzansi_innovation_hub/mih_components/mih_objects/app_user.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_objects/arguments.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/Example/package_test.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_providers/mzansi_profile_provider.dart'; import 'package:mzansi_innovation_hub/mih_packages/about_mih/about_mih.dart'; import 'package:mzansi_innovation_hub/mih_packages/access_review/mih_access.dart'; import 'package:mzansi_innovation_hub/mih_packages/calculator/mih_calculator.dart'; @@ -29,6 +30,7 @@ import 'package:mzansi_innovation_hub/mih_packages/patient_profile/pat_profile/a import 'package:mzansi_innovation_hub/mih_packages/patient_profile/pat_profile/components/full_screen_file.dart'; import 'package:mzansi_innovation_hub/mih_packages/patient_profile/pat_profile/patient_edit.dart'; import 'package:mzansi_innovation_hub/mih_packages/patient_profile/pat_profile/patient_profile.dart'; +import 'package:provider/provider.dart'; import 'package:supertokens_flutter/supertokens.dart'; class MihGoRouterPaths { @@ -133,16 +135,8 @@ class MihGoRouter { path: MihGoRouterPaths.mihHome, builder: (BuildContext context, GoRouterState state) { KenLogger.success("MihGoRouter: mihHome"); - if (state.extra != null) { - final bool personalSelected = state.extra as bool; - return MihHome( - key: UniqueKey(), - personalSelected: personalSelected, - ); - } return MihHome( key: UniqueKey(), - personalSelected: true, ); }, ), @@ -166,15 +160,13 @@ class MihGoRouter { path: MihGoRouterPaths.mzansiProfileManage, builder: (BuildContext context, GoRouterState state) { KenLogger.success("MihGoRouter: mzansiProfileManage"); - final AppProfileUpdateArguments? args = - state.extra as AppProfileUpdateArguments?; - if (args == null) { + if (context.watch().user == null) { WidgetsBinding.instance.addPostFrameCallback((_) { context.go(MihGoRouterPaths.mihHome); }); return const SizedBox.shrink(); } - return MzansiProfile(arguments: args); + return MzansiProfile(); }, ), GoRoute( @@ -198,8 +190,7 @@ class MihGoRouter { path: MihGoRouterPaths.businessProfileManage, builder: (BuildContext context, GoRouterState state) { KenLogger.success("MihGoRouter: businessProfileManage"); - final BusinessArguments? args = state.extra as BusinessArguments?; - if (args == null) { + if (context.watch().business == null) { WidgetsBinding.instance.addPostFrameCallback((_) { context.go(MihGoRouterPaths.mihHome); }); @@ -207,7 +198,6 @@ class MihGoRouter { } return MzansiBusinessProfile( key: UniqueKey(), - arguments: args, ); }, ), diff --git a/Frontend/lib/mih_packages/calculator/package_tiles/mih_calculator_tile.dart b/Frontend/lib/mih_packages/calculator/package_tiles/mih_calculator_tile.dart index 58c42944..4011d6d1 100644 --- a/Frontend/lib/mih_packages/calculator/package_tiles/mih_calculator_tile.dart +++ b/Frontend/lib/mih_packages/calculator/package_tiles/mih_calculator_tile.dart @@ -28,10 +28,6 @@ class _MihCalculatorTileState extends State { "mihCalculator", extra: widget.personalSelected, ); - // Navigator.of(context).pushNamed( - // '/calculator', - // arguments: widget.personalSelected, - // ); }, appName: "Calculator", appIcon: Icon( diff --git a/Frontend/lib/mih_packages/calendar/mzansi_calendar.dart b/Frontend/lib/mih_packages/calendar/mzansi_calendar.dart index 2e5bbd51..fc148291 100644 --- a/Frontend/lib/mih_packages/calendar/mzansi_calendar.dart +++ b/Frontend/lib/mih_packages/calendar/mzansi_calendar.dart @@ -3,8 +3,10 @@ import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_ import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_action.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_tools.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_objects/arguments.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_providers/mih_calendar_provider.dart'; import 'package:mzansi_innovation_hub/mih_packages/calendar/package_tools/appointments.dart'; import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; class MzansiCalendar extends StatefulWidget { final CalendarArguments arguments; @@ -18,8 +20,6 @@ class MzansiCalendar extends StatefulWidget { } class _MzansiCalendarState extends State { - int _selcetedIndex = 0; - @override Widget build(BuildContext context) { return MihPackage( @@ -27,12 +27,9 @@ class _MzansiCalendarState extends State { appTools: getTools(), appBody: getToolBody(), appToolTitles: getToolTitle(), - selectedbodyIndex: _selcetedIndex, - onIndexChange: (newValue) { - setState(() { - _selcetedIndex = newValue; - }); - print("Index: $_selcetedIndex"); + selectedbodyIndex: context.watch().toolIndex, + onIndexChange: (newIndex) { + context.read().setToolIndex(newIndex); }, ); } @@ -55,14 +52,12 @@ class _MzansiCalendarState extends State { MihPackageTools getTools() { Map temp = {}; temp[const Icon(Icons.calendar_month)] = () { - setState(() { - _selcetedIndex = 0; - }); + context.read().setToolIndex(0); }; return MihPackageTools( tools: temp, - selcetedIndex: _selcetedIndex, + selcetedIndex: context.watch().toolIndex, ); } diff --git a/Frontend/lib/mih_packages/mih_home/components/mih_app_drawer.dart b/Frontend/lib/mih_packages/mih_home/components/mih_app_drawer.dart index bd09514d..3b3821ea 100644 --- a/Frontend/lib/mih_packages/mih_home/components/mih_app_drawer.dart +++ b/Frontend/lib/mih_packages/mih_home/components/mih_app_drawer.dart @@ -5,6 +5,7 @@ import 'package:mzansi_innovation_hub/mih_components/mih_objects/arguments.dart' import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_circle_avatar.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_icons.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_providers/about_mih_provider.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_providers/mzansi_profile_provider.dart'; import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart'; import 'package:provider/provider.dart'; import '../../../main.dart'; @@ -78,293 +79,299 @@ class _MIHAppDrawerState extends State { Widget build(BuildContext context) { // precacheImage( // MzansiInnovationHub.of(context)!.theme.logoImage().image, context); - return SafeArea( - child: Drawer( - //backgroundColor: MihColors.getPrimaryColor(MzansiInnovationHub.of(context)!.theme.mode == "Dark"), - child: LayoutBuilder( - builder: (BuildContext context, BoxConstraints constraints) { - return Stack( - //fit: StackFit.passthrough, - children: [ - Column( - // reverse: false, - // padding: EdgeInsets.zero, - mainAxisSize: MainAxisSize.max, + return Consumer( + builder: (BuildContext context, + MzansiProfileProvider mzansiProfileProvider, Widget? child) { + return SafeArea( + child: Drawer( + //backgroundColor: MihColors.getPrimaryColor(MzansiInnovationHub.of(context)!.theme.mode == "Dark"), + child: LayoutBuilder( + builder: (BuildContext context, BoxConstraints constraints) { + return Stack( + //fit: StackFit.passthrough, children: [ - DrawerHeader( - decoration: BoxDecoration( - color: MihColors.getSecondaryColor( - MzansiInnovationHub.of(context)!.theme.mode == - "Dark"), - ), - child: SizedBox( - height: 400, - width: constraints.maxWidth, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisSize: MainAxisSize.max, - children: [ - profilePictureLoaded, - Text( - "${widget.signedInUser.fname} ${widget.signedInUser.lname}", - style: TextStyle( - fontWeight: FontWeight.bold, - color: MihColors.getPrimaryColor( - MzansiInnovationHub.of(context)! - .theme - .mode == - "Dark"), - ), + Column( + // reverse: false, + // padding: EdgeInsets.zero, + mainAxisSize: MainAxisSize.max, + children: [ + DrawerHeader( + decoration: BoxDecoration( + color: MihColors.getSecondaryColor( + MzansiInnovationHub.of(context)!.theme.mode == + "Dark"), + ), + child: SizedBox( + height: 400, + width: constraints.maxWidth, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.max, + children: [ + profilePictureLoaded, + Text( + "${widget.signedInUser.fname} ${widget.signedInUser.lname}", + style: TextStyle( + fontWeight: FontWeight.bold, + color: MihColors.getPrimaryColor( + MzansiInnovationHub.of(context)! + .theme + .mode == + "Dark"), + ), + ), + Text( + "@${widget.signedInUser.username}", + style: TextStyle( + fontSize: 12, + fontWeight: FontWeight.bold, + color: MihColors.getPrimaryColor( + MzansiInnovationHub.of(context)! + .theme + .mode == + "Dark"), + ), + ), + Text( + widget.signedInUser.type.toUpperCase(), + style: TextStyle( + fontSize: 10, + fontWeight: FontWeight.bold, + color: MihColors.getPrimaryColor( + MzansiInnovationHub.of(context)! + .theme + .mode == + "Dark"), + ), + ), + ], ), - Text( - "@${widget.signedInUser.username}", - style: TextStyle( - fontSize: 12, - fontWeight: FontWeight.bold, - color: MihColors.getPrimaryColor( - MzansiInnovationHub.of(context)! - .theme - .mode == - "Dark"), + ), + ), + // ListTile( + // title: Row( + // mainAxisSize: MainAxisSize.max, + // children: [ + // Icon( + // Icons.home_outlined, + // color: + // MihColors.getSecondaryColor(MzansiInnovationHub.of(context)!.theme.mode == "Dark"), + // ), + // const SizedBox(width: 25.0), + // Text( + // "Home", + // style: TextStyle( + // //fontWeight: FontWeight.bold, + // color: MzansiInnovationHub.of(context)! + // .theme + // .secondaryColor(), + // ), + // ), + // ], + // ), + // onTap: () { + // Navigator.of(context) + // .pushNamedAndRemoveUntil('/', (route) => false); + // }, + // ), + Expanded( + child: Column( + mainAxisAlignment: MainAxisAlignment.end, + mainAxisSize: MainAxisSize.max, + children: [ + ListTile( + title: Row( + mainAxisSize: MainAxisSize.max, + children: [ + Icon( + Icons.policy, + color: MihColors.getSecondaryColor( + MzansiInnovationHub.of(context)! + .theme + .mode == + "Dark"), + ), + const SizedBox(width: 25.0), + Text( + "Privacy Policy", + style: TextStyle( + //fontWeight: FontWeight.bold, + color: MihColors.getSecondaryColor( + MzansiInnovationHub.of(context)! + .theme + .mode == + "Dark"), + ), + ), + ], + ), + onTap: () { + WidgetsBinding.instance + .addPostFrameCallback((_) async { + context + .read() + .setToolIndex(1); + }); + context.goNamed( + "aboutMih", + extra: true, + ); + }, ), - ), - Text( - widget.signedInUser.type.toUpperCase(), - style: TextStyle( - fontSize: 10, - fontWeight: FontWeight.bold, - color: MihColors.getPrimaryColor( - MzansiInnovationHub.of(context)! - .theme - .mode == - "Dark"), + ListTile( + title: Row( + mainAxisSize: MainAxisSize.max, + children: [ + Icon( + Icons.design_services_rounded, + color: MihColors.getSecondaryColor( + MzansiInnovationHub.of(context)! + .theme + .mode == + "Dark"), + ), + const SizedBox(width: 25.0), + Text( + "Terms of Service", + style: TextStyle( + //fontWeight: FontWeight.bold, + color: MihColors.getSecondaryColor( + MzansiInnovationHub.of(context)! + .theme + .mode == + "Dark"), + ), + ), + ], + ), + onTap: () { + WidgetsBinding.instance + .addPostFrameCallback((_) async { + context + .read() + .setToolIndex(2); + }); + context.goNamed( + "aboutMih", + extra: true, + ); + }, ), - ), - ], + ListTile( + title: Row( + mainAxisSize: MainAxisSize.max, + children: [ + Icon( + Icons.logout, + color: MihColors.getSecondaryColor( + MzansiInnovationHub.of(context)! + .theme + .mode == + "Dark"), + ), + const SizedBox(width: 25.0), + Text( + "Sign Out", + style: TextStyle( + //fontWeight: FontWeight.bold, + color: MihColors.getSecondaryColor( + MzansiInnovationHub.of(context)! + .theme + .mode == + "Dark"), + ), + ), + ], + ), + onTap: () async { + await SuperTokens.signOut( + completionHandler: (error) { + print(error); + }); + if (await SuperTokens.doesSessionExist() == + false) { + mzansiProfileProvider.reset(); + context.goNamed( + 'mihHome', + extra: true, + ); + // Navigator.of(context).pop(); + // Navigator.of(context).popAndPushNamed( + // '/', + // arguments: AuthArguments(true, false), + // ); + } + }, + ), + ], + ), + ), + ], + ), + Positioned( + top: 5, + right: 5, + width: 30, + height: 30, + child: InkWell( + onTap: () { + setState(() { + if (MzansiInnovationHub.of(context)?.theme.mode == + "Dark") { + //darkm = !darkm; + MzansiInnovationHub.of(context)! + .changeTheme(ThemeMode.light); + //print("Dark Mode: $darkm"); + } else { + //darkm = !darkm; + MzansiInnovationHub.of(context)! + .changeTheme(ThemeMode.dark); + //print("Dark Mode: $darkm"); + } + Navigator.of(context).pop(); + Navigator.of(context).popAndPushNamed( + '/', + arguments: AuthArguments(true, false), + ); + // Navigator.of(context).popAndPushNamed('/',); + }); + }, + child: Icon( + MihIcons.mihLogo, + color: MihColors.getPrimaryColor( + MzansiInnovationHub.of(context)!.theme.mode == + "Dark"), ), ), - ), - // ListTile( - // title: Row( - // mainAxisSize: MainAxisSize.max, - // children: [ - // Icon( - // Icons.home_outlined, - // color: - // MihColors.getSecondaryColor(MzansiInnovationHub.of(context)!.theme.mode == "Dark"), - // ), - // const SizedBox(width: 25.0), - // Text( - // "Home", - // style: TextStyle( - // //fontWeight: FontWeight.bold, - // color: MzansiInnovationHub.of(context)! - // .theme - // .secondaryColor(), - // ), - // ), - // ], - // ), - // onTap: () { - // Navigator.of(context) - // .pushNamedAndRemoveUntil('/', (route) => false); - // }, - // ), - Expanded( - child: Column( - mainAxisAlignment: MainAxisAlignment.end, - mainAxisSize: MainAxisSize.max, - children: [ - ListTile( - title: Row( - mainAxisSize: MainAxisSize.max, - children: [ - Icon( - Icons.policy, - color: MihColors.getSecondaryColor( - MzansiInnovationHub.of(context)! - .theme - .mode == - "Dark"), - ), - const SizedBox(width: 25.0), - Text( - "Privacy Policy", - style: TextStyle( - //fontWeight: FontWeight.bold, - color: MihColors.getSecondaryColor( - MzansiInnovationHub.of(context)! - .theme - .mode == - "Dark"), - ), - ), - ], - ), - onTap: () { - WidgetsBinding.instance - .addPostFrameCallback((_) async { - context - .read() - .setToolIndex(1); - }); - context.goNamed( - "aboutMih", - extra: true, - ); - }, - ), - ListTile( - title: Row( - mainAxisSize: MainAxisSize.max, - children: [ - Icon( - Icons.design_services_rounded, - color: MihColors.getSecondaryColor( - MzansiInnovationHub.of(context)! - .theme - .mode == - "Dark"), - ), - const SizedBox(width: 25.0), - Text( - "Terms of Service", - style: TextStyle( - //fontWeight: FontWeight.bold, - color: MihColors.getSecondaryColor( - MzansiInnovationHub.of(context)! - .theme - .mode == - "Dark"), - ), - ), - ], - ), - onTap: () { - WidgetsBinding.instance - .addPostFrameCallback((_) async { - context - .read() - .setToolIndex(2); - }); - context.goNamed( - "aboutMih", - extra: true, - ); - }, - ), - ListTile( - title: Row( - mainAxisSize: MainAxisSize.max, - children: [ - Icon( - Icons.logout, - color: MihColors.getSecondaryColor( - MzansiInnovationHub.of(context)! - .theme - .mode == - "Dark"), - ), - const SizedBox(width: 25.0), - Text( - "Sign Out", - style: TextStyle( - //fontWeight: FontWeight.bold, - color: MihColors.getSecondaryColor( - MzansiInnovationHub.of(context)! - .theme - .mode == - "Dark"), - ), - ), - ], - ), - onTap: () async { - await SuperTokens.signOut( - completionHandler: (error) { - print(error); - }); - if (await SuperTokens.doesSessionExist() == - false) { - context.goNamed( - 'mihHome', - extra: true, - ); - // Navigator.of(context).pop(); - // Navigator.of(context).popAndPushNamed( - // '/', - // arguments: AuthArguments(true, false), - // ); - } - }, - ), - ], - ), + // IconButton( + // onPressed: () { + // setState(() { + // if (MzansiInnovationHub.of(context)?.theme.mode == "Dark") { + // //darkm = !darkm; + // MzansiInnovationHub.of(context)!.changeTheme(ThemeMode.light); + // //print("Dark Mode: $darkm"); + // } else { + // //darkm = !darkm; + // MzansiInnovationHub.of(context)!.changeTheme(ThemeMode.dark); + // //print("Dark Mode: $darkm"); + // } + // Navigator.of(context).popAndPushNamed('/'); + // }); + // }, + // icon: Icon( + // Icons.light_mode, + // color: MihColors.getPrimaryColor(MzansiInnovationHub.of(context)!.theme.mode == "Dark"), + // size: 35, + // ), + // ), ), ], - ), - Positioned( - top: 5, - right: 5, - width: 30, - height: 30, - child: InkWell( - onTap: () { - setState(() { - if (MzansiInnovationHub.of(context)?.theme.mode == - "Dark") { - //darkm = !darkm; - MzansiInnovationHub.of(context)! - .changeTheme(ThemeMode.light); - //print("Dark Mode: $darkm"); - } else { - //darkm = !darkm; - MzansiInnovationHub.of(context)! - .changeTheme(ThemeMode.dark); - //print("Dark Mode: $darkm"); - } - Navigator.of(context).pop(); - Navigator.of(context).popAndPushNamed( - '/', - arguments: AuthArguments(true, false), - ); - // Navigator.of(context).popAndPushNamed('/',); - }); - }, - child: Icon( - MihIcons.mihLogo, - color: MihColors.getPrimaryColor( - MzansiInnovationHub.of(context)!.theme.mode == - "Dark"), - ), - ), - // IconButton( - // onPressed: () { - // setState(() { - // if (MzansiInnovationHub.of(context)?.theme.mode == "Dark") { - // //darkm = !darkm; - // MzansiInnovationHub.of(context)!.changeTheme(ThemeMode.light); - // //print("Dark Mode: $darkm"); - // } else { - // //darkm = !darkm; - // MzansiInnovationHub.of(context)!.changeTheme(ThemeMode.dark); - // //print("Dark Mode: $darkm"); - // } - // Navigator.of(context).popAndPushNamed('/'); - // }); - // }, - // icon: Icon( - // Icons.light_mode, - // color: MihColors.getPrimaryColor(MzansiInnovationHub.of(context)!.theme.mode == "Dark"), - // size: 35, - // ), - // ), - ), - ], - ); - }, - ), - ), + ); + }, + ), + ), + ); + }, ); } } diff --git a/Frontend/lib/mih_packages/mih_home/mih_home.dart b/Frontend/lib/mih_packages/mih_home/mih_home.dart index 1e90ccb0..61022390 100644 --- a/Frontend/lib/mih_packages/mih_home/mih_home.dart +++ b/Frontend/lib/mih_packages/mih_home/mih_home.dart @@ -1,7 +1,8 @@ import 'package:go_router/go_router.dart'; import 'package:ken_logger/ken_logger.dart'; import 'package:mzansi_innovation_hub/main.dart'; -import 'package:mzansi_innovation_hub/mih_components/mih_objects/arguments.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_objects/business.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_objects/business_user.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_objects/user_consent.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_button.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package.dart'; @@ -13,22 +14,24 @@ import 'package:mzansi_innovation_hub/mih_components/mih_objects/app_user.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_window.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_scack_bar.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_loading_circle.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_providers/about_mih_provider.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_providers/mzansi_profile_provider.dart'; import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart'; import 'package:mzansi_innovation_hub/mih_config/mih_env.dart'; import 'package:mzansi_innovation_hub/mih_packages/mih_home/components/mih_app_drawer.dart'; -import 'package:mzansi_innovation_hub/mih_packages/mih_home/mih_home_error.dart'; import 'package:mzansi_innovation_hub/mih_packages/mih_home/package_tools/mih_business_home.dart'; import 'package:mzansi_innovation_hub/mih_packages/mih_home/package_tools/mih_personal_home.dart'; import 'package:flutter/material.dart'; -import 'package:mzansi_innovation_hub/mih_services/mih_service_calls.dart'; +import 'package:mzansi_innovation_hub/mih_services/mih_business_details_services.dart'; +import 'package:mzansi_innovation_hub/mih_services/mih_file_services.dart'; +import 'package:mzansi_innovation_hub/mih_services/mih_my_business_user_services.dart'; import 'package:mzansi_innovation_hub/mih_services/mih_user_consent_services.dart'; +import 'package:mzansi_innovation_hub/mih_services/mih_user_services.dart'; +import 'package:provider/provider.dart'; -// ignore: must_be_immutable class MihHome extends StatefulWidget { - final bool personalSelected; const MihHome({ super.key, - required this.personalSelected, }); @override @@ -38,12 +41,49 @@ class MihHome extends StatefulWidget { class _MihHomeState extends State { final proPicController = TextEditingController(); late int _selcetedIndex; - late bool _personalSelected; - late Future profileData; - late Future futureUserConsent; - bool showUserConsent = false; + late bool _personalHome; DateTime latestPrivacyPolicyDate = DateTime.parse("2024-12-01"); DateTime latestTermOfServiceDate = DateTime.parse("2024-12-01"); + bool _isLoadingInitialData = true; + + Future _loadInitialData() async { + // Note: getUserData sets user and userProfilePicUrl in the provider + await getUserData(); + // Note: getUserConsentStatus sets userConsent in the provider + await getUserConsentStatus(); + await getBusinessData(); + // 2. Set state after all data is loaded + if (mounted) { + setState(() { + _isLoadingInitialData = false; + }); + } + } + + Future getBusinessData() async { + Business? business = context.read().business; + AppUser? user = context.read().user; + String logoUrl; + String signatureUrl; + if (business == null && user!.type == "business") { + // Get Business + await MihBusinessDetailsServices().getBusinessDetailsByUser(context); + logoUrl = await MihFileApi.getMinioFileUrl( + context.read().business!.logo_path, + context, + ); + context.read().setBusinessProfilePicUrl(logoUrl); + // Get Business User + await MihMyBusinessUserServices().getBusinessUser(context); + signatureUrl = await MihFileApi.getMinioFileUrl( + context.read().businessUser!.sig_path, + context, + ); + context + .read() + .setBusinessUserSignatureUrl(signatureUrl); + } + } bool showPolicyWindow(UserConsent? userConsent) { if (userConsent == null) { @@ -60,20 +100,19 @@ class _MihHomeState extends State { } } - void createOrUpdateAccpetance(UserConsent? userConsent, String app_id) { + void createOrUpdateAccpetance(MzansiProfileProvider mzansiProfileProvider) { + UserConsent? userConsent = mzansiProfileProvider.userConsent; userConsent != null ? MihUserConsentServices() .updateUserConsentStatus( - app_id, DateTime.now().toIso8601String(), DateTime.now().toIso8601String(), + mzansiProfileProvider, + context, ) .then((value) { if (value == 200) { - // setState(() { - // showUserConsent = false; - // }); - context.goNamed("mihHome", extra: false); + context.goNamed("mihHome"); ScaffoldMessenger.of(context).showSnackBar( MihSnackBar( child: Text("Thank you for accepting our Policies"), @@ -89,16 +128,14 @@ class _MihHomeState extends State { }) : MihUserConsentServices() .insertUserConsentStatus( - app_id, DateTime.now().toIso8601String(), DateTime.now().toIso8601String(), + mzansiProfileProvider, + context, ) .then((value) { if (value == 201) { - // setState(() { - // showUserConsent = false; - // }); - context.goNamed("mihHome", extra: false); + context.goNamed("mihHome"); ScaffoldMessenger.of(context).showSnackBar( MihSnackBar( child: Text("Thank you for accepting our Policies"), @@ -114,6 +151,22 @@ class _MihHomeState extends State { }); } + Future getUserData() async { + String url; + await MihUserServices().getUserDetails( + context, + ); + url = await MihFileApi.getMinioFileUrl( + context.read().user!.pro_pic_path, + context, + ); + context.read().setUserProfilePicUrl(url); + } + + Future getUserConsentStatus() async { + await MihUserConsentServices().getUserConsentStatus(context); + } + @override void dispose() { super.dispose(); @@ -122,18 +175,15 @@ class _MihHomeState extends State { @override void initState() { super.initState(); - profileData = MIHApiCalls().getProfile(10, context); - futureUserConsent = MihUserConsentServices().getUserConsentStatus(); - if (widget.personalSelected == true) { - setState(() { - _selcetedIndex = 0; - _personalSelected = true; - }); + WidgetsBinding.instance.addPostFrameCallback((_) async { + _loadInitialData(); + }); + if (context.read().personalHome == true) { + _selcetedIndex = 0; + _personalHome = true; } else { - setState(() { - _selcetedIndex = 1; - _personalSelected = false; - }); + _selcetedIndex = 1; + _personalHome = false; } } @@ -147,278 +197,239 @@ class _MihHomeState extends State { @override Widget build(BuildContext context) { - return FutureBuilder( - future: profileData, - builder: (context, asyncSnapshot) { - if (asyncSnapshot.connectionState == ConnectionState.waiting) { + return Consumer( + builder: (BuildContext context, + MzansiProfileProvider mzansiProfileProvider, Widget? child) { + if (_isLoadingInitialData) { return Scaffold( - body: const Mihloadingcircle( - // message: "Fetching your Data...", - ), + body: Center( + child: Mihloadingcircle(), + ), ); - } else if (asyncSnapshot.connectionState == ConnectionState.done && - asyncSnapshot.hasData) { - return Stack( - children: [ - MihPackage( - appActionButton: getAction(asyncSnapshot.data!.profilePicUrl), - appTools: getTools( - asyncSnapshot.data!.signedInUser.type != "personal"), - appBody: getToolBody(asyncSnapshot.data!), - appToolTitles: getToolTitle(), - actionDrawer: getActionDrawer( - asyncSnapshot.data!.signedInUser, - asyncSnapshot.data!.profilePicUrl, - ), - selectedbodyIndex: _selcetedIndex, - onIndexChange: (newValue) { - if (_selcetedIndex == 0) { - setState(() { - _selcetedIndex = newValue; - _personalSelected = true; - }); - } else { - setState(() { - _selcetedIndex = newValue; - _personalSelected = false; - }); - } - }, - ), - FutureBuilder( - future: futureUserConsent, - builder: (context, asyncSnapshotUserConsent) { - if (asyncSnapshotUserConsent.connectionState == - ConnectionState.waiting) { - showUserConsent = false; - } else if (asyncSnapshotUserConsent.connectionState == - ConnectionState.done && - asyncSnapshotUserConsent.hasData) { - showUserConsent = - showPolicyWindow(asyncSnapshotUserConsent.data); - } else if (asyncSnapshotUserConsent.connectionState == - ConnectionState.done && - !asyncSnapshotUserConsent.hasData) { - showUserConsent = true; - } else { - showUserConsent = false; - } - return Visibility( - visible: showUserConsent, - child: Container( - color: Colors.black.withValues(alpha: 0.5), - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - mainAxisSize: MainAxisSize.max, - children: [ - MihPackageWindow( - fullscreen: false, - windowTitle: - "Privacy Policy & Terms Of Service Alert!", - onWindowTapClose: () { - showDialog( - context: context, - builder: (context) { - return MihPackageAlert( - alertIcon: Icon( - Icons.warning_amber_rounded, - size: 100, - color: MihColors.getRedColor( - MzansiInnovationHub.of(context)! - .theme - .mode == - "Dark", - ), - ), - alertTitle: - "Oops, Looks like you missed a step!", - alertBody: Text( - "We're excited for you to keep using the MIH app! Before you do, please take a moment to accept our Privacy Policy and Terms of Service. Thanks for helping us keep your experience great!", - textAlign: TextAlign.center, - style: TextStyle( - color: MihColors.getSecondaryColor( - MzansiInnovationHub.of(context)! - .theme - .mode == - "Dark", - ), - fontSize: 15, - fontWeight: FontWeight.normal, - ), - ), - alertColour: MihColors.getRedColor( - MzansiInnovationHub.of(context)! - .theme - .mode == - "Dark", - ), - ); - }); - }, - windowBody: Column( - children: [ - Icon( - Icons.policy, - size: 150, + } + // bool showConsentWindow = + // showPolicyWindow(mzansiProfileProvider.userConsent); + return Stack( + children: [ + MihPackage( + appActionButton: + getAction(mzansiProfileProvider.userProfilePicUrl as String), + appTools: + getTools(mzansiProfileProvider.user!.type != "personal"), + appBody: getToolBody(), + appToolTitles: getToolTitle(), + actionDrawer: getActionDrawer(), + selectedbodyIndex: _selcetedIndex, + onIndexChange: (newValue) { + if (_selcetedIndex == 0) { + setState(() { + _selcetedIndex = newValue; + _personalHome = true; + }); + } else { + setState(() { + _selcetedIndex = newValue; + _personalHome = false; + }); + } + }, + ), + Visibility( + visible: showPolicyWindow(mzansiProfileProvider.userConsent), + child: Container( + color: Colors.black.withValues(alpha: 0.5), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + mainAxisSize: MainAxisSize.max, + children: [ + MihPackageWindow( + fullscreen: false, + windowTitle: "Privacy Policy & Terms Of Service Alert!", + onWindowTapClose: () { + showDialog( + context: context, + builder: (context) { + return MihPackageAlert( + alertIcon: Icon( + Icons.warning_amber_rounded, + size: 100, + color: MihColors.getRedColor( + MzansiInnovationHub.of(context)! + .theme + .mode == + "Dark", + ), + ), + alertTitle: + "Oops, Looks like you missed a step!", + alertBody: Text( + "We're excited for you to keep using the MIH app! Before you do, please take a moment to accept our Privacy Policy and Terms of Service. Thanks for helping us keep your experience great!", + textAlign: TextAlign.center, + style: TextStyle( color: MihColors.getSecondaryColor( MzansiInnovationHub.of(context)! .theme .mode == "Dark", ), + fontSize: 15, + fontWeight: FontWeight.normal, ), - const SizedBox(height: 10), - Text( - "Welcome to the MIH App", - textAlign: TextAlign.center, + ), + alertColour: MihColors.getRedColor( + MzansiInnovationHub.of(context)!.theme.mode == + "Dark", + ), + ); + }); + }, + windowBody: Column( + children: [ + Icon( + Icons.policy, + size: 150, + color: MihColors.getSecondaryColor( + MzansiInnovationHub.of(context)!.theme.mode == + "Dark", + ), + ), + const SizedBox(height: 10), + Text( + "Welcome to the MIH App", + textAlign: TextAlign.center, + style: TextStyle( + color: MihColors.getSecondaryColor( + MzansiInnovationHub.of(context)!.theme.mode == + "Dark", + ), + fontSize: 30, + fontWeight: FontWeight.bold, + ), + ), + const SizedBox(height: 10), + Text( + "To keep using the MIH app, please take a moment to review and accept our Policies. Our agreements helps us keep things running smoothly and securely.", + textAlign: TextAlign.center, + style: TextStyle( + color: MihColors.getSecondaryColor( + MzansiInnovationHub.of(context)!.theme.mode == + "Dark", + ), + fontSize: 15, + fontWeight: FontWeight.normal, + ), + ), + const SizedBox(height: 20), + Center( + child: Wrap( + alignment: WrapAlignment.center, + spacing: 10, + runSpacing: 10, + children: [ + MihButton( + onPressed: () { + WidgetsBinding.instance + .addPostFrameCallback((_) async { + context + .read() + .setToolIndex(1); + }); + context.goNamed("aboutMih", + extra: + mzansiProfileProvider.personalHome); + }, + buttonColor: MihColors.getOrangeColor( + MzansiInnovationHub.of(context)! + .theme + .mode == + "Dark"), + elevation: 10, + width: 300, + child: Text( + "Privacy Policy", style: TextStyle( - color: MihColors.getSecondaryColor( - MzansiInnovationHub.of(context)! - .theme - .mode == - "Dark", - ), - fontSize: 30, + color: MihColors.getPrimaryColor( + MzansiInnovationHub.of(context)! + .theme + .mode == + "Dark"), + fontSize: 20, fontWeight: FontWeight.bold, ), ), - const SizedBox(height: 10), - Text( - "To keep using the MIH app, please take a moment to review and accept our Policies. Our agreements helps us keep things running smoothly and securely.", - textAlign: TextAlign.center, + ), + MihButton( + onPressed: () { + WidgetsBinding.instance + .addPostFrameCallback((_) async { + context + .read() + .setToolIndex(2); + }); + context.goNamed("aboutMih", + extra: + mzansiProfileProvider.personalHome); + }, + buttonColor: MihColors.getYellowColor( + MzansiInnovationHub.of(context)! + .theme + .mode == + "Dark"), + elevation: 10, + width: 300, + child: Text( + "Terms of Service", style: TextStyle( - color: MihColors.getSecondaryColor( - MzansiInnovationHub.of(context)! - .theme - .mode == - "Dark", - ), - fontSize: 15, - fontWeight: FontWeight.normal, + color: MihColors.getPrimaryColor( + MzansiInnovationHub.of(context)! + .theme + .mode == + "Dark"), + fontSize: 20, + fontWeight: FontWeight.bold, ), ), - const SizedBox(height: 20), - Center( - child: Wrap( - alignment: WrapAlignment.center, - spacing: 10, - runSpacing: 10, - children: [ - MihButton( - onPressed: () { - context.goNamed( - "aboutMih", - extra: AboutArguments( - widget.personalSelected, - 1, - ), - ); - }, - buttonColor: MihColors.getOrangeColor( - MzansiInnovationHub.of(context)! - .theme - .mode == - "Dark"), - elevation: 10, - width: 300, - child: Text( - "Privacy Policy", - style: TextStyle( - color: MihColors.getPrimaryColor( - MzansiInnovationHub.of( - context)! - .theme - .mode == - "Dark"), - fontSize: 20, - fontWeight: FontWeight.bold, - ), - ), - ), - MihButton( - onPressed: () { - context.goNamed( - "aboutMih", - extra: AboutArguments( - widget.personalSelected, - 2, - ), - ); - }, - buttonColor: MihColors.getYellowColor( - MzansiInnovationHub.of(context)! - .theme - .mode == - "Dark"), - elevation: 10, - width: 300, - child: Text( - "Terms of Service", - style: TextStyle( - color: MihColors.getPrimaryColor( - MzansiInnovationHub.of( - context)! - .theme - .mode == - "Dark"), - fontSize: 20, - fontWeight: FontWeight.bold, - ), - ), - ), - MihButton( - onPressed: () { - DateTime now = DateTime.now(); - KenLogger.success( - "Date Time Now: $now"); - createOrUpdateAccpetance( - asyncSnapshotUserConsent.data, - asyncSnapshot - .data!.signedInUser.app_id, - ); - }, - buttonColor: MihColors.getGreenColor( - MzansiInnovationHub.of(context)! - .theme - .mode == - "Dark"), - elevation: 10, - width: 300, - child: Text( - "Accept", - style: TextStyle( - color: MihColors.getPrimaryColor( - MzansiInnovationHub.of( - context)! - .theme - .mode == - "Dark"), - fontSize: 20, - fontWeight: FontWeight.bold, - ), - ), - ), - ], + ), + MihButton( + onPressed: () { + DateTime now = DateTime.now(); + KenLogger.success("Date Time Now: $now"); + createOrUpdateAccpetance( + mzansiProfileProvider); + }, + buttonColor: MihColors.getGreenColor( + MzansiInnovationHub.of(context)! + .theme + .mode == + "Dark"), + elevation: 10, + width: 300, + child: Text( + "Accept", + style: TextStyle( + color: MihColors.getPrimaryColor( + MzansiInnovationHub.of(context)! + .theme + .mode == + "Dark"), + fontSize: 20, + fontWeight: FontWeight.bold, ), ), - const SizedBox(height: 10), - ], - ), + ), + ], ), - ], - ), + ), + const SizedBox(height: 10), + ], ), - ); - }), - ], - ); - } else { - return MihHomeError( - errorMessage: asyncSnapshot.hasError - ? asyncSnapshot.error.toString() - : "An unknown error occurred", - ); - } + ), + ], + ), + ), + ), + ], + ); }, ); } @@ -464,7 +475,11 @@ class _MihHomeState extends State { }); } - MIHAppDrawer getActionDrawer(AppUser signedInUser, String proPicUrl) { + MIHAppDrawer getActionDrawer() { + AppUser signedInUser = + context.watch().user as AppUser; + String proPicUrl = + context.watch().userProfilePicUrl ?? ""; return MIHAppDrawer( signedInUser: signedInUser, propicFile: proPicUrl != "" ? NetworkImage(proPicUrl) : null, @@ -476,14 +491,14 @@ class _MihHomeState extends State { temp[const Icon(Icons.person)] = () { setState(() { _selcetedIndex = 0; - _personalSelected = true; + _personalHome = true; }); }; if (isBusinessUser) { temp[const Icon(Icons.business_center)] = () { setState(() { _selcetedIndex = 1; - _personalSelected = false; + _personalHome = false; }); }; } @@ -493,29 +508,35 @@ class _MihHomeState extends State { ); } - List getToolBody(HomeArguments profData) { + List getToolBody() { List toolBodies = []; + AppUser? user = context.watch().user; + Business? business = context.watch().business; + BusinessUser? businessUser = + context.watch().businessUser; + String userProfilePictureUrl = + context.watch().userProfilePicUrl ?? ""; toolBodies.add( MihPersonalHome( - signedInUser: profData.signedInUser, - personalSelected: _personalSelected, - business: profData.business, - businessUser: profData.businessUser, - propicFile: profData.profilePicUrl != "" - ? NetworkImage(profData.profilePicUrl) + signedInUser: user!, + personalSelected: _personalHome, + business: business, + businessUser: businessUser, + propicFile: userProfilePictureUrl != "" + ? NetworkImage(userProfilePictureUrl) : null, isDevActive: AppEnviroment.getEnv() == "Dev", - isUserNew: profData.signedInUser.username == "", + isUserNew: user.username == "", ), ); - if (profData.signedInUser.type != "personal") { + if (user.type != "personal") { toolBodies.add( MihBusinessHome( - signedInUser: profData.signedInUser, - personalSelected: _personalSelected, - businessUser: profData.businessUser, - business: profData.business, - isBusinessUserNew: profData.businessUser == null, + signedInUser: user, + personalSelected: _personalHome, + businessUser: businessUser, + business: business, + isBusinessUserNew: businessUser == null, ), ); } diff --git a/Frontend/lib/mih_packages/mih_home/package_tools/mih_personal_home.dart b/Frontend/lib/mih_packages/mih_home/package_tools/mih_personal_home.dart index 8c17cf56..79120d66 100644 --- a/Frontend/lib/mih_packages/mih_home/package_tools/mih_personal_home.dart +++ b/Frontend/lib/mih_packages/mih_home/package_tools/mih_personal_home.dart @@ -14,6 +14,7 @@ import 'package:mzansi_innovation_hub/mih_packages/about_mih/package_tile/about_ import 'package:mzansi_innovation_hub/mih_packages/access_review/package_tile/mih_access_tile.dart'; import 'package:mzansi_innovation_hub/mih_packages/calculator/package_tiles/mih_calculator_tile.dart'; import 'package:mzansi_innovation_hub/mih_packages/calendar/package_tiles/mzansi_calendar_tile.dart'; +import 'package:mzansi_innovation_hub/mih_packages/mine_sweeper/package_tiles/mih_mine_sweeper_tile.dart'; import 'package:mzansi_innovation_hub/mih_packages/mzansi_ai/package_tiles/mzansi_ai_tile.dart'; import 'package:mzansi_innovation_hub/mih_packages/mzansi_directory/package_tiles/mzansi_directory_tile.dart'; import 'package:mzansi_innovation_hub/mih_packages/mzansi_profile/personal_profile/package_tiles/mzansi_profile_tile.dart'; @@ -153,6 +154,13 @@ class _MihPersonalHomeState extends State packageSize: packageSize, ) }); + //=============== Mine Sweeper =============== + temp.add({ + "Mine Sweeper": MihMineSweeperTile( + personalSelected: widget.personalSelected, + packageSize: packageSize, + ) + }); //=============== MIH Access =============== temp.add({ "MIH Access": MihAccessTile( diff --git a/Frontend/lib/mih_packages/mzansi_profile/business_profile/builders/build_employee_list.dart b/Frontend/lib/mih_packages/mzansi_profile/business_profile/builders/build_employee_list.dart index edc2b570..d4268a57 100644 --- a/Frontend/lib/mih_packages/mzansi_profile/business_profile/builders/build_employee_list.dart +++ b/Frontend/lib/mih_packages/mzansi_profile/business_profile/builders/build_employee_list.dart @@ -4,6 +4,7 @@ import 'package:flutter_speed_dial/flutter_speed_dial.dart'; import 'package:go_router/go_router.dart'; import 'package:mzansi_innovation_hub/main.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_alert.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_providers/mzansi_profile_provider.dart'; import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart'; import 'package:mzansi_innovation_hub/mih_services/mih_alert_services.dart'; import 'package:mzansi_innovation_hub/mih_services/mih_validation_services.dart'; @@ -16,19 +17,17 @@ import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_del import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_error_message.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_loading_circle.dart'; import 'package:mzansi_innovation_hub/mih_config/mih_env.dart'; -import 'package:mzansi_innovation_hub/mih_components/mih_objects/arguments.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_objects/business_employee.dart'; import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; import 'package:supertokens_flutter/http.dart' as http; class BuildEmployeeList extends StatefulWidget { final List employees; - final BusinessArguments arguments; const BuildEmployeeList({ super.key, required this.employees, - required this.arguments, }); @override @@ -369,36 +368,41 @@ class _BuildEmployeeListState extends State { @override Widget build(BuildContext context) { double screenWidth = MediaQuery.of(context).size.width; - return ListView.separated( - shrinkWrap: true, - physics: const NeverScrollableScrollPhysics(), - separatorBuilder: (BuildContext context, index) { - return Divider( - color: MihColors.getSecondaryColor( - MzansiInnovationHub.of(context)!.theme.mode == "Dark"), - ); - }, - itemCount: widget.employees.length, - itemBuilder: (context, index) { - //final patient = widget.patients[index].id_no.contains(widget.searchString); - //print(index); - var isMe = ""; - if (widget.arguments.signedInUser.app_id == - widget.employees[index].app_id) { - isMe = "(You)"; - } - return ListTile( - title: Text( - "${widget.employees[index].fname} ${widget.employees[index].lname} - ${widget.employees[index].title} $isMe"), - subtitle: Text( - "${widget.employees[index].username}\n${widget.employees[index].email}\nAccess: ${widget.employees[index].access}", - style: TextStyle( + return Consumer( + builder: (BuildContext context, + MzansiProfileProvider mzansiProfileProvider, Widget? child) { + return ListView.separated( + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + separatorBuilder: (BuildContext context, index) { + return Divider( color: MihColors.getSecondaryColor( MzansiInnovationHub.of(context)!.theme.mode == "Dark"), - ), - ), - onTap: () { - updateEmployeePopUp(index, screenWidth); + ); + }, + itemCount: widget.employees.length, + itemBuilder: (context, index) { + //final patient = widget.patients[index].id_no.contains(widget.searchString); + //print(index); + var isMe = ""; + if (mzansiProfileProvider.user!.app_id == + widget.employees[index].app_id) { + isMe = "(You)"; + } + return ListTile( + title: Text( + "${widget.employees[index].fname} ${widget.employees[index].lname} - ${widget.employees[index].title} $isMe"), + subtitle: Text( + "${widget.employees[index].username}\n${widget.employees[index].email}\nAccess: ${widget.employees[index].access}", + style: TextStyle( + color: MihColors.getSecondaryColor( + MzansiInnovationHub.of(context)!.theme.mode == "Dark"), + ), + ), + onTap: () { + updateEmployeePopUp(index, screenWidth); + }, + ); }, ); }, diff --git a/Frontend/lib/mih_packages/mzansi_profile/business_profile/components/mih_update_business_details_window.dart b/Frontend/lib/mih_packages/mzansi_profile/business_profile/components/mih_update_business_details_window.dart new file mode 100644 index 00000000..a5cef9de --- /dev/null +++ b/Frontend/lib/mih_packages/mzansi_profile/business_profile/components/mih_update_business_details_window.dart @@ -0,0 +1,705 @@ +import 'package:country_code_picker/country_code_picker.dart'; +import 'package:file_picker/file_picker.dart'; +import 'package:flutter/material.dart'; +import 'package:go_router/go_router.dart'; +import 'package:ken_logger/ken_logger.dart'; +import 'package:mzansi_innovation_hub/main.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_button.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_circle_avatar.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_form.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_alert.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_window.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_single_child_scroll.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_text_form_field.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_error_message.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_loading_circle.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_providers/mzansi_profile_provider.dart'; +import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart'; +import 'package:mzansi_innovation_hub/mih_config/mih_env.dart'; +import 'package:mzansi_innovation_hub/mih_services/mih_alert_services.dart'; +import 'package:mzansi_innovation_hub/mih_services/mih_business_details_services.dart'; +import 'package:mzansi_innovation_hub/mih_services/mih_file_services.dart'; +import 'package:mzansi_innovation_hub/mih_services/mih_location_services.dart'; +import 'package:mzansi_innovation_hub/mih_services/mih_validation_services.dart'; +import 'package:provider/provider.dart'; + +class MihUpdateBusinessDetailsWindow extends StatefulWidget { + final double width; + const MihUpdateBusinessDetailsWindow({ + super.key, + required this.width, + }); + + @override + State createState() => + _MihUpdateBusinessDetailsWindowState(); +} + +class _MihUpdateBusinessDetailsWindowState + extends State { + final _formKey = GlobalKey(); + PlatformFile? newSelectedLogoPic; + final fileNameController = TextEditingController(); + final regController = TextEditingController(); + final nameController = TextEditingController(); + final typeController = TextEditingController(); + final practiceNoController = TextEditingController(); + final vatNoController = TextEditingController(); + final countryCodeController = TextEditingController(); + final contactController = TextEditingController(); + final emailController = TextEditingController(); + final locationController = TextEditingController(); + final websiteController = TextEditingController(); + final ratingController = TextEditingController(); + final missionVisionController = TextEditingController(); + final ValueNotifier _counter = ValueNotifier(0); + late String env; + + void setContactNumberControllers( + MzansiProfileProvider mzansiProfileProvider) { + if (mzansiProfileProvider.business!.contact_no[0] == "+") { + List contactDetails = + mzansiProfileProvider.business!.contact_no.split("-"); + setState(() { + countryCodeController.text = contactDetails[0]; + contactController.text = contactDetails[1]; + }); + } else { + setState(() { + countryCodeController.text = "+27"; + contactController.text = mzansiProfileProvider.business!.contact_no; + }); + } + } + + void setControllers() { + MzansiProfileProvider mzansiProfileProvider = + context.read(); + setState(() { + fileNameController.text = + mzansiProfileProvider.business!.logo_path.split("/").last; + regController.text = mzansiProfileProvider.business!.registration_no; + nameController.text = mzansiProfileProvider.business!.Name; + typeController.text = mzansiProfileProvider.business!.type; + practiceNoController.text = mzansiProfileProvider.business!.practice_no; + vatNoController.text = mzansiProfileProvider.business!.vat_no; + emailController.text = mzansiProfileProvider.business!.bus_email; + locationController.text = mzansiProfileProvider.business!.gps_location; + websiteController.text = mzansiProfileProvider.business!.website; + ratingController.text = mzansiProfileProvider.business!.rating; + missionVisionController.text = + mzansiProfileProvider.business!.mission_vision; + }); + setContactNumberControllers(mzansiProfileProvider); + if (AppEnviroment.getEnv() == "Prod") { + env = "Prod"; + } else { + env = "Dev"; + } + } + + Color getMissionVisionLimitColor(int limit) { + if (_counter.value <= limit) { + return MihColors.getSecondaryColor( + MzansiInnovationHub.of(context)!.theme.mode == "Dark"); + } else { + return MihColors.getRedColor( + MzansiInnovationHub.of(context)!.theme.mode == "Dark"); + } + } + + void _updateMissionVisionCounter() { + // New function name + // No need for setState since you are using a ValueNotifier for _counter + _counter.value = missionVisionController.text.characters.length; + } + + String getNumberWithCountryCode() { + String numberWithoutBeginingZero = ""; + if (contactController.text[0] == "0") { + numberWithoutBeginingZero = contactController.text + .replaceAll(" ", "") + .substring(1, contactController.text.length); + } else { + numberWithoutBeginingZero = contactController.text.replaceAll("-", " "); + } + return "${countryCodeController.text}-$numberWithoutBeginingZero"; + } + + bool isFormFilled() { + if (typeController.text.isEmpty) { + return false; + } else { + return true; + } + } + + void successPopUp(String message, bool stayOnPersonalSide) { + showDialog( + context: context, + builder: (context) { + return MihPackageAlert( + alertIcon: Icon( + Icons.check_circle_outline_rounded, + size: 150, + color: MihColors.getGreenColor( + MzansiInnovationHub.of(context)!.theme.mode == "Dark"), + ), + alertTitle: "Successfully Updated Profile", + alertBody: Column( + children: [ + Text( + message, + style: TextStyle( + color: MihColors.getSecondaryColor( + MzansiInnovationHub.of(context)!.theme.mode == "Dark"), + fontSize: 15, + fontWeight: FontWeight.bold, + ), + ), + const SizedBox(height: 25), + Center( + child: MihButton( + onPressed: () { + context.pop(); + }, + buttonColor: MihColors.getGreenColor( + MzansiInnovationHub.of(context)!.theme.mode == "Dark"), + elevation: 10, + width: 300, + child: Text( + "Dismiss", + style: TextStyle( + color: MihColors.getPrimaryColor( + MzansiInnovationHub.of(context)!.theme.mode == + "Dark"), + fontSize: 20, + fontWeight: FontWeight.bold, + ), + ), + ), + ) + ], + ), + alertColour: MihColors.getGreenColor( + MzansiInnovationHub.of(context)!.theme.mode == "Dark"), + ); + // return MIHSuccessMessage( + // successType: "Success", + // successMessage: message, + // ); + }, + ); + } + + Future uploadFile(MzansiProfileProvider mzansiProfileProvider) async { + if (newSelectedLogoPic != null) { + int uploadStatusCode = 0; + uploadStatusCode = await MihFileApi.uploadFile( + mzansiProfileProvider.business!.business_id, + env, + "business_files", + newSelectedLogoPic!, + context, + ); + if (uploadStatusCode == 200) { + int deleteStatusCode = 0; + deleteStatusCode = await MihFileApi.deleteFile( + mzansiProfileProvider.business!.logo_path.split("/").first, + env, + "business_files", + mzansiProfileProvider.business!.logo_path.split("/").last, + context, + ); + if (deleteStatusCode == 200) { + return true; + } else { + return false; + } + } else { + return false; + } + } else { + return true; // No file selected, so no upload needed + } + } + + Future submitForm(MzansiProfileProvider mzansiProfileProvider) async { + KenLogger.success("Start Submit Form"); + if (isFormFilled()) { + KenLogger.success("Form Filled"); + KenLogger.success("Start File Upload"); + bool successfullyUploadedFile = await uploadFile(mzansiProfileProvider); + KenLogger.success( + "File Upload Complete: outcome $successfullyUploadedFile"); + if (!mounted) return; + KenLogger.success("is mounted"); + if (successfullyUploadedFile) { + KenLogger.success("Start Details Update"); + int statusCode = 0; + statusCode = await MihBusinessDetailsServices().updateBusinessDetailsV2( + mzansiProfileProvider.business!.business_id, + nameController.text, + typeController.text, + regController.text, + practiceNoController.text, + vatNoController.text, + emailController.text, + getNumberWithCountryCode(), + // contactController.text, + locationController.text, + fileNameController.text, + websiteController.text, + ratingController.text.isEmpty ? "0" : ratingController.text, + missionVisionController.text, + mzansiProfileProvider, + context, + ); + KenLogger.success("Details Update Complete: status code $statusCode"); + if (!mounted) return; + KenLogger.success("is mounted"); + if (statusCode == 200) { + KenLogger.success("Start Success Message"); + //You left of here + String message = "Your information has been updated successfully!"; + context.pop(); + successPopUp(message, false); + // File uploaded successfully + } else { + context.pop(); + // File upload failed + showDialog( + context: context, + builder: (context) { + return MihPackageAlert( + alertIcon: Icon( + Icons.warning_rounded, + color: MihColors.getRedColor( + MzansiInnovationHub.of(context)!.theme.mode == "Dark"), + ), + alertTitle: "Error Updating Business Details", + alertBody: Column( + children: [ + Text( + "An error occurred while updating the business details. Please check internet connection and try again.", + style: TextStyle( + color: MihColors.getSecondaryColor( + MzansiInnovationHub.of(context)!.theme.mode == + "Dark"), + ), + ), + ], + ), + alertColour: MihColors.getRedColor( + MzansiInnovationHub.of(context)!.theme.mode == "Dark"), + ); + }, + ); + } + } else { + context.pop(); + if (!mounted) return; + showDialog( + context: context, + builder: (context) { + return const MIHErrorMessage(errorType: "Internet Connection"); + }, + ); + } + } else { + showDialog( + context: context, + builder: (context) { + return const MIHErrorMessage(errorType: "Input Error"); + }, + ); + } + } + + @override + void initState() { + super.initState(); + setControllers(); + missionVisionController.addListener(_updateMissionVisionCounter); + } + + @override + Widget build(BuildContext context) { + return Consumer( + builder: (BuildContext context, + MzansiProfileProvider mzansiProfileProvider, Widget? child) { + return MihPackageWindow( + fullscreen: false, + windowTitle: 'Edit Profile', + onWindowTapClose: () { + context.pop(); + }, + windowBody: MihSingleChildScroll( + child: Padding( + padding: + MzansiInnovationHub.of(context)!.theme.screenType == "desktop" + ? EdgeInsets.symmetric(horizontal: widget.width * 0.05) + : EdgeInsets.symmetric(horizontal: widget.width * 0), + child: Column( + children: [ + MihForm( + formKey: _formKey, + formFields: [ + Center( + child: MihCircleAvatar( + imageFile: newSelectedLogoPic != null + ? MemoryImage(newSelectedLogoPic!.bytes!) + : mzansiProfileProvider.businessProfilePicture, + width: 150, + editable: true, + fileNameController: fileNameController, + userSelectedfile: newSelectedLogoPic, + frameColor: MihColors.getSecondaryColor( + MzansiInnovationHub.of(context)!.theme.mode == + "Dark"), + backgroundColor: MihColors.getPrimaryColor( + MzansiInnovationHub.of(context)!.theme.mode == + "Dark"), + onChange: (selectedfile) { + setState(() { + newSelectedLogoPic = selectedfile; + }); + }, + ), + ), + Visibility( + visible: false, + child: MihTextFormField( + fillColor: MihColors.getSecondaryColor( + MzansiInnovationHub.of(context)!.theme.mode == + "Dark"), + inputColor: MihColors.getPrimaryColor( + MzansiInnovationHub.of(context)!.theme.mode == + "Dark"), + controller: fileNameController, + multiLineInput: false, + requiredText: true, + readOnly: true, + hintText: "Selected File Name", + ), + ), + const SizedBox(height: 20), + MihTextFormField( + fillColor: MihColors.getSecondaryColor( + MzansiInnovationHub.of(context)!.theme.mode == + "Dark"), + inputColor: MihColors.getPrimaryColor( + MzansiInnovationHub.of(context)!.theme.mode == + "Dark"), + controller: nameController, + multiLineInput: false, + requiredText: true, + hintText: "Business Name", + validator: (value) { + return MihValidationServices().isEmpty(value); + }, + ), + const SizedBox(height: 10), + MihTextFormField( + fillColor: MihColors.getSecondaryColor( + MzansiInnovationHub.of(context)!.theme.mode == + "Dark"), + inputColor: MihColors.getPrimaryColor( + MzansiInnovationHub.of(context)!.theme.mode == + "Dark"), + controller: typeController, + multiLineInput: false, + requiredText: true, + hintText: "Business Type", + validator: (value) { + return MihValidationServices() + .validateNoSpecialChars(value); + }, + ), + const SizedBox(height: 10), + MihTextFormField( + fillColor: MihColors.getSecondaryColor( + MzansiInnovationHub.of(context)!.theme.mode == + "Dark"), + inputColor: MihColors.getPrimaryColor( + MzansiInnovationHub.of(context)!.theme.mode == + "Dark"), + controller: emailController, + multiLineInput: false, + requiredText: true, + hintText: "Business Email", + validator: (value) { + return MihValidationServices().validateEmail(value); + }, + ), + const SizedBox(height: 10), + Container( + width: 300, + alignment: Alignment.topLeft, + child: const Text( + "Contact Number:", + style: TextStyle( + fontSize: 18, + fontWeight: FontWeight.bold, + ), + ), + ), + Row( + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + CountryCodePicker( + padding: EdgeInsetsGeometry.all(0), + onChanged: (selectedCode) { + setState(() { + countryCodeController.text = + selectedCode.toString(); + }); + debugPrint( + "Selected Country Code: ${countryCodeController.text}"); + }, + initialSelection: countryCodeController.text, + showDropDownButton: false, + pickerStyle: PickerStyle.bottomSheet, + dialogBackgroundColor: MihColors.getPrimaryColor( + MzansiInnovationHub.of(context)!.theme.mode == + "Dark"), + barrierColor: MihColors.getPrimaryColor( + MzansiInnovationHub.of(context)!.theme.mode == + "Dark"), + ), + Expanded( + child: MihTextFormField( + fillColor: MihColors.getSecondaryColor( + MzansiInnovationHub.of(context)!.theme.mode == + "Dark"), + inputColor: MihColors.getPrimaryColor( + MzansiInnovationHub.of(context)!.theme.mode == + "Dark"), + controller: contactController, + numberMode: true, + multiLineInput: false, + requiredText: true, + hintText: null, + validator: (value) { + return MihValidationServices().isEmpty(value); + }, + ), + ), + ], + ), + const SizedBox(height: 10), + MihTextFormField( + height: 250, + fillColor: MihColors.getSecondaryColor( + MzansiInnovationHub.of(context)!.theme.mode == + "Dark"), + inputColor: MihColors.getPrimaryColor( + MzansiInnovationHub.of(context)!.theme.mode == + "Dark"), + controller: missionVisionController, + multiLineInput: true, + requiredText: true, + hintText: "Business Mission & Vision", + validator: (value) { + return MihValidationServices().validateLength( + missionVisionController.text, 256); + }, + ), + SizedBox( + height: 15, + child: ValueListenableBuilder( + valueListenable: _counter, + builder: + (BuildContext context, int value, Widget? child) { + return Row( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: MainAxisAlignment.end, + children: [ + Text( + "$value", + style: TextStyle( + color: getMissionVisionLimitColor(256), + fontWeight: FontWeight.bold, + ), + ), + const SizedBox(width: 5), + Text( + "/256", + style: TextStyle( + color: getMissionVisionLimitColor(256), + fontWeight: FontWeight.bold, + ), + ), + ], + ); + }, + ), + ), + const SizedBox(height: 10.0), + MihTextFormField( + fillColor: MihColors.getSecondaryColor( + MzansiInnovationHub.of(context)!.theme.mode == + "Dark"), + inputColor: MihColors.getPrimaryColor( + MzansiInnovationHub.of(context)!.theme.mode == + "Dark"), + controller: websiteController, + multiLineInput: false, + requiredText: false, + hintText: "Business Website", + validator: (value) { + return MihValidationServices() + .validateWebsite(value, false); + }, + ), + const SizedBox(height: 10), + MihTextFormField( + fillColor: MihColors.getSecondaryColor( + MzansiInnovationHub.of(context)!.theme.mode == + "Dark"), + inputColor: MihColors.getPrimaryColor( + MzansiInnovationHub.of(context)!.theme.mode == + "Dark"), + controller: regController, + multiLineInput: false, + requiredText: false, + hintText: "Registration No.", + validator: (value) { + // return MihValidationServices().isEmpty(value); + return null; + }, + ), + const SizedBox(height: 10), + MihTextFormField( + fillColor: MihColors.getSecondaryColor( + MzansiInnovationHub.of(context)!.theme.mode == + "Dark"), + inputColor: MihColors.getPrimaryColor( + MzansiInnovationHub.of(context)!.theme.mode == + "Dark"), + controller: practiceNoController, + multiLineInput: false, + requiredText: false, + hintText: "Practice Number", + validator: (validateValue) { + return null; + }, + ), + const SizedBox(height: 10), + MihTextFormField( + fillColor: MihColors.getSecondaryColor( + MzansiInnovationHub.of(context)!.theme.mode == + "Dark"), + inputColor: MihColors.getPrimaryColor( + MzansiInnovationHub.of(context)!.theme.mode == + "Dark"), + controller: vatNoController, + multiLineInput: false, + requiredText: false, + hintText: "VAT Number", + validator: (value) { + // return MihValidationServices().isEmpty(value); + return null; + }, + ), + const SizedBox(height: 10), + Row( + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + Flexible( + child: MihTextFormField( + fillColor: MihColors.getSecondaryColor( + MzansiInnovationHub.of(context)!.theme.mode == + "Dark"), + inputColor: MihColors.getPrimaryColor( + MzansiInnovationHub.of(context)!.theme.mode == + "Dark"), + controller: locationController, + multiLineInput: false, + requiredText: true, + readOnly: true, + hintText: "GPS Location", + ), + ), + const SizedBox(width: 10.0), + MihButton( + onPressed: () { + showDialog( + context: context, + builder: (context) { + return const Mihloadingcircle( + message: "Getting your location", + ); + }, + ); + MIHLocationAPI() + .getGPSPosition(context) + .then((position) { + if (position != null) { + setState(() { + locationController.text = + "${position.latitude}, ${position.longitude}"; + }); + } + //Dismiss loading indicator + context.pop(); + }); + }, + buttonColor: MihColors.getSecondaryColor( + MzansiInnovationHub.of(context)!.theme.mode == + "Dark"), + width: 100, + child: Text( + "Set", + style: TextStyle( + color: MihColors.getPrimaryColor( + MzansiInnovationHub.of(context)! + .theme + .mode == + "Dark"), + fontSize: 20, + fontWeight: FontWeight.bold, + ), + ), + ), + ], + ), + const SizedBox(height: 25), + Center( + child: MihButton( + onPressed: () { + if (_formKey.currentState!.validate()) { + submitForm(mzansiProfileProvider); + } else { + MihAlertServices() + .formNotFilledCompletely(context); + } + }, + buttonColor: MihColors.getGreenColor( + MzansiInnovationHub.of(context)!.theme.mode == + "Dark"), + width: 300, + child: Text( + "Update", + style: TextStyle( + color: MihColors.getPrimaryColor( + MzansiInnovationHub.of(context)!.theme.mode == + "Dark"), + fontSize: 20, + fontWeight: FontWeight.bold, + ), + ), + ), + ), + const SizedBox(height: 20), + ], + ), + ], + ), + ), + ), + ); + }, + ); + } +} diff --git a/Frontend/lib/mih_packages/mzansi_profile/business_profile/mzansi_business_profile.dart b/Frontend/lib/mih_packages/mzansi_profile/business_profile/mzansi_business_profile.dart index f106ec95..1baef840 100644 --- a/Frontend/lib/mih_packages/mzansi_profile/business_profile/mzansi_business_profile.dart +++ b/Frontend/lib/mih_packages/mzansi_profile/business_profile/mzansi_business_profile.dart @@ -1,23 +1,22 @@ +import 'dart:convert'; + import 'package:go_router/go_router.dart'; -import 'package:mzansi_innovation_hub/mih_packages/mzansi_profile/business_profile/package_tools/mih_business_qr_code.dart'; -import 'package:mzansi_innovation_hub/mih_packages/mzansi_profile/business_profile/package_tools/mih_business_reviews.dart'; -import 'package:mzansi_innovation_hub/mih_services/mih_file_services.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_objects/business_employee.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_providers/mzansi_profile_provider.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_action.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_tools.dart'; -import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_loading_circle.dart'; -import 'package:mzansi_innovation_hub/mih_components/mih_objects/arguments.dart'; +import 'package:mzansi_innovation_hub/mih_config/mih_env.dart'; import 'package:mzansi_innovation_hub/mih_packages/mzansi_profile/business_profile/package_tools/mih_business_details.dart'; -import 'package:mzansi_innovation_hub/mih_packages/mzansi_profile/business_profile/package_tools/mih_business_user_search.dart'; -import 'package:mzansi_innovation_hub/mih_packages/mzansi_profile/business_profile/package_tools/mih_my_business_team.dart'; import 'package:flutter/material.dart'; +import 'package:mzansi_innovation_hub/mih_packages/mzansi_profile/business_profile/package_tools/mih_my_business_team.dart'; import 'package:mzansi_innovation_hub/mih_packages/mzansi_profile/business_profile/package_tools/mih_my_business_user.dart'; +import 'package:provider/provider.dart'; +import 'package:supertokens_flutter/http.dart' as http; class MzansiBusinessProfile extends StatefulWidget { - final BusinessArguments arguments; const MzansiBusinessProfile({ super.key, - required this.arguments, }); @override @@ -25,26 +24,38 @@ class MzansiBusinessProfile extends StatefulWidget { } class _MzansiBusinessProfileState extends State { - int _selcetedIndex = 0; - late Future futureLogoUrl; - late Future futureProPicUrl; - late Future futureUserSignatureUrl; + String errorCode = ""; + String errorBody = ""; + + Future fetchEmployees() async { + //print("Patien manager page: $endpoint"); + MzansiProfileProvider mzansiProfileProvider = + context.read(); + final response = await http.get(Uri.parse( + "${AppEnviroment.baseApiUrl}/business-user/employees/${mzansiProfileProvider.businessUser!.business_id}")); + errorCode = response.statusCode.toString(); + errorBody = response.body; + if (response.statusCode == 200) { + //print("Here1"); + Iterable l = jsonDecode(response.body); + //print("Here2"); + List employeeList = List.from( + l.map((model) => BusinessEmployee.fromJson(model))); + mzansiProfileProvider.setEmployeeList(employeeList: employeeList); + //print("Here3"); + //print(patientQueue); + // return patientQueue; + } else { + throw Exception('failed to load employees'); + } + } @override void initState() { super.initState(); - futureLogoUrl = MihFileApi.getMinioFileUrl( - widget.arguments.business!.logo_path, - context, - ); - futureProPicUrl = MihFileApi.getMinioFileUrl( - widget.arguments.signedInUser.pro_pic_path, - context, - ); - futureUserSignatureUrl = MihFileApi.getMinioFileUrl( - widget.arguments.businessUser!.sig_path, - context, - ); + WidgetsBinding.instance.addPostFrameCallback((_) async { + await fetchEmployees(); + }); } @override @@ -54,11 +65,9 @@ class _MzansiBusinessProfileState extends State { appTools: getTools(), appBody: getToolBody(), appToolTitles: getToolTitle(), - selectedbodyIndex: _selcetedIndex, - onIndexChange: (newValue) { - setState(() { - _selcetedIndex = newValue; - }); + selectedbodyIndex: context.watch().businessIndex, + onIndexChange: (newIndex) { + context.read().setBusinessIndex(newIndex); }, ); } @@ -80,96 +89,40 @@ class _MzansiBusinessProfileState extends State { MihPackageTools getTools() { Map temp = {}; temp[const Icon(Icons.business)] = () { - setState(() { - _selcetedIndex = 0; - }); + context.read().setBusinessIndex(0); }; temp[const Icon(Icons.person)] = () { - setState(() { - _selcetedIndex = 1; - }); + context.read().setBusinessIndex(1); }; - // temp[const Icon(Icons.warning)] = () { - // setState(() { - // _selcetedIndex = 2; - // }); - // }; temp[const Icon(Icons.people)] = () { - setState(() { - _selcetedIndex = 2; - }); - }; - temp[const Icon(Icons.add)] = () { - setState(() { - _selcetedIndex = 3; - }); - }; - temp[const Icon(Icons.star_rate_rounded)] = () { - setState(() { - _selcetedIndex = 4; - }); - }; - temp[const Icon(Icons.qr_code_rounded)] = () { - setState(() { - _selcetedIndex = 5; - }); + context.read().setBusinessIndex(2); }; + // temp[const Icon(Icons.add)] = () { + // context.read().setBusinessIndex(3); + // }; + // temp[const Icon(Icons.star_rate_rounded)] = () { + // context.read().setBusinessIndex(4); + // }; + // temp[const Icon(Icons.qr_code_rounded)] = () { + // context.read().setBusinessIndex(5); + // }; return MihPackageTools( tools: temp, - selcetedIndex: _selcetedIndex, + selcetedIndex: context.watch().businessIndex, ); } List getToolBody() { List toolBodies = [ - FutureBuilder( - future: futureLogoUrl, - builder: (context, snapshot) { - if (snapshot.connectionState == ConnectionState.waiting) { - return const Center(child: Mihloadingcircle()); - } else if (snapshot.connectionState == ConnectionState.done && - snapshot.hasData) { - final logoUrl = snapshot.data!.isNotEmpty - ? NetworkImage(snapshot.data!) - : null; - return MihBusinessDetails( - arguments: widget.arguments, - logoImage: logoUrl, - ); - } else { - return Text("Error: ${snapshot.error}"); - } - }), - FutureBuilder>( - future: Future.wait([futureProPicUrl, futureUserSignatureUrl]), - builder: (context, snapshot) { - if (snapshot.connectionState == ConnectionState.waiting) { - return const Center(child: Mihloadingcircle()); - } else if (snapshot.connectionState == ConnectionState.done && - snapshot.hasData) { - final proPicUrl = NetworkImage(snapshot.data![0]); - print("=============== Signature URL: ${snapshot.data![1]}"); - final signatureUrl = snapshot.data![1].isNotEmpty - ? NetworkImage(snapshot.data![1]) - : null; - return MihMyBusinessUser( - arguments: widget.arguments, - userProPicImage: proPicUrl, - userSignatureImage: signatureUrl, - ); - } else { - return Text("Error: ${snapshot.error}"); - } - }, - ), - // MihBusinessProfile(arguments: widget.arguments), - MihMyBusinessTeam(arguments: widget.arguments), - MihBusinessUserSearch(arguments: widget.arguments), - MihBusinessReviews(business: widget.arguments.business!), - MihBusinessQrCode( - business: widget.arguments.business!, - startUpSearch: "", - ), + MihBusinessDetails(), + MihMyBusinessUser(), + MihMyBusinessTeam(), + // MihBusinessUserSearch(arguments: widget.arguments), + // MihBusinessReviews(business: widget.arguments.business!), + // MihBusinessQrCode( + // business: widget.arguments.business!, + // startUpSearch: "", + // ), ]; return toolBodies; } @@ -179,9 +132,9 @@ class _MzansiBusinessProfileState extends State { "Profile", "User", "Team", - "Add", - "Reviews", - "Share", + // "Add", + // "Reviews", + // "Share", ]; return toolTitles; } diff --git a/Frontend/lib/mih_packages/mzansi_profile/business_profile/package_tools/mih_business_details.dart b/Frontend/lib/mih_packages/mzansi_profile/business_profile/package_tools/mih_business_details.dart index 4399f5ea..b682df21 100644 --- a/Frontend/lib/mih_packages/mzansi_profile/business_profile/package_tools/mih_business_details.dart +++ b/Frontend/lib/mih_packages/mzansi_profile/business_profile/package_tools/mih_business_details.dart @@ -1,35 +1,19 @@ -import 'package:country_code_picker/country_code_picker.dart'; import 'package:file_picker/file_picker.dart'; import 'package:flutter/material.dart'; -import 'package:go_router/go_router.dart'; import 'package:mzansi_innovation_hub/main.dart'; -import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_window.dart'; -import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_loading_circle.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_providers/mzansi_profile_provider.dart'; import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart'; import 'package:mzansi_innovation_hub/mih_packages/mzansi_profile/business_profile/components/mih_business_info_card.dart'; -import 'package:mzansi_innovation_hub/mih_services/mih_alert_services.dart'; -import 'package:mzansi_innovation_hub/mih_services/mih_business_details_services.dart'; -import 'package:mzansi_innovation_hub/mih_services/mih_file_services.dart'; -import 'package:mzansi_innovation_hub/mih_services/mih_location_services.dart'; -import 'package:mzansi_innovation_hub/mih_services/mih_validation_services.dart'; +import 'package:mzansi_innovation_hub/mih_packages/mzansi_profile/business_profile/components/mih_update_business_details_window.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_single_child_scroll.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_button.dart'; -import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_form.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_tool_body.dart'; -import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_alert.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_circle_avatar.dart'; -import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_text_form_field.dart'; -import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_error_message.dart'; -import 'package:mzansi_innovation_hub/mih_config/mih_env.dart'; -import 'package:mzansi_innovation_hub/mih_components/mih_objects/arguments.dart'; +import 'package:provider/provider.dart'; class MihBusinessDetails extends StatefulWidget { - final BusinessArguments arguments; - final ImageProvider? logoImage; const MihBusinessDetails({ super.key, - required this.arguments, - required this.logoImage, }); @override @@ -37,696 +21,25 @@ class MihBusinessDetails extends StatefulWidget { } class _MihBusinessDetailsState extends State { - PlatformFile? imageFile; + PlatformFile? newSelectedLogoPic; final fileNameController = TextEditingController(); - final regController = TextEditingController(); - final nameController = TextEditingController(); - final typeController = TextEditingController(); - final practiceNoController = TextEditingController(); - final vatNoController = TextEditingController(); - final countryCodeController = TextEditingController(); - final contactController = TextEditingController(); - final emailController = TextEditingController(); - final locationController = TextEditingController(); - final websiteController = TextEditingController(); - final ratingController = TextEditingController(); - final missionVisionController = TextEditingController(); - final _formKey = GlobalKey(); - final ValueNotifier _counter = ValueNotifier(0); - late String env; - void successPopUp(String message, bool stayOnPersonalSide) { + void editBizProfileWindow( + MzansiProfileProvider mzansiProfileProvider, double width) { showDialog( context: context, - builder: (context) { - return MihPackageAlert( - alertIcon: Icon( - Icons.check_circle_outline_rounded, - size: 150, - color: MihColors.getGreenColor( - MzansiInnovationHub.of(context)!.theme.mode == "Dark"), - ), - alertTitle: "Successfully Updated Profile", - alertBody: Column( - children: [ - Text( - message, - style: TextStyle( - color: MihColors.getSecondaryColor( - MzansiInnovationHub.of(context)!.theme.mode == "Dark"), - fontSize: 15, - fontWeight: FontWeight.bold, - ), - ), - const SizedBox(height: 25), - Center( - child: MihButton( - onPressed: () { - context.goNamed( - 'mihHome', - extra: stayOnPersonalSide, - ); - }, - buttonColor: MihColors.getGreenColor( - MzansiInnovationHub.of(context)!.theme.mode == "Dark"), - elevation: 10, - width: 300, - child: Text( - "Dismiss", - style: TextStyle( - color: MihColors.getPrimaryColor( - MzansiInnovationHub.of(context)!.theme.mode == - "Dark"), - fontSize: 20, - fontWeight: FontWeight.bold, - ), - ), - ), - ) - ], - ), - alertColour: MihColors.getGreenColor( - MzansiInnovationHub.of(context)!.theme.mode == "Dark"), - ); - // return MIHSuccessMessage( - // successType: "Success", - // successMessage: message, - // ); - }, + builder: (context) => MihUpdateBusinessDetailsWindow(width: width), ); } - Future submitForm() async { - if (isFormFilled()) { - int statusCode = 0; - statusCode = await MihBusinessDetailsServices().updateBusinessDetailsV2( - widget.arguments.business!.business_id, - nameController.text, - typeController.text, - regController.text, - practiceNoController.text, - vatNoController.text, - emailController.text, - getNumberWithCountryCode(), - // contactController.text, - locationController.text, - fileNameController.text, - websiteController.text, - ratingController.text.isEmpty ? "0" : ratingController.text, - missionVisionController.text, - context, - ); - if (statusCode == 200) { - bool successfullyUploadedFile = await uploadFile(); - if (successfullyUploadedFile) { - //You left of here - String message = "Your information has been updated successfully!"; - successPopUp(message, false); - // File uploaded successfully - } else { - // File upload failed - showDialog( - context: context, - builder: (context) { - return MihPackageAlert( - alertIcon: Icon( - Icons.warning_rounded, - color: MihColors.getRedColor( - MzansiInnovationHub.of(context)!.theme.mode == "Dark"), - ), - alertTitle: "Error Updating Business Details", - alertBody: Column( - children: [ - Text( - "An error occurred while updating the business details. Please check internet connection and try again.", - style: TextStyle( - color: MihColors.getSecondaryColor( - MzansiInnovationHub.of(context)!.theme.mode == - "Dark"), - ), - ), - ], - ), - alertColour: MihColors.getRedColor( - MzansiInnovationHub.of(context)!.theme.mode == "Dark"), - ); - }, - ); - } - } else { - showDialog( - context: context, - builder: (context) { - return const MIHErrorMessage(errorType: "Internet Connection"); - }, - ); - } - } else { - showDialog( - context: context, - builder: (context) { - return const MIHErrorMessage(errorType: "Input Error"); - }, - ); - } - } - - Future uploadFile() async { - if (imageFile != null) { - int uploadStatusCode = 0; - uploadStatusCode = await MihFileApi.uploadFile( - widget.arguments.business!.business_id, - env, - "business_files", - imageFile!, - context, - ); - if (uploadStatusCode == 200) { - int deleteStatusCode = 0; - deleteStatusCode = await MihFileApi.deleteFile( - widget.arguments.business!.logo_path.split("/").first, - env, - "business_files", - widget.arguments.business!.logo_path.split("/").last, - context, - ); - if (deleteStatusCode == 200) { - return true; - } else { - return false; - } - } else { - return false; - } - } else { - return true; // No file selected, so no upload needed - } - } - - bool isFileSelected() { - if (imageFile != null) { - return true; - } else { - return false; - } - } - - bool isEmailValid() { - String text = emailController.text; - var regex = RegExp(r'^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$'); - return regex.hasMatch(text); - } - - bool isFormFilled() { - if (typeController.text.isEmpty) { - return false; - } else { - return true; - } - } - - void setContactNumberControllers() { - if (widget.arguments.business!.contact_no[0] == "+") { - List contactDetails = - widget.arguments.business!.contact_no.split("-"); - setState(() { - countryCodeController.text = contactDetails[0]; - contactController.text = contactDetails[1]; - }); - } else { - setState(() { - countryCodeController.text = "+27"; - contactController.text = widget.arguments.business!.contact_no; - }); - } - } - - String getNumberWithCountryCode() { - String numberWithoutBeginingZero = ""; - if (contactController.text[0] == "0") { - numberWithoutBeginingZero = contactController.text - .replaceAll(" ", "") - .substring(1, contactController.text.length); - } else { - numberWithoutBeginingZero = contactController.text.replaceAll("-", " "); - } - return "${countryCodeController.text}-$numberWithoutBeginingZero"; - } - - void editBizProfileWindow(double width) { - showDialog( - context: context, - builder: (context) => MihPackageWindow( - fullscreen: false, - windowTitle: 'Edit Profile', - onWindowTapClose: () { - context.pop(); - resetControllers(); - }, - windowBody: MihSingleChildScroll( - child: Padding( - padding: MzansiInnovationHub.of(context)!.theme.screenType == - "desktop" - ? EdgeInsets.symmetric(horizontal: width * 0.05) - : EdgeInsets.symmetric(horizontal: width * 0), - child: Column( - children: [ - MihForm( - formKey: _formKey, - formFields: [ - Center( - child: MihCircleAvatar( - imageFile: widget.logoImage, - width: 150, - editable: true, - fileNameController: fileNameController, - userSelectedfile: imageFile, - frameColor: MihColors.getSecondaryColor( - MzansiInnovationHub.of(context)!.theme.mode == - "Dark"), - backgroundColor: MihColors.getPrimaryColor( - MzansiInnovationHub.of(context)!.theme.mode == - "Dark"), - onChange: (selectedfile) { - setState(() { - imageFile = selectedfile; - }); - }, - ), - ), - Visibility( - visible: false, - child: MihTextFormField( - fillColor: MihColors.getSecondaryColor( - MzansiInnovationHub.of(context)!.theme.mode == - "Dark"), - inputColor: MihColors.getPrimaryColor( - MzansiInnovationHub.of(context)!.theme.mode == - "Dark"), - controller: fileNameController, - multiLineInput: false, - requiredText: true, - readOnly: true, - hintText: "Selected File Name", - ), - ), - const SizedBox(height: 20), - MihTextFormField( - fillColor: MihColors.getSecondaryColor( - MzansiInnovationHub.of(context)!.theme.mode == - "Dark"), - inputColor: MihColors.getPrimaryColor( - MzansiInnovationHub.of(context)!.theme.mode == - "Dark"), - controller: nameController, - multiLineInput: false, - requiredText: true, - hintText: "Business Name", - validator: (value) { - return MihValidationServices().isEmpty(value); - }, - ), - const SizedBox(height: 10), - MihTextFormField( - fillColor: MihColors.getSecondaryColor( - MzansiInnovationHub.of(context)!.theme.mode == - "Dark"), - inputColor: MihColors.getPrimaryColor( - MzansiInnovationHub.of(context)!.theme.mode == - "Dark"), - controller: typeController, - multiLineInput: false, - requiredText: true, - hintText: "Business Type", - validator: (value) { - return MihValidationServices() - .validateNoSpecialChars(value); - }, - ), - const SizedBox(height: 10), - MihTextFormField( - fillColor: MihColors.getSecondaryColor( - MzansiInnovationHub.of(context)!.theme.mode == - "Dark"), - inputColor: MihColors.getPrimaryColor( - MzansiInnovationHub.of(context)!.theme.mode == - "Dark"), - controller: emailController, - multiLineInput: false, - requiredText: true, - hintText: "Business Email", - validator: (value) { - return MihValidationServices() - .validateEmail(value); - }, - ), - const SizedBox(height: 10), - Container( - width: 300, - alignment: Alignment.topLeft, - child: const Text( - "Contact Number:", - style: TextStyle( - fontSize: 18, - fontWeight: FontWeight.bold, - ), - ), - ), - Row( - crossAxisAlignment: CrossAxisAlignment.end, - children: [ - CountryCodePicker( - padding: EdgeInsetsGeometry.all(0), - onChanged: (selectedCode) { - setState(() { - countryCodeController.text = - selectedCode.toString(); - }); - debugPrint( - "Selected Country Code: ${countryCodeController.text}"); - }, - initialSelection: countryCodeController.text, - showDropDownButton: false, - pickerStyle: PickerStyle.bottomSheet, - dialogBackgroundColor: - MihColors.getPrimaryColor( - MzansiInnovationHub.of(context)! - .theme - .mode == - "Dark"), - barrierColor: MihColors.getPrimaryColor( - MzansiInnovationHub.of(context)! - .theme - .mode == - "Dark"), - ), - Expanded( - child: MihTextFormField( - fillColor: MihColors.getSecondaryColor( - MzansiInnovationHub.of(context)! - .theme - .mode == - "Dark"), - inputColor: MihColors.getPrimaryColor( - MzansiInnovationHub.of(context)! - .theme - .mode == - "Dark"), - controller: contactController, - numberMode: true, - multiLineInput: false, - requiredText: true, - hintText: null, - validator: (value) { - return MihValidationServices() - .isEmpty(value); - }, - ), - ), - ], - ), - const SizedBox(height: 10), - MihTextFormField( - height: 250, - fillColor: MihColors.getSecondaryColor( - MzansiInnovationHub.of(context)!.theme.mode == - "Dark"), - inputColor: MihColors.getPrimaryColor( - MzansiInnovationHub.of(context)!.theme.mode == - "Dark"), - controller: missionVisionController, - multiLineInput: true, - requiredText: true, - hintText: "Business Mission & Vision", - validator: (value) { - return MihValidationServices().validateLength( - missionVisionController.text, 256); - }, - ), - SizedBox( - height: 15, - child: ValueListenableBuilder( - valueListenable: _counter, - builder: (BuildContext context, int value, - Widget? child) { - return Row( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.end, - children: [ - Text( - "$value", - style: TextStyle( - color: getMissionVisionLimitColor(256), - fontWeight: FontWeight.bold, - ), - ), - const SizedBox(width: 5), - Text( - "/256", - style: TextStyle( - color: getMissionVisionLimitColor(256), - fontWeight: FontWeight.bold, - ), - ), - ], - ); - }, - ), - ), - const SizedBox(height: 10.0), - MihTextFormField( - fillColor: MihColors.getSecondaryColor( - MzansiInnovationHub.of(context)!.theme.mode == - "Dark"), - inputColor: MihColors.getPrimaryColor( - MzansiInnovationHub.of(context)!.theme.mode == - "Dark"), - controller: websiteController, - multiLineInput: false, - requiredText: false, - hintText: "Business Website", - validator: (value) { - return MihValidationServices() - .validateWebsite(value, false); - }, - ), - const SizedBox(height: 10), - MihTextFormField( - fillColor: MihColors.getSecondaryColor( - MzansiInnovationHub.of(context)!.theme.mode == - "Dark"), - inputColor: MihColors.getPrimaryColor( - MzansiInnovationHub.of(context)!.theme.mode == - "Dark"), - controller: regController, - multiLineInput: false, - requiredText: false, - hintText: "Registration No.", - validator: (value) { - // return MihValidationServices().isEmpty(value); - return null; - }, - ), - const SizedBox(height: 10), - MihTextFormField( - fillColor: MihColors.getSecondaryColor( - MzansiInnovationHub.of(context)!.theme.mode == - "Dark"), - inputColor: MihColors.getPrimaryColor( - MzansiInnovationHub.of(context)!.theme.mode == - "Dark"), - controller: practiceNoController, - multiLineInput: false, - requiredText: false, - hintText: "Practice Number", - validator: (validateValue) { - return null; - }, - ), - const SizedBox(height: 10), - MihTextFormField( - fillColor: MihColors.getSecondaryColor( - MzansiInnovationHub.of(context)!.theme.mode == - "Dark"), - inputColor: MihColors.getPrimaryColor( - MzansiInnovationHub.of(context)!.theme.mode == - "Dark"), - controller: vatNoController, - multiLineInput: false, - requiredText: false, - hintText: "VAT Number", - validator: (value) { - // return MihValidationServices().isEmpty(value); - return null; - }, - ), - const SizedBox(height: 10), - Row( - crossAxisAlignment: CrossAxisAlignment.end, - children: [ - Flexible( - child: MihTextFormField( - fillColor: MihColors.getSecondaryColor( - MzansiInnovationHub.of(context)! - .theme - .mode == - "Dark"), - inputColor: MihColors.getPrimaryColor( - MzansiInnovationHub.of(context)! - .theme - .mode == - "Dark"), - controller: locationController, - multiLineInput: false, - requiredText: true, - readOnly: true, - hintText: "GPS Location", - ), - ), - const SizedBox(width: 10.0), - MihButton( - onPressed: () { - showDialog( - context: context, - builder: (context) { - return const Mihloadingcircle( - message: "Getting your location", - ); - }, - ); - MIHLocationAPI() - .getGPSPosition(context) - .then((position) { - if (position != null) { - setState(() { - locationController.text = - "${position.latitude}, ${position.longitude}"; - }); - } - //Dismiss loading indicator - Navigator.of(context).pop(); - }); - }, - buttonColor: MihColors.getSecondaryColor( - MzansiInnovationHub.of(context)! - .theme - .mode == - "Dark"), - width: 100, - child: Text( - "Set", - style: TextStyle( - color: MihColors.getPrimaryColor( - MzansiInnovationHub.of(context)! - .theme - .mode == - "Dark"), - fontSize: 20, - fontWeight: FontWeight.bold, - ), - ), - ), - ], - ), - const SizedBox(height: 25), - Center( - child: MihButton( - onPressed: () { - if (_formKey.currentState!.validate()) { - submitForm(); - } else { - MihAlertServices() - .formNotFilledCompletely(context); - } - }, - buttonColor: MihColors.getGreenColor( - MzansiInnovationHub.of(context)!.theme.mode == - "Dark"), - width: 300, - child: Text( - "Update", - style: TextStyle( - color: MihColors.getPrimaryColor( - MzansiInnovationHub.of(context)! - .theme - .mode == - "Dark"), - fontSize: 20, - fontWeight: FontWeight.bold, - ), - ), - ), - ), - const SizedBox(height: 20), - ], - ), - ], - ), - ), - ), - )); - } - - Color getMissionVisionLimitColor(int limit) { - if (_counter.value <= limit) { - return MihColors.getSecondaryColor( - MzansiInnovationHub.of(context)!.theme.mode == "Dark"); - } else { - return MihColors.getRedColor( - MzansiInnovationHub.of(context)!.theme.mode == "Dark"); - } - } - - void resetControllers() { - setState(() { - fileNameController.text = - widget.arguments.business!.logo_path.split("/").last; - regController.text = widget.arguments.business!.registration_no; - nameController.text = widget.arguments.business!.Name; - typeController.text = widget.arguments.business!.type; - practiceNoController.text = widget.arguments.business!.practice_no; - vatNoController.text = widget.arguments.business!.vat_no; - emailController.text = widget.arguments.business!.bus_email; - locationController.text = widget.arguments.business!.gps_location; - websiteController.text = widget.arguments.business!.website; - ratingController.text = widget.arguments.business!.rating; - missionVisionController.text = widget.arguments.business!.mission_vision; - }); - setContactNumberControllers(); - if (AppEnviroment.getEnv() == "Prod") { - env = "Prod"; - } else { - env = "Dev"; - } - missionVisionController.addListener(() { - setState(() { - _counter.value = missionVisionController.text.characters.length; - }); - }); - } - @override void dispose() { super.dispose(); - fileNameController.dispose(); - regController.dispose(); - nameController.dispose(); - typeController.dispose(); - practiceNoController.dispose(); - vatNoController.dispose(); - contactController.dispose(); - emailController.dispose(); - locationController.dispose(); - websiteController.dispose(); - ratingController.dispose(); - missionVisionController.dispose(); - imageFile = null; } @override void initState() { super.initState(); - resetControllers(); } @override @@ -740,161 +53,149 @@ class _MihBusinessDetailsState extends State { } Widget getBody(double width, BuildContext context) { - return Stack( - children: [ - MihSingleChildScroll( - child: Padding( - padding: - MzansiInnovationHub.of(context)!.theme.screenType == "desktop" + return Consumer( + builder: (BuildContext context, + MzansiProfileProvider mzansiProfileProvider, Widget? child) { + return Stack( + children: [ + MihSingleChildScroll( + child: Padding( + padding: MzansiInnovationHub.of(context)!.theme.screenType == + "desktop" ? EdgeInsets.symmetric(horizontal: width * 0.2) : EdgeInsets.symmetric(horizontal: width * 0.075), - child: Column( - children: [ - Center( - child: MihCircleAvatar( - imageFile: widget.logoImage, - width: 150, - editable: false, - fileNameController: fileNameController, - userSelectedfile: imageFile, - frameColor: MihColors.getSecondaryColor( - MzansiInnovationHub.of(context)!.theme.mode == "Dark"), - backgroundColor: MihColors.getPrimaryColor( - MzansiInnovationHub.of(context)!.theme.mode == "Dark"), - onChange: (selectedfile) { - setState(() { - imageFile = selectedfile; - }); - }, - ), - ), - FittedBox( - child: Text( - widget.arguments.business!.Name, - style: TextStyle( - fontSize: 35, - fontWeight: FontWeight.bold, - color: MihColors.getSecondaryColor( - MzansiInnovationHub.of(context)!.theme.mode == - "Dark"), - ), - ), - ), - FittedBox( - child: Text( - widget.arguments.business!.type, - style: TextStyle( - fontSize: 20, - fontWeight: FontWeight.w600, - color: MihColors.getSecondaryColor( - MzansiInnovationHub.of(context)!.theme.mode == - "Dark"), - ), - ), - ), - const SizedBox(height: 5), - // FittedBox( - // child: Text( - // "Mission & Vision", - // style: TextStyle( - // fontSize: 15, - // fontWeight: FontWeight.bold, - // color: MzansiInnovationHub.of(context)! - // .theme - // .secondaryColor(), - // ), - // ), - // ), - Center( - child: SizedBox( - width: 700, - child: Text( - widget.arguments.business!.mission_vision.isNotEmpty - ? widget.arguments.business!.mission_vision - : "No Mission & Vision added yet", - textAlign: TextAlign.center, - style: TextStyle( - fontSize: 15, - fontWeight: FontWeight.bold, - color: MihColors.getSecondaryColor( + child: Column( + children: [ + Center( + child: MihCircleAvatar( + imageFile: mzansiProfileProvider.businessProfilePicture, + width: 150, + editable: false, + fileNameController: fileNameController, + userSelectedfile: newSelectedLogoPic, + frameColor: MihColors.getSecondaryColor( MzansiInnovationHub.of(context)!.theme.mode == "Dark"), - ), - ), - ), - ), - const SizedBox(height: 20), - SizedBox( - width: 700, - child: MihBusinessCard( - // businessid: widget.arguments.business!.business_id, - // businessName: widget.arguments.business!.Name, - // cellNumber: widget.arguments.business!.contact_no, - // email: widget.arguments.business!.bus_email, - // gpsLocation: widget.arguments.business!.gps_location, - // rating: widget.arguments.business!.rating.isNotEmpty - // ? double.parse(widget.arguments.business!.rating) - // : 0, - // website: widget.arguments.business!.website, - business: widget.arguments.business!, - startUpSearch: null, - width: width, - ), - ), - const SizedBox(height: 30.0), - Center( - child: MihButton( - onPressed: () { - // Connect with the user - editBizProfileWindow(width); - }, - buttonColor: MihColors.getGreenColor( - MzansiInnovationHub.of(context)!.theme.mode == "Dark"), - width: 300, - child: Text( - "Edit Profile", - style: TextStyle( - color: MihColors.getPrimaryColor( + backgroundColor: MihColors.getPrimaryColor( MzansiInnovationHub.of(context)!.theme.mode == "Dark"), - fontSize: 20, - fontWeight: FontWeight.bold, + onChange: (selectedfile) { + setState(() { + newSelectedLogoPic = selectedfile; + }); + }, ), ), - ), + FittedBox( + child: Text( + mzansiProfileProvider.business!.Name, + style: TextStyle( + fontSize: 35, + fontWeight: FontWeight.bold, + color: MihColors.getSecondaryColor( + MzansiInnovationHub.of(context)!.theme.mode == + "Dark"), + ), + ), + ), + FittedBox( + child: Text( + mzansiProfileProvider.business!.type, + style: TextStyle( + fontSize: 20, + fontWeight: FontWeight.w600, + color: MihColors.getSecondaryColor( + MzansiInnovationHub.of(context)!.theme.mode == + "Dark"), + ), + ), + ), + const SizedBox(height: 5), + Center( + child: SizedBox( + width: 700, + child: Text( + mzansiProfileProvider + .business!.mission_vision.isNotEmpty + ? mzansiProfileProvider.business!.mission_vision + : "No Mission & Vision added yet", + textAlign: TextAlign.center, + style: TextStyle( + fontSize: 15, + fontWeight: FontWeight.bold, + color: MihColors.getSecondaryColor( + MzansiInnovationHub.of(context)!.theme.mode == + "Dark"), + ), + ), + ), + ), + const SizedBox(height: 20), + SizedBox( + width: 700, + child: MihBusinessCard( + business: mzansiProfileProvider.business!, + startUpSearch: null, + width: width, + ), + ), + const SizedBox(height: 30.0), + Center( + child: MihButton( + onPressed: () { + // Connect with the user + editBizProfileWindow(mzansiProfileProvider, width); + }, + buttonColor: MihColors.getGreenColor( + MzansiInnovationHub.of(context)!.theme.mode == + "Dark"), + width: 300, + child: Text( + "Edit Profile", + style: TextStyle( + color: MihColors.getPrimaryColor( + MzansiInnovationHub.of(context)!.theme.mode == + "Dark"), + fontSize: 20, + fontWeight: FontWeight.bold, + ), + ), + ), + ), + ], ), - ], + ), ), - ), - ), - // Positioned( - // right: 5, - // bottom: 10, - // child: MihFloatingMenu( - // animatedIcon: AnimatedIcons.menu_close, - // children: [ - // SpeedDialChild( - // child: Icon( - // Icons.edit, - // color: MihColors.getPrimaryColor(MzansiInnovationHub.of(context)!.theme.mode == "Dark"), - // ), - // label: "Edit Profile", - // labelBackgroundColor: - // MihColors.getGreenColor(MzansiInnovationHub.of(context)!.theme.mode == "Dark"), - // labelStyle: TextStyle( - // color: MihColors.getPrimaryColor(MzansiInnovationHub.of(context)!.theme.mode == "Dark"), - // fontWeight: FontWeight.bold, - // ), - // backgroundColor: - // MihColors.getGreenColor(MzansiInnovationHub.of(context)!.theme.mode == "Dark"), - // onTap: () { - // editBizProfileWindow(width); - // }, - // ) - // ], - // ), - // ), - ], + // Positioned( + // right: 5, + // bottom: 10, + // child: MihFloatingMenu( + // animatedIcon: AnimatedIcons.menu_close, + // children: [ + // SpeedDialChild( + // child: Icon( + // Icons.edit, + // color: MihColors.getPrimaryColor(MzansiInnovationHub.of(context)!.theme.mode == "Dark"), + // ), + // label: "Edit Profile", + // labelBackgroundColor: + // MihColors.getGreenColor(MzansiInnovationHub.of(context)!.theme.mode == "Dark"), + // labelStyle: TextStyle( + // color: MihColors.getPrimaryColor(MzansiInnovationHub.of(context)!.theme.mode == "Dark"), + // fontWeight: FontWeight.bold, + // ), + // backgroundColor: + // MihColors.getGreenColor(MzansiInnovationHub.of(context)!.theme.mode == "Dark"), + // onTap: () { + // editBizProfileWindow(width); + // }, + // ) + // ], + // ), + // ), + ], + ); + }, ); } } diff --git a/Frontend/lib/mih_packages/mzansi_profile/business_profile/package_tools/mih_my_business_team.dart b/Frontend/lib/mih_packages/mzansi_profile/business_profile/package_tools/mih_my_business_team.dart index 651d7d21..4fb5696f 100644 --- a/Frontend/lib/mih_packages/mzansi_profile/business_profile/package_tools/mih_my_business_team.dart +++ b/Frontend/lib/mih_packages/mzansi_profile/business_profile/package_tools/mih_my_business_team.dart @@ -3,19 +3,18 @@ import 'package:mzansi_innovation_hub/main.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_single_child_scroll.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_tool_body.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_loading_circle.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_providers/mzansi_profile_provider.dart'; import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart'; import 'package:mzansi_innovation_hub/mih_config/mih_env.dart'; -import 'package:mzansi_innovation_hub/mih_components/mih_objects/arguments.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_objects/business_employee.dart'; import 'package:mzansi_innovation_hub/mih_packages/mzansi_profile/business_profile/builders/build_employee_list.dart'; import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; import 'package:supertokens_flutter/http.dart' as http; class MihMyBusinessTeam extends StatefulWidget { - final BusinessArguments arguments; const MihMyBusinessTeam({ super.key, - required this.arguments, }); @override @@ -23,36 +22,35 @@ class MihMyBusinessTeam extends StatefulWidget { } class _MihMyBusinessTeamState extends State { - late Future> employeeList; - String errorCode = ""; String errorBody = ""; - Future> fetchEmployees() async { - //print("Patien manager page: $endpoint"); - final response = await http.get(Uri.parse( - "${AppEnviroment.baseApiUrl}/business-user/employees/${widget.arguments.businessUser!.business_id}")); - errorCode = response.statusCode.toString(); - errorBody = response.body; - if (response.statusCode == 200) { - //print("Here1"); - Iterable l = jsonDecode(response.body); - //print("Here2"); - List patientQueue = List.from( - l.map((model) => BusinessEmployee.fromJson(model))); - //print("Here3"); - //print(patientQueue); - return patientQueue; - } else { - throw Exception('failed to load employees'); - } - } + // Future fetchEmployees( + // MzansiProfileProvider mzansiProfileProvider) async { + // //print("Patien manager page: $endpoint"); + // final response = await http.get(Uri.parse( + // "${AppEnviroment.baseApiUrl}/business-user/employees/${mzansiProfileProvider.businessUser!.business_id}")); + // errorCode = response.statusCode.toString(); + // errorBody = response.body; + // if (response.statusCode == 200) { + // //print("Here1"); + // Iterable l = jsonDecode(response.body); + // //print("Here2"); + // List employeeList = List.from( + // l.map((model) => BusinessEmployee.fromJson(model))); + // mzansiProfileProvider.setEmployeeList(employeeList: employeeList); + // //print("Here3"); + // //print(patientQueue); + // // return patientQueue; + // } else { + // throw Exception('failed to load employees'); + // } + // } Widget displayEmployeeList(List employeeList) { if (employeeList.isNotEmpty) { return BuildEmployeeList( employees: employeeList, - arguments: widget.arguments, ); } return Center( @@ -70,7 +68,10 @@ class _MihMyBusinessTeamState extends State { @override void initState() { super.initState(); - employeeList = fetchEmployees(); + // fetchEmployees(context.read()).catchError((e) { + // // Handle the error thrown in fetchEmployees + // print('Error fetching employees: $e'); + // }); } @override @@ -82,40 +83,20 @@ class _MihMyBusinessTeamState extends State { } Widget getBody() { - return MihSingleChildScroll( - child: Column(mainAxisSize: MainAxisSize.max, children: [ - FutureBuilder( - future: employeeList, - builder: (context, snapshot) { - //print("patient Queue List ${snapshot.hasData}"); - if (snapshot.connectionState == ConnectionState.waiting) { - return const Mihloadingcircle(); - } else if (snapshot.connectionState == ConnectionState.done) { - //List employeeListResults; - // if (searchString == "") { - // patientQueueList = []; - // } else { - - // print(patientQueueList); - // } - - return displayEmployeeList(snapshot.requireData); - } else { - return Center( - child: Text( - "$errorCode: Error pulling Patients Data\n${AppEnviroment.baseApiUrl}/business-user/users/${widget.arguments.businessUser!.business_id}\n$errorBody", - style: TextStyle( - fontSize: 25, - color: MihColors.getRedColor( - MzansiInnovationHub.of(context)!.theme.mode == - "Dark")), - textAlign: TextAlign.center, - ), - ); - } - }, - ), - ]), + return Consumer( + builder: (BuildContext context, + MzansiProfileProvider mzansiProfileProvider, Widget? child) { + if (mzansiProfileProvider.employeeList == null) { + return Center( + child: Mihloadingcircle(), + ); + } + return MihSingleChildScroll( + child: Column(mainAxisSize: MainAxisSize.max, children: [ + displayEmployeeList(mzansiProfileProvider.employeeList!), + ]), + ); + }, ); } } diff --git a/Frontend/lib/mih_packages/mzansi_profile/business_profile/package_tools/mih_my_business_user.dart b/Frontend/lib/mih_packages/mzansi_profile/business_profile/package_tools/mih_my_business_user.dart index 45e87a65..8bc78d59 100644 --- a/Frontend/lib/mih_packages/mzansi_profile/business_profile/package_tools/mih_my_business_user.dart +++ b/Frontend/lib/mih_packages/mzansi_profile/business_profile/package_tools/mih_my_business_user.dart @@ -1,7 +1,9 @@ import 'package:file_picker/file_picker.dart'; import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; +import 'package:ken_logger/ken_logger.dart'; import 'package:mzansi_innovation_hub/main.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_providers/mzansi_profile_provider.dart'; import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart'; import 'package:mzansi_innovation_hub/mih_services/mih_alert_services.dart'; import 'package:mzansi_innovation_hub/mih_services/mih_file_services.dart'; @@ -17,18 +19,11 @@ import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_ import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_text_form_field.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_error_message.dart'; import 'package:mzansi_innovation_hub/mih_config/mih_env.dart'; -import 'package:mzansi_innovation_hub/mih_components/mih_objects/arguments.dart'; +import 'package:provider/provider.dart'; class MihMyBusinessUser extends StatefulWidget { - final BusinessArguments arguments; - final ImageProvider? userProPicImage; - final ImageProvider? userSignatureImage; - const MihMyBusinessUser({ super.key, - required this.arguments, - required this.userProPicImage, - required this.userSignatureImage, }); @override @@ -37,7 +32,7 @@ class MihMyBusinessUser extends StatefulWidget { class _MihMyBusinessUserState extends State { PlatformFile? userPicFile; - PlatformFile? userSignatureFile; + PlatformFile? newSelectedSignaturePic; final fileNameController = TextEditingController(); final titleTextController = TextEditingController(); final fnameController = TextEditingController(); @@ -55,23 +50,24 @@ class _MihMyBusinessUserState extends State { } } - Future uploadFile() async { - if (userSignatureFile != null) { + Future uploadFile(MzansiProfileProvider mzansiProfileProvider) async { + if (newSelectedSignaturePic != null) { int uploadStatusCode = 0; uploadStatusCode = await MihFileApi.uploadFile( - widget.arguments.signedInUser.app_id, + mzansiProfileProvider.user!.app_id, env, "business_files", - userSignatureFile!, + newSelectedSignaturePic!, context, ); if (uploadStatusCode == 200) { + signtureController.text = newSelectedSignaturePic!.name; int deleteStatusCode = 0; deleteStatusCode = await MihFileApi.deleteFile( - widget.arguments.signedInUser.app_id, + mzansiProfileProvider.user!.app_id, env, "business_files", - widget.arguments.businessUser!.sig_path.split("/").last, + mzansiProfileProvider.businessUser!.sig_path.split("/").last, context, ); if (deleteStatusCode == 200) { @@ -87,42 +83,34 @@ class _MihMyBusinessUserState extends State { } } - Future submitForm() async { + Future submitForm(MzansiProfileProvider mzansiProfileProvider) async { + KenLogger.success("Start Submit Form"); if (isFormFilled()) { - int statusCode = await MihMyBusinessUserServices().updateBusinessUser( - widget.arguments.signedInUser.app_id, - widget.arguments.businessUser!.business_id, - titleTextController.text, - accessController.text, - signtureController.text, - context, - ); - if (statusCode == 200) { - bool successfullyUploadedFile = await uploadFile(); - if (successfullyUploadedFile) { - // Navigator.of(context).pop(); - // Navigator.of(context).pop(); - // Navigator.of(context).pushNamed( - // '/', - // arguments: AuthArguments( - // false, - // false, - // ), - // ); - // File uploaded successfully + KenLogger.success("Form Filled"); + KenLogger.success("Start File Upload"); + bool successfullyUploadedFile = await uploadFile(mzansiProfileProvider); + KenLogger.success( + "File Upload Complete: outcome $successfullyUploadedFile"); + if (!mounted) return; + KenLogger.success("is mounted"); + if (successfullyUploadedFile) { + int statusCode = await MihMyBusinessUserServices().updateBusinessUser( + mzansiProfileProvider.user!.app_id, + mzansiProfileProvider.businessUser!.business_id, + titleTextController.text, + accessController.text, + signtureController.text, + mzansiProfileProvider, + context, + ); + KenLogger.success("Details Update Complete: status code $statusCode"); + if (!mounted) return; + KenLogger.success("is mounted"); + if (statusCode == 200) { + KenLogger.success("Start Success Message"); String message = "Business details updated successfully"; successPopUp(message, false); - // showDialog( - // context: context, - // builder: (context) { - // return const MIHSuccessMessage( - // successType: "Success", - // successMessage: "Business details updated successfully", - // ); - // }, - // ); } else { - // File upload failed showDialog( context: context, builder: (context) { @@ -196,10 +184,7 @@ class _MihMyBusinessUserState extends State { Center( child: MihButton( onPressed: () { - context.goNamed( - 'mihHome', - extra: stayOnPersonalSide, - ); + context.pop(); }, buttonColor: MihColors.getGreenColor( MzansiInnovationHub.of(context)!.theme.mode == "Dark"), @@ -230,6 +215,29 @@ class _MihMyBusinessUserState extends State { ); } + void setControllers() { + MzansiProfileProvider mzansiProfileProvider = + context.read(); + setState(() { + fileNameController.text = + mzansiProfileProvider.user!.pro_pic_path.split("/").last; + signtureController.text = + mzansiProfileProvider.businessUser!.sig_path.split("/").last; + KenLogger.success("title: ${mzansiProfileProvider.businessUser!.title}"); + KenLogger.success( + "sig url: ${mzansiProfileProvider.businessUser!.sig_path}"); + titleTextController.text = mzansiProfileProvider.businessUser!.title; + fnameController.text = mzansiProfileProvider.user!.fname; + lnameController.text = mzansiProfileProvider.user!.lname; + accessController.text = mzansiProfileProvider.businessUser!.access; + }); + if (AppEnviroment.getEnv() == "Prod") { + env = "Prod"; + } else { + env = "Dev"; + } + } + @override void dispose() { super.dispose(); @@ -240,27 +248,13 @@ class _MihMyBusinessUserState extends State { accessController.dispose(); signtureController.dispose(); userPicFile = null; - userSignatureFile = null; + newSelectedSignaturePic = null; } @override void initState() { super.initState(); - setState(() { - fileNameController.text = - widget.arguments.signedInUser.pro_pic_path.split("/").last; - signtureController.text = - widget.arguments.businessUser!.sig_path.split("/").last; - titleTextController.text = widget.arguments.businessUser!.title; - fnameController.text = widget.arguments.signedInUser.fname; - lnameController.text = widget.arguments.signedInUser.lname; - accessController.text = widget.arguments.businessUser!.access; - }); - if (AppEnviroment.getEnv() == "Prod") { - env = "Prod"; - } else { - env = "Dev"; - } + setControllers(); } @override @@ -274,177 +268,200 @@ class _MihMyBusinessUserState extends State { } Widget getBody(double width) { - return MihSingleChildScroll( - child: Padding( - padding: MzansiInnovationHub.of(context)!.theme.screenType == "desktop" - ? EdgeInsets.symmetric(horizontal: width * 0.2) - : EdgeInsets.symmetric(horizontal: width * 0.075), - child: Column( - children: [ - MihForm( - formKey: _formKey, - formFields: [ - Center( - child: MihCircleAvatar( - imageFile: widget.userProPicImage, - width: 150, - editable: false, - fileNameController: fileNameController, - userSelectedfile: userPicFile, - frameColor: MihColors.getSecondaryColor( - MzansiInnovationHub.of(context)!.theme.mode == "Dark"), - backgroundColor: MihColors.getPrimaryColor( - MzansiInnovationHub.of(context)!.theme.mode == "Dark"), - onChange: (_) {}, - ), - ), - Visibility( - visible: false, - child: MihTextFormField( - fillColor: MihColors.getSecondaryColor( - MzansiInnovationHub.of(context)!.theme.mode == "Dark"), - inputColor: MihColors.getPrimaryColor( - MzansiInnovationHub.of(context)!.theme.mode == "Dark"), - controller: fileNameController, - multiLineInput: false, - requiredText: true, - readOnly: true, - hintText: "Selected File Name", - ), - ), - const SizedBox(height: 20), - MihTextFormField( - fillColor: MihColors.getSecondaryColor( - MzansiInnovationHub.of(context)!.theme.mode == "Dark"), - inputColor: MihColors.getPrimaryColor( - MzansiInnovationHub.of(context)!.theme.mode == "Dark"), - controller: titleTextController, - multiLineInput: false, - requiredText: true, - readOnly: false, - hintText: "Title", - validator: (value) { - return MihValidationServices().isEmpty(value); - }, - ), - const SizedBox(height: 10), - MihTextFormField( - fillColor: MihColors.getSecondaryColor( - MzansiInnovationHub.of(context)!.theme.mode == "Dark"), - inputColor: MihColors.getPrimaryColor( - MzansiInnovationHub.of(context)!.theme.mode == "Dark"), - controller: fnameController, - multiLineInput: false, - requiredText: true, - readOnly: true, - hintText: "First Name", - validator: (value) { - return MihValidationServices().isEmpty(value); - }, - ), - const SizedBox(height: 10), - MihTextFormField( - fillColor: MihColors.getSecondaryColor( - MzansiInnovationHub.of(context)!.theme.mode == "Dark"), - inputColor: MihColors.getPrimaryColor( - MzansiInnovationHub.of(context)!.theme.mode == "Dark"), - controller: lnameController, - multiLineInput: false, - requiredText: true, - readOnly: true, - hintText: "Surname", - validator: (value) { - return MihValidationServices().isEmpty(value); - }, - ), - const SizedBox(height: 10), - MihTextFormField( - fillColor: MihColors.getSecondaryColor( - MzansiInnovationHub.of(context)!.theme.mode == "Dark"), - inputColor: MihColors.getPrimaryColor( - MzansiInnovationHub.of(context)!.theme.mode == "Dark"), - controller: accessController, - multiLineInput: false, - requiredText: true, - hintText: "Access Level", - readOnly: true, - validator: (value) { - return MihValidationServices().isEmpty(value); - }, - ), - const SizedBox(height: 10), - Container( - width: 300, - alignment: Alignment.topLeft, - child: const Text( - "Signature:", - style: TextStyle( - fontSize: 18, - fontWeight: FontWeight.bold, - ), - ), - ), - Center( - child: MihImageDisplay( - imageFile: widget.userSignatureImage, - width: 300, - height: 200, - editable: true, - fileNameController: signtureController, - userSelectedfile: userSignatureFile, - onChange: (selectedFile) { - setState(() { - userSignatureFile = selectedFile; - }); - }, - ), - ), - const SizedBox(height: 10), - Visibility( - visible: false, - child: MihTextFormField( - fillColor: MihColors.getSecondaryColor( - MzansiInnovationHub.of(context)!.theme.mode == "Dark"), - inputColor: MihColors.getPrimaryColor( - MzansiInnovationHub.of(context)!.theme.mode == "Dark"), - controller: fileNameController, - multiLineInput: false, - requiredText: true, - readOnly: true, - hintText: "Selected Signature File", - ), - ), - const SizedBox(height: 15), - Center( - child: MihButton( - onPressed: () { - if (_formKey.currentState!.validate()) { - submitForm(); - } else { - MihAlertServices().formNotFilledCompletely(context); - } - }, - buttonColor: MihColors.getGreenColor( - MzansiInnovationHub.of(context)!.theme.mode == "Dark"), - width: 300, - child: Text( - "Update", - style: TextStyle( - color: MihColors.getPrimaryColor( + return Consumer( + builder: (BuildContext context, + MzansiProfileProvider mzansiProfileProvider, Widget? child) { + return MihSingleChildScroll( + child: Padding( + padding: + MzansiInnovationHub.of(context)!.theme.screenType == "desktop" + ? EdgeInsets.symmetric(horizontal: width * 0.2) + : EdgeInsets.symmetric(horizontal: width * 0.075), + child: Column( + children: [ + MihForm( + formKey: _formKey, + formFields: [ + Center( + child: MihCircleAvatar( + imageFile: mzansiProfileProvider.userProfilePicture, + width: 150, + editable: false, + fileNameController: fileNameController, + userSelectedfile: userPicFile, + frameColor: MihColors.getSecondaryColor( MzansiInnovationHub.of(context)!.theme.mode == "Dark"), - fontSize: 20, - fontWeight: FontWeight.bold, + backgroundColor: MihColors.getPrimaryColor( + MzansiInnovationHub.of(context)!.theme.mode == + "Dark"), + onChange: (_) {}, ), ), - ), + Visibility( + visible: false, + child: MihTextFormField( + fillColor: MihColors.getSecondaryColor( + MzansiInnovationHub.of(context)!.theme.mode == + "Dark"), + inputColor: MihColors.getPrimaryColor( + MzansiInnovationHub.of(context)!.theme.mode == + "Dark"), + controller: fileNameController, + multiLineInput: false, + requiredText: true, + readOnly: true, + hintText: "Selected File Name", + ), + ), + const SizedBox(height: 20), + MihTextFormField( + fillColor: MihColors.getSecondaryColor( + MzansiInnovationHub.of(context)!.theme.mode == + "Dark"), + inputColor: MihColors.getPrimaryColor( + MzansiInnovationHub.of(context)!.theme.mode == + "Dark"), + controller: titleTextController, + multiLineInput: false, + requiredText: true, + readOnly: false, + hintText: "Title", + validator: (value) { + return MihValidationServices().isEmpty(value); + }, + ), + const SizedBox(height: 10), + MihTextFormField( + fillColor: MihColors.getSecondaryColor( + MzansiInnovationHub.of(context)!.theme.mode == + "Dark"), + inputColor: MihColors.getPrimaryColor( + MzansiInnovationHub.of(context)!.theme.mode == + "Dark"), + controller: fnameController, + multiLineInput: false, + requiredText: true, + readOnly: true, + hintText: "First Name", + validator: (value) { + return MihValidationServices().isEmpty(value); + }, + ), + const SizedBox(height: 10), + MihTextFormField( + fillColor: MihColors.getSecondaryColor( + MzansiInnovationHub.of(context)!.theme.mode == + "Dark"), + inputColor: MihColors.getPrimaryColor( + MzansiInnovationHub.of(context)!.theme.mode == + "Dark"), + controller: lnameController, + multiLineInput: false, + requiredText: true, + readOnly: true, + hintText: "Surname", + validator: (value) { + return MihValidationServices().isEmpty(value); + }, + ), + const SizedBox(height: 10), + MihTextFormField( + fillColor: MihColors.getSecondaryColor( + MzansiInnovationHub.of(context)!.theme.mode == + "Dark"), + inputColor: MihColors.getPrimaryColor( + MzansiInnovationHub.of(context)!.theme.mode == + "Dark"), + controller: accessController, + multiLineInput: false, + requiredText: true, + hintText: "Access Level", + readOnly: true, + validator: (value) { + return MihValidationServices().isEmpty(value); + }, + ), + const SizedBox(height: 10), + Container( + width: 300, + alignment: Alignment.topLeft, + child: const Text( + "Signature:", + style: TextStyle( + fontSize: 18, + fontWeight: FontWeight.bold, + ), + ), + ), + Center( + child: MihImageDisplay( + imageFile: newSelectedSignaturePic != null + ? MemoryImage(newSelectedSignaturePic!.bytes!) + : mzansiProfileProvider.businessUserSignature, + width: 300, + height: 200, + editable: true, + fileNameController: signtureController, + userSelectedfile: newSelectedSignaturePic, + onChange: (selectedFile) { + setState(() { + newSelectedSignaturePic = selectedFile; + }); + }, + ), + ), + const SizedBox(height: 10), + Visibility( + visible: false, + child: MihTextFormField( + fillColor: MihColors.getSecondaryColor( + MzansiInnovationHub.of(context)!.theme.mode == + "Dark"), + inputColor: MihColors.getPrimaryColor( + MzansiInnovationHub.of(context)!.theme.mode == + "Dark"), + controller: fileNameController, + multiLineInput: false, + requiredText: true, + readOnly: true, + hintText: "Selected Signature File", + ), + ), + const SizedBox(height: 15), + Center( + child: MihButton( + onPressed: () { + if (_formKey.currentState!.validate()) { + submitForm(mzansiProfileProvider); + } else { + MihAlertServices().formNotFilledCompletely(context); + } + }, + buttonColor: MihColors.getGreenColor( + MzansiInnovationHub.of(context)!.theme.mode == + "Dark"), + width: 300, + child: Text( + "Update", + style: TextStyle( + color: MihColors.getPrimaryColor( + MzansiInnovationHub.of(context)!.theme.mode == + "Dark"), + fontSize: 20, + fontWeight: FontWeight.bold, + ), + ), + ), + ), + const SizedBox(height: 20), + ], ), - const SizedBox(height: 20), ], ), - ], - ), - ), + ), + ); + }, ); } } diff --git a/Frontend/lib/mih_packages/mzansi_profile/personal_profile/mzansi_profile.dart b/Frontend/lib/mih_packages/mzansi_profile/personal_profile/mzansi_profile.dart index 46dea907..e1692b51 100644 --- a/Frontend/lib/mih_packages/mzansi_profile/personal_profile/mzansi_profile.dart +++ b/Frontend/lib/mih_packages/mzansi_profile/personal_profile/mzansi_profile.dart @@ -2,16 +2,15 @@ import 'package:go_router/go_router.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_action.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_tools.dart'; -import 'package:mzansi_innovation_hub/mih_components/mih_objects/arguments.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_providers/mzansi_profile_provider.dart'; import 'package:mzansi_innovation_hub/mih_packages/mzansi_profile/personal_profile/package_tools/mih_personal_profile.dart'; import 'package:mzansi_innovation_hub/mih_packages/mzansi_profile/personal_profile/package_tools/mih_personal_settings.dart'; import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; class MzansiProfile extends StatefulWidget { - final AppProfileUpdateArguments arguments; const MzansiProfile({ super.key, - required this.arguments, }); @override @@ -19,8 +18,6 @@ class MzansiProfile extends StatefulWidget { } class _MzansiProfileState extends State { - int _selcetedIndex = 0; - @override Widget build(BuildContext context) { return MihPackage( @@ -28,11 +25,9 @@ class _MzansiProfileState extends State { appTools: getTools(), appBody: getToolBody(), appToolTitles: getToolTitle(), - selectedbodyIndex: _selcetedIndex, - onIndexChange: (newValue) { - setState(() { - _selcetedIndex = newValue; - }); + selectedbodyIndex: context.watch().personalIndex, + onIndexChange: (newIndex) { + context.read().setPersonalIndex(newIndex); }, ); } @@ -55,29 +50,25 @@ class _MzansiProfileState extends State { MihPackageTools getTools() { Map temp = {}; temp[const Icon(Icons.person)] = () { - setState(() { - _selcetedIndex = 0; - }); + context.read().setPersonalIndex(0); }; + // temp[const Icon(Icons.person)] = () { + // context.read().setPersonalIndex(1); + // }; temp[const Icon(Icons.settings)] = () { - setState(() { - _selcetedIndex = 1; - }); + context.read().setPersonalIndex(1); }; return MihPackageTools( tools: temp, - selcetedIndex: _selcetedIndex, + selcetedIndex: context.watch().personalIndex, ); } List getToolBody() { List toolBodies = []; - toolBodies.add(MihPersonalProfile( - arguments: widget.arguments, - )); - toolBodies.add(MihPersonalSettings( - signedInUser: widget.arguments.signedInUser, - )); + toolBodies.add(MihPersonalProfile()); + // toolBodies.add(MihPersonalProfile()); + toolBodies.add(MihPersonalSettings()); return toolBodies; } diff --git a/Frontend/lib/mih_packages/mzansi_profile/personal_profile/package_tools/mih_personal_profile.dart b/Frontend/lib/mih_packages/mzansi_profile/personal_profile/package_tools/mih_personal_profile.dart index 97f3900b..965ad532 100644 --- a/Frontend/lib/mih_packages/mzansi_profile/personal_profile/package_tools/mih_personal_profile.dart +++ b/Frontend/lib/mih_packages/mzansi_profile/personal_profile/package_tools/mih_personal_profile.dart @@ -1,146 +1,322 @@ +import 'package:file_picker/file_picker.dart'; +import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; +import 'package:ken_logger/ken_logger.dart'; import 'package:mzansi_innovation_hub/main.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_button.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_circle_avatar.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_form.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_alert.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_tool_body.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_window.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_single_child_scroll.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_text_form_field.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_toggle.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_error_message.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_loading_circle.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_providers/mzansi_profile_provider.dart'; import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart'; +import 'package:mzansi_innovation_hub/mih_config/mih_env.dart'; import 'package:mzansi_innovation_hub/mih_services/mih_alert_services.dart'; import 'package:mzansi_innovation_hub/mih_services/mih_file_services.dart'; import 'package:mzansi_innovation_hub/mih_services/mih_user_services.dart'; import 'package:mzansi_innovation_hub/mih_services/mih_validation_services.dart'; -import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_single_child_scroll.dart'; -import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_button.dart'; -import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_form.dart'; -import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_tool_body.dart'; -import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_alert.dart'; -import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_circle_avatar.dart'; -import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_text_form_field.dart'; -import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_toggle.dart'; -import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_error_message.dart'; -import 'package:mzansi_innovation_hub/mih_config/mih_env.dart'; -import 'package:mzansi_innovation_hub/mih_components/mih_objects/arguments.dart'; -import 'package:file_picker/file_picker.dart'; -import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; class MihPersonalProfile extends StatefulWidget { - final AppProfileUpdateArguments arguments; - const MihPersonalProfile({ - super.key, - required this.arguments, - }); + const MihPersonalProfile({super.key}); @override State createState() => _MihPersonalProfileState(); } class _MihPersonalProfileState extends State { - final proPicController = TextEditingController(); - final usernameController = TextEditingController(); - final fnameController = TextEditingController(); - final lnameController = TextEditingController(); - final purposeController = TextEditingController(); + TextEditingController proPicController = TextEditingController(); + TextEditingController usernameController = TextEditingController(); + TextEditingController fnameController = TextEditingController(); + TextEditingController lnameController = TextEditingController(); + TextEditingController purposeController = TextEditingController(); final ValueNotifier _counter = ValueNotifier(0); - PlatformFile? proPic; - late ImageProvider? propicPreview; - late bool originalProfileTypeIsBusiness; - late bool businessUser; - late String oldProPicName; - late String env; + PlatformFile? newSelectedProPic; + bool businessUser = false; + bool _controllersInitialized = false; + String env = ""; + String oldProPicName = ""; final _formKey = GlobalKey(); - void notUniqueAlert() { + void initializeControllers(MzansiProfileProvider mzansiProfileProvider) { + if (!_controllersInitialized && mzansiProfileProvider.user != null) { + usernameController.text = mzansiProfileProvider.user!.username; + fnameController.text = mzansiProfileProvider.user!.fname; + lnameController.text = mzansiProfileProvider.user!.lname; + purposeController.text = mzansiProfileProvider.user!.purpose; + proPicController.text = + mzansiProfileProvider.user!.pro_pic_path.isNotEmpty + ? mzansiProfileProvider.user!.pro_pic_path.split("/").last + : ""; + businessUser = mzansiProfileProvider.user!.type == "business"; + _controllersInitialized = true; + } + } + + void editProfileWindow(double width) { showDialog( context: context, - builder: (context) { - return MihPackageAlert( - alertIcon: Icon( - Icons.warning_amber_rounded, - size: 100, - color: MihColors.getRedColor( - MzansiInnovationHub.of(context)!.theme.mode == "Dark"), - ), - alertTitle: "Too Slow, That Username is Taken", - alertBody: const Text( - "The username you have entered is already taken by another member of Mzansi. Please choose a different username and try again.", - style: TextStyle( - fontSize: 15, + builder: (context) => Consumer( + builder: (BuildContext context, + MzansiProfileProvider mzansiProfileProvider, Widget? child) { + // usernameController.text = mzansiProfileProvider.user!.username; + // fnameController.text = mzansiProfileProvider.user!.fname; + // lnameController.text = mzansiProfileProvider.user!.lname; + // purposeController.text = mzansiProfileProvider.user!.purpose; + // proPicController.text = + // mzansiProfileProvider.user!.pro_pic_path.isNotEmpty + // ? mzansiProfileProvider.user!.pro_pic_path.split("/").last + // : ""; + initializeControllers(mzansiProfileProvider); + return MihPackageWindow( + fullscreen: false, + windowTitle: "Edit Profile", + onWindowTapClose: () { + Navigator.of(context).pop(); + }, + windowBody: Padding( + padding: + MzansiInnovationHub.of(context)!.theme.screenType == "desktop" + ? EdgeInsets.symmetric(horizontal: width * 0.05) + : EdgeInsets.symmetric(horizontal: width * 0), + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + MihForm( + formKey: _formKey, + formFields: [ + Center( + child: MihCircleAvatar( + imageFile: newSelectedProPic != null + ? MemoryImage(newSelectedProPic!.bytes!) + : mzansiProfileProvider.userProfilePicture, + width: 150, + editable: true, + fileNameController: proPicController, + userSelectedfile: newSelectedProPic, + frameColor: MihColors.getSecondaryColor( + MzansiInnovationHub.of(context)!.theme.mode == + "Dark"), + backgroundColor: MihColors.getPrimaryColor( + MzansiInnovationHub.of(context)!.theme.mode == + "Dark"), + onChange: (selectedImage) { + setState(() { + newSelectedProPic = selectedImage; + }); + }, + ), + ), + // const SizedBox(height: 25.0), + Visibility( + visible: false, + child: MihTextFormField( + fillColor: MihColors.getSecondaryColor( + MzansiInnovationHub.of(context)!.theme.mode == + "Dark"), + inputColor: MihColors.getPrimaryColor( + MzansiInnovationHub.of(context)!.theme.mode == + "Dark"), + controller: proPicController, + multiLineInput: false, + requiredText: true, + readOnly: true, + hintText: "Selected File Name", + ), + ), + const SizedBox(height: 10.0), + MihTextFormField( + fillColor: MihColors.getSecondaryColor( + MzansiInnovationHub.of(context)!.theme.mode == + "Dark"), + inputColor: MihColors.getPrimaryColor( + MzansiInnovationHub.of(context)!.theme.mode == + "Dark"), + controller: usernameController, + multiLineInput: false, + requiredText: true, + hintText: "Username", + validator: (value) { + return MihValidationServices() + .validateUsername(value); + }, + ), + const SizedBox(height: 10.0), + MihTextFormField( + fillColor: MihColors.getSecondaryColor( + MzansiInnovationHub.of(context)!.theme.mode == + "Dark"), + inputColor: MihColors.getPrimaryColor( + MzansiInnovationHub.of(context)!.theme.mode == + "Dark"), + controller: fnameController, + multiLineInput: false, + requiredText: true, + hintText: "First Name", + validator: (value) { + return MihValidationServices().isEmpty(value); + }, + ), + const SizedBox(height: 10.0), + MihTextFormField( + fillColor: MihColors.getSecondaryColor( + MzansiInnovationHub.of(context)!.theme.mode == + "Dark"), + inputColor: MihColors.getPrimaryColor( + MzansiInnovationHub.of(context)!.theme.mode == + "Dark"), + controller: lnameController, + multiLineInput: false, + requiredText: true, + hintText: "Last Name", + validator: (value) { + return MihValidationServices().isEmpty(value); + }, + ), + const SizedBox(height: 10.0), + MihTextFormField( + height: 250, + fillColor: MihColors.getSecondaryColor( + MzansiInnovationHub.of(context)!.theme.mode == + "Dark"), + inputColor: MihColors.getPrimaryColor( + MzansiInnovationHub.of(context)!.theme.mode == + "Dark"), + controller: purposeController, + multiLineInput: true, + requiredText: true, + hintText: "Your Personal Mission", + validator: (value) { + return MihValidationServices() + .validateLength(purposeController.text, 256); + }, + ), + SizedBox( + height: 15, + child: ValueListenableBuilder( + valueListenable: _counter, + builder: + (BuildContext context, int value, Widget? child) { + return Row( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: MainAxisAlignment.end, + children: [ + Text( + "$value", + style: TextStyle( + color: getPurposeLimitColor(256), + fontWeight: FontWeight.bold, + ), + ), + const SizedBox(width: 5), + Text( + "/256", + style: TextStyle( + color: getPurposeLimitColor(256), + fontWeight: FontWeight.bold, + ), + ), + ], + ); + }, + ), + ), + const SizedBox(height: 10.0), + MihToggle( + hintText: "Activate Business Account", + initialPostion: businessUser, + fillColor: MihColors.getSecondaryColor( + MzansiInnovationHub.of(context)!.theme.mode == + "Dark"), + secondaryFillColor: MihColors.getPrimaryColor( + MzansiInnovationHub.of(context)!.theme.mode == + "Dark"), + onChange: (value) { + setState(() { + businessUser = value; + }); + }, + ), + const SizedBox(height: 30.0), + Center( + child: MihButton( + onPressed: () { + //Add validation here + if (_formKey.currentState!.validate()) { + submitForm(mzansiProfileProvider); + } else { + MihAlertServices() + .formNotFilledCompletely(context); + } + }, + buttonColor: MihColors.getGreenColor( + MzansiInnovationHub.of(context)!.theme.mode == + "Dark"), + width: 300, + child: Text( + "Update", + style: TextStyle( + color: MihColors.getPrimaryColor( + MzansiInnovationHub.of(context)!.theme.mode == + "Dark"), + fontSize: 20, + fontWeight: FontWeight.bold, + ), + ), + ), + ), + ], + ), + ], + ), ), - ), - alertColour: MihColors.getRedColor( - MzansiInnovationHub.of(context)!.theme.mode == "Dark"), - ); - }, + ); + }, + ), ); } - Future submitForm() async { - // print("============\nsubmiit form\n================="); - if (widget.arguments.signedInUser.username != usernameController.text) { + Future submitForm(MzansiProfileProvider mzansiProfileProvider) async { + if (mzansiProfileProvider.user!.username != usernameController.text) { bool isUsernameUnique = await MihUserServices.isUsernameUnique( usernameController.text, context); - print("isUsernameUnique: $isUsernameUnique"); if (isUsernameUnique == false) { notUniqueAlert(); return; } } if (oldProPicName != proPicController.text) { - await uploadSelectedFile(proPic); + await uploadSelectedFile(mzansiProfileProvider, newSelectedProPic); } - await updateUserApiCall(); + await updateUserApiCall(mzansiProfileProvider); } - bool isBusinessUser() { - if (widget.arguments.signedInUser.type == "personal") { - return false; - } else { - return true; - } - } - - bool isUsernameValid(String username) { - return RegExp(r'^[a-zA-Z][a-zA-Z0-9_]{5,19}$').hasMatch(username); - } - - Future uploadSelectedFile(PlatformFile? file) async { + Future uploadSelectedFile( + MzansiProfileProvider mzansiProfileProvider, PlatformFile? file) async { var response = await MihFileApi.uploadFile( - widget.arguments.signedInUser.app_id, + mzansiProfileProvider.user!.app_id, env, "profile_files", file, context, ); if (response == 200) { - deleteFileApiCall(oldProPicName); + deleteFileApiCall(mzansiProfileProvider, oldProPicName); } else { internetConnectionPopUp(); } } - Future updateUserApiCall() async { - int responseCode = await MihUserServices().updateUserV2( - widget.arguments.signedInUser, - fnameController.text, - lnameController.text, - usernameController.text, - proPicController.text, - purposeController.text, - businessUser, - context, - ); - if (responseCode == 200) { - bool stayOnPersonalSide = true; - if (originalProfileTypeIsBusiness == false && businessUser == true) { - stayOnPersonalSide = false; - } - String message = "Your information has been updated successfully!"; - successPopUp(message, stayOnPersonalSide); - } else { - internetConnectionPopUp(); - } - } - - Future deleteFileApiCall(String filename) async { + Future deleteFileApiCall( + MzansiProfileProvider mzansiProfileProvider, String filename) async { var response = await MihFileApi.deleteFile( - widget.arguments.signedInUser.app_id, + mzansiProfileProvider.user!.app_id, env, "profile_files", filename, @@ -153,6 +329,53 @@ class _MihPersonalProfileState extends State { } } + Future updateUserApiCall( + MzansiProfileProvider mzansiProfileProvider) async { + int responseCode = await MihUserServices().updateUserV2( + mzansiProfileProvider.user!, + fnameController.text, + lnameController.text, + usernameController.text, + proPicController.text, + purposeController.text, + businessUser, + context, + ); + if (responseCode == 200) { + setState(() { + setProfileVariables(mzansiProfileProvider); + newSelectedProPic = null; + }); + bool stayOnPersonalSide = true; + // if (originalProfileTypeIsBusiness == false && businessUser == true) { + // stayOnPersonalSide = false; + // } + String message = "Your information has been updated successfully!"; + context.pop(); + successPopUp(message, stayOnPersonalSide); + } else { + internetConnectionPopUp(); + } + } + + Color getPurposeLimitColor(int limit) { + if (_counter.value <= limit) { + return MihColors.getSecondaryColor( + MzansiInnovationHub.of(context)!.theme.mode == "Dark"); + } else { + return MihColors.getRedColor( + MzansiInnovationHub.of(context)!.theme.mode == "Dark"); + } + } + + void setProfileVariables(MzansiProfileProvider mzansiProfileProvider) { + businessUser = mzansiProfileProvider.user!.type == "business"; + oldProPicName = mzansiProfileProvider.user!.pro_pic_path.isNotEmpty + ? mzansiProfileProvider.user!.pro_pic_path.split("/").last + : ""; + env = AppEnviroment.getEnv() == "Prod" ? env = "Prod" : env = "Dev"; + } + void successPopUp(String message, bool stayOnPersonalSide) { showDialog( context: context, @@ -180,10 +403,7 @@ class _MihPersonalProfileState extends State { Center( child: MihButton( onPressed: () { - context.goNamed( - 'mihHome', - extra: stayOnPersonalSide, - ); + context.pop(); }, buttonColor: MihColors.getGreenColor( MzansiInnovationHub.of(context)!.theme.mode == "Dark"), @@ -223,264 +443,31 @@ class _MihPersonalProfileState extends State { ); } - void usernamePopUp() { + void notUniqueAlert() { showDialog( context: context, builder: (context) { - return const MIHErrorMessage(errorType: "Invalid Username"); + return MihPackageAlert( + alertIcon: Icon( + Icons.warning_amber_rounded, + size: 100, + color: MihColors.getRedColor( + MzansiInnovationHub.of(context)!.theme.mode == "Dark"), + ), + alertTitle: "Too Slow, That Username is Taken", + alertBody: const Text( + "The username you have entered is already taken by another member of Mzansi. Please choose a different username and try again.", + style: TextStyle( + fontSize: 15, + ), + ), + alertColour: MihColors.getRedColor( + MzansiInnovationHub.of(context)!.theme.mode == "Dark"), + ); }, ); } - Color getPurposeLimitColor(int limit) { - if (_counter.value <= limit) { - return MihColors.getSecondaryColor( - MzansiInnovationHub.of(context)!.theme.mode == "Dark"); - } else { - return MihColors.getRedColor( - MzansiInnovationHub.of(context)!.theme.mode == "Dark"); - } - } - - void editProfileWindow(double width) { - showDialog( - context: context, - builder: (context) => MihPackageWindow( - fullscreen: false, - windowTitle: "Edit Profile", - onWindowTapClose: () { - Navigator.of(context).pop(); - }, - windowBody: Padding( - padding: - MzansiInnovationHub.of(context)!.theme.screenType == "desktop" - ? EdgeInsets.symmetric(horizontal: width * 0.05) - : EdgeInsets.symmetric(horizontal: width * 0), - child: Column( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - MihForm( - formKey: _formKey, - formFields: [ - Center( - child: MihCircleAvatar( - imageFile: propicPreview, - width: 150, - editable: true, - fileNameController: proPicController, - userSelectedfile: proPic, - frameColor: MihColors.getSecondaryColor( - MzansiInnovationHub.of(context)!.theme.mode == - "Dark"), - backgroundColor: MihColors.getPrimaryColor( - MzansiInnovationHub.of(context)!.theme.mode == - "Dark"), - onChange: (selectedImage) { - setState(() { - proPic = selectedImage; - }); - }, - ), - ), - // const SizedBox(height: 25.0), - Visibility( - visible: false, - child: MihTextFormField( - fillColor: MihColors.getSecondaryColor( - MzansiInnovationHub.of(context)!.theme.mode == - "Dark"), - inputColor: MihColors.getPrimaryColor( - MzansiInnovationHub.of(context)!.theme.mode == - "Dark"), - controller: proPicController, - multiLineInput: false, - requiredText: true, - readOnly: true, - hintText: "Selected File Name", - ), - ), - const SizedBox(height: 10.0), - MihTextFormField( - fillColor: MihColors.getSecondaryColor( - MzansiInnovationHub.of(context)!.theme.mode == "Dark"), - inputColor: MihColors.getPrimaryColor( - MzansiInnovationHub.of(context)!.theme.mode == "Dark"), - controller: usernameController, - multiLineInput: false, - requiredText: true, - hintText: "Username", - validator: (value) { - return MihValidationServices().validateUsername(value); - }, - ), - const SizedBox(height: 10.0), - MihTextFormField( - fillColor: MihColors.getSecondaryColor( - MzansiInnovationHub.of(context)!.theme.mode == "Dark"), - inputColor: MihColors.getPrimaryColor( - MzansiInnovationHub.of(context)!.theme.mode == "Dark"), - controller: fnameController, - multiLineInput: false, - requiredText: true, - hintText: "First Name", - validator: (value) { - return MihValidationServices().isEmpty(value); - }, - ), - const SizedBox(height: 10.0), - MihTextFormField( - fillColor: MihColors.getSecondaryColor( - MzansiInnovationHub.of(context)!.theme.mode == "Dark"), - inputColor: MihColors.getPrimaryColor( - MzansiInnovationHub.of(context)!.theme.mode == "Dark"), - controller: lnameController, - multiLineInput: false, - requiredText: true, - hintText: "Last Name", - validator: (value) { - return MihValidationServices().isEmpty(value); - }, - ), - const SizedBox(height: 10.0), - MihTextFormField( - height: 250, - fillColor: MihColors.getSecondaryColor( - MzansiInnovationHub.of(context)!.theme.mode == "Dark"), - inputColor: MihColors.getPrimaryColor( - MzansiInnovationHub.of(context)!.theme.mode == "Dark"), - controller: purposeController, - multiLineInput: true, - requiredText: true, - hintText: "Your Personal Mission", - validator: (value) { - return MihValidationServices() - .validateLength(purposeController.text, 256); - }, - ), - SizedBox( - height: 15, - child: ValueListenableBuilder( - valueListenable: _counter, - builder: - (BuildContext context, int value, Widget? child) { - return Row( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.end, - children: [ - Text( - "$value", - style: TextStyle( - color: getPurposeLimitColor(256), - fontWeight: FontWeight.bold, - ), - ), - const SizedBox(width: 5), - Text( - "/256", - style: TextStyle( - color: getPurposeLimitColor(256), - fontWeight: FontWeight.bold, - ), - ), - ], - ); - }, - ), - ), - const SizedBox(height: 10.0), - MihToggle( - hintText: "Activate Business Account", - initialPostion: businessUser, - fillColor: MihColors.getSecondaryColor( - MzansiInnovationHub.of(context)!.theme.mode == "Dark"), - secondaryFillColor: MihColors.getPrimaryColor( - MzansiInnovationHub.of(context)!.theme.mode == "Dark"), - onChange: (value) { - setState(() { - businessUser = value; - }); - }, - ), - const SizedBox(height: 30.0), - Center( - child: MihButton( - onPressed: () { - //Add validation here - if (_formKey.currentState!.validate()) { - submitForm(); - } else { - MihAlertServices().formNotFilledCompletely(context); - } - }, - buttonColor: MihColors.getGreenColor( - MzansiInnovationHub.of(context)!.theme.mode == - "Dark"), - width: 300, - child: Text( - "Update", - style: TextStyle( - color: MihColors.getPrimaryColor( - MzansiInnovationHub.of(context)!.theme.mode == - "Dark"), - fontSize: 20, - fontWeight: FontWeight.bold, - ), - ), - ), - ), - ], - ), - ], - ), - ), - ), - ); - } - - @override - void dispose() { - proPicController.dispose(); - usernameController.dispose(); - fnameController.dispose(); - lnameController.dispose(); - purposeController.dispose(); - super.dispose(); - } - - @override - void initState() { - super.initState(); - var proPicName = ""; - if (widget.arguments.signedInUser.pro_pic_path.isNotEmpty) { - proPicName = widget.arguments.signedInUser.pro_pic_path.split("/").last; - } - if (AppEnviroment.getEnv() == "Prod") { - env = "Prod"; - } else { - env = "Dev"; - } - purposeController.addListener(() { - setState(() { - _counter.value = purposeController.text.characters.length; - }); - }); - setState(() { - propicPreview = widget.arguments.propicFile; - oldProPicName = proPicName; - proPicController.text = proPicName; - fnameController.text = widget.arguments.signedInUser.fname; - lnameController.text = widget.arguments.signedInUser.lname; - usernameController.text = widget.arguments.signedInUser.username; - purposeController.text = widget.arguments.signedInUser.purpose; - businessUser = isBusinessUser(); - if (businessUser) { - originalProfileTypeIsBusiness = true; - } else { - originalProfileTypeIsBusiness = false; - } - }); - } - @override Widget build(BuildContext context) { double screenWidth = MediaQuery.of(context).size.width; @@ -492,84 +479,87 @@ class _MihPersonalProfileState extends State { } Widget getBody(double width) { - return Stack( - children: [ - MihSingleChildScroll( - child: Padding( - padding: - MzansiInnovationHub.of(context)!.theme.screenType == "desktop" - ? EdgeInsets.symmetric(horizontal: width * 0.2) - : EdgeInsets.symmetric(horizontal: width * 0.075), - child: Column( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Center( - child: MihCircleAvatar( - imageFile: propicPreview, - width: 150, - editable: false, - fileNameController: proPicController, - userSelectedfile: proPic, - frameColor: MihColors.getSecondaryColor( - MzansiInnovationHub.of(context)!.theme.mode == "Dark"), - backgroundColor: MihColors.getPrimaryColor( - MzansiInnovationHub.of(context)!.theme.mode == "Dark"), - onChange: (selectedImage) { - setState(() { - proPic = selectedImage; - }); - }, - ), - ), - FittedBox( - child: Text( - widget.arguments.signedInUser.username.isNotEmpty - ? widget.arguments.signedInUser.username - : "username", - style: TextStyle( - fontSize: 35, - fontWeight: FontWeight.bold, - color: MihColors.getSecondaryColor( + return Consumer( + builder: (BuildContext context, + MzansiProfileProvider mzansiProfileProvider, Widget? child) { + if (mzansiProfileProvider.user == null) { + //Change to new user flow + return Center( + child: Mihloadingcircle(), + ); + } + // else if (mzansiProfileProvider.user!.username.isEmpty) { + // editProfileWindow(width); + // } + else { + businessUser = mzansiProfileProvider.user!.type == "business"; + oldProPicName = mzansiProfileProvider.user!.pro_pic_path.isNotEmpty + ? mzansiProfileProvider.user!.pro_pic_path.split("/").last + : ""; + env = AppEnviroment.getEnv() == "Prod" ? env = "Prod" : env = "Dev"; + KenLogger.success( + mzansiProfileProvider.userProfilePicture.toString()); + return MihSingleChildScroll( + child: Padding( + padding: + MzansiInnovationHub.of(context)!.theme.screenType == "desktop" + ? EdgeInsets.symmetric(horizontal: width * 0.2) + : EdgeInsets.symmetric(horizontal: width * 0.075), + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Center( + child: MihCircleAvatar( + imageFile: mzansiProfileProvider.userProfilePicture, + width: 150, + editable: false, + fileNameController: proPicController, + userSelectedfile: newSelectedProPic, + frameColor: MihColors.getSecondaryColor( MzansiInnovationHub.of(context)!.theme.mode == "Dark"), - ), - ), - ), - FittedBox( - child: Text( - widget.arguments.signedInUser.fname.isNotEmpty - ? "${widget.arguments.signedInUser.fname} ${widget.arguments.signedInUser.lname}" - : "Name Surname", - style: TextStyle( - fontSize: 25, - fontWeight: FontWeight.bold, - color: MihColors.getSecondaryColor( + backgroundColor: MihColors.getPrimaryColor( MzansiInnovationHub.of(context)!.theme.mode == "Dark"), + onChange: (selectedImage) { + setState(() { + newSelectedProPic = selectedImage; + }); + }, + key: ValueKey(mzansiProfileProvider.userProfilePicUrl), ), ), - ), - FittedBox( - child: Text( - businessUser ? "Business" : "Personal", - style: TextStyle( - fontSize: 15, - fontWeight: FontWeight.bold, - color: MihColors.getSecondaryColor( - MzansiInnovationHub.of(context)!.theme.mode == - "Dark"), - ), - ), - ), - const SizedBox(height: 10.0), - Center( - child: SizedBox( - width: 700, + FittedBox( child: Text( - widget.arguments.signedInUser.purpose.isNotEmpty - ? widget.arguments.signedInUser.purpose - : "No Personal Mission added yet", - textAlign: TextAlign.center, + mzansiProfileProvider.user!.username.isNotEmpty + ? mzansiProfileProvider.user!.username + : "username", + style: TextStyle( + fontSize: 35, + fontWeight: FontWeight.bold, + color: MihColors.getSecondaryColor( + MzansiInnovationHub.of(context)!.theme.mode == + "Dark"), + ), + ), + ), + FittedBox( + child: Text( + mzansiProfileProvider.user!.fname.isNotEmpty + ? "${mzansiProfileProvider.user!.fname} ${mzansiProfileProvider.user!.lname}" + : "Name Surname", + style: TextStyle( + fontSize: 25, + fontWeight: FontWeight.bold, + color: MihColors.getSecondaryColor( + MzansiInnovationHub.of(context)!.theme.mode == + "Dark"), + ), + ), + ), + FittedBox( + child: Text( + businessUser == true ? "Business" : "Personal", style: TextStyle( fontSize: 15, fontWeight: FontWeight.bold, @@ -579,63 +569,56 @@ class _MihPersonalProfileState extends State { ), ), ), - ), - const SizedBox(height: 30.0), - Center( - child: MihButton( - onPressed: () { - // Connect with the user - editProfileWindow(width); - }, - buttonColor: MihColors.getGreenColor( - MzansiInnovationHub.of(context)!.theme.mode == "Dark"), - width: 300, - child: Text( - widget.arguments.signedInUser.username.isEmpty - ? "Set Up Profile" - : "Edit Profile", - style: TextStyle( - color: MihColors.getPrimaryColor( - MzansiInnovationHub.of(context)!.theme.mode == - "Dark"), - fontSize: 20, - fontWeight: FontWeight.bold, + const SizedBox(height: 10.0), + Center( + child: SizedBox( + width: 700, + child: Text( + mzansiProfileProvider.user!.purpose.isNotEmpty + ? mzansiProfileProvider.user!.purpose + : "No Personal Mission added yet", + textAlign: TextAlign.center, + style: TextStyle( + fontSize: 15, + fontWeight: FontWeight.bold, + color: MihColors.getSecondaryColor( + MzansiInnovationHub.of(context)!.theme.mode == + "Dark"), + ), ), ), ), - ), - ], + const SizedBox(height: 30.0), + Center( + child: MihButton( + onPressed: () { + // Connect with the user + editProfileWindow(width); + }, + buttonColor: MihColors.getGreenColor( + MzansiInnovationHub.of(context)!.theme.mode == + "Dark"), + width: 300, + child: Text( + mzansiProfileProvider.user!.username.isEmpty + ? "Set Up Profile" + : "Edit Profile", + style: TextStyle( + color: MihColors.getPrimaryColor( + MzansiInnovationHub.of(context)!.theme.mode == + "Dark"), + fontSize: 20, + fontWeight: FontWeight.bold, + ), + ), + ), + ), + ], + ), ), - ), - ), - // Positioned( - // right: 5, - // bottom: 10, - // child: MihFloatingMenu( - // animatedIcon: AnimatedIcons.menu_close, - // children: [ - // SpeedDialChild( - // child: Icon( - // Icons.edit, - // color: MihColors.getPrimaryColor(MzansiInnovationHub.of(context)!.theme.mode == "Dark"), - // ), - // label: "Edit Profile", - // labelBackgroundColor: - // MihColors.getGreenColor(MzansiInnovationHub.of(context)!.theme.mode == "Dark"), - // labelStyle: TextStyle( - // color: MihColors.getPrimaryColor(MzansiInnovationHub.of(context)!.theme.mode == "Dark"), - // fontWeight: FontWeight.bold, - // ), - // backgroundColor: - // MihColors.getGreenColor(MzansiInnovationHub.of(context)!.theme.mode == "Dark"), - // onTap: () { - // editProfileWindow(width); - // }, - // ) - // ], - // ), - // ), - ], + ); + } + }, ); } } diff --git a/Frontend/lib/mih_packages/mzansi_profile/personal_profile/package_tools/mih_personal_settings.dart b/Frontend/lib/mih_packages/mzansi_profile/personal_profile/package_tools/mih_personal_settings.dart index 7a7eeac9..1427074d 100644 --- a/Frontend/lib/mih_packages/mzansi_profile/personal_profile/package_tools/mih_personal_settings.dart +++ b/Frontend/lib/mih_packages/mzansi_profile/personal_profile/package_tools/mih_personal_settings.dart @@ -1,19 +1,18 @@ import 'package:mzansi_innovation_hub/main.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_providers/mzansi_profile_provider.dart'; import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart'; import 'package:mzansi_innovation_hub/mih_services/mih_user_services.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_single_child_scroll.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_button.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_tool_body.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_alert.dart'; -import 'package:mzansi_innovation_hub/mih_components/mih_objects/app_user.dart'; import 'package:flutter/material.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; +import 'package:provider/provider.dart'; class MihPersonalSettings extends StatefulWidget { - final AppUser signedInUser; const MihPersonalSettings({ super.key, - required this.signedInUser, }); @override @@ -35,75 +34,83 @@ class _MihPersonalSettingsState extends State { context: context, barrierDismissible: false, builder: (context) { - return MihPackageAlert( - alertIcon: Icon( - Icons.warning_amber_rounded, - size: 100, - color: MihColors.getRedColor( - MzansiInnovationHub.of(context)!.theme.mode == "Dark"), - ), - alertTitle: - "Are you sure you want to permanently delete your MIH account?", - alertBody: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Text( - "This action will remove all of your data, and it cannot be recovered. We understand this is a big decision, so please take a moment to double-check.\n\nIf you're certain, please confirm below. If you've changed your mind, you can simply close this window.", - style: TextStyle( - color: MihColors.getSecondaryColor( - MzansiInnovationHub.of(context)!.theme.mode == "Dark"), - fontSize: 15, - fontWeight: FontWeight.bold, - ), + return Consumer( + builder: (BuildContext context, + MzansiProfileProvider mzansiProfileProvider, Widget? child) { + return MihPackageAlert( + alertIcon: Icon( + Icons.warning_amber_rounded, + size: 100, + color: MihColors.getRedColor( + MzansiInnovationHub.of(context)!.theme.mode == "Dark"), ), - const SizedBox(height: 15), - Wrap( - spacing: 10, - runSpacing: 10, + alertTitle: + "Are you sure you want to permanently delete your MIH account?", + alertBody: Column( + mainAxisSize: MainAxisSize.min, children: [ - MihButton( - onPressed: () { - MihUserServices.deleteAccount( - widget.signedInUser.app_id, context); - }, - buttonColor: MihColors.getRedColor( - MzansiInnovationHub.of(context)!.theme.mode == "Dark"), - width: 300, - child: Text( - "Delete", - style: TextStyle( - color: MihColors.getPrimaryColor( - MzansiInnovationHub.of(context)!.theme.mode == - "Dark"), - fontSize: 20, - fontWeight: FontWeight.bold, - ), + Text( + "This action will remove all of your data, and it cannot be recovered. We understand this is a big decision, so please take a moment to double-check.\n\nIf you're certain, please confirm below. If you've changed your mind, you can simply close this window.", + style: TextStyle( + color: MihColors.getSecondaryColor( + MzansiInnovationHub.of(context)!.theme.mode == + "Dark"), + fontSize: 15, + fontWeight: FontWeight.bold, ), ), - MihButton( - onPressed: () { - Navigator.pop(context); - }, - buttonColor: MihColors.getGreenColor( - MzansiInnovationHub.of(context)!.theme.mode == "Dark"), - width: 300, - child: Text( - "Cancel", - style: TextStyle( - color: MihColors.getPrimaryColor( + const SizedBox(height: 15), + Wrap( + spacing: 10, + runSpacing: 10, + children: [ + MihButton( + onPressed: () { + MihUserServices.deleteAccount( + mzansiProfileProvider, context); + }, + buttonColor: MihColors.getRedColor( MzansiInnovationHub.of(context)!.theme.mode == "Dark"), - fontSize: 20, - fontWeight: FontWeight.bold, + width: 300, + child: Text( + "Delete", + style: TextStyle( + color: MihColors.getPrimaryColor( + MzansiInnovationHub.of(context)!.theme.mode == + "Dark"), + fontSize: 20, + fontWeight: FontWeight.bold, + ), + ), ), - ), - ), + MihButton( + onPressed: () { + Navigator.pop(context); + }, + buttonColor: MihColors.getGreenColor( + MzansiInnovationHub.of(context)!.theme.mode == + "Dark"), + width: 300, + child: Text( + "Cancel", + style: TextStyle( + color: MihColors.getPrimaryColor( + MzansiInnovationHub.of(context)!.theme.mode == + "Dark"), + fontSize: 20, + fontWeight: FontWeight.bold, + ), + ), + ), + ], + ) ], - ) - ], - ), - alertColour: MihColors.getRedColor( - MzansiInnovationHub.of(context)!.theme.mode == "Dark"), + ), + alertColour: MihColors.getRedColor( + MzansiInnovationHub.of(context)!.theme.mode == "Dark"), + ); + }, ); }, ); diff --git a/Frontend/lib/mih_services/mih_business_details_services.dart b/Frontend/lib/mih_services/mih_business_details_services.dart index b59840c1..6b976cb9 100644 --- a/Frontend/lib/mih_services/mih_business_details_services.dart +++ b/Frontend/lib/mih_services/mih_business_details_services.dart @@ -1,10 +1,15 @@ import 'dart:convert'; +import 'package:go_router/go_router.dart'; import 'package:http/http.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_objects/business.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_loading_circle.dart'; import 'package:flutter/material.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_providers/mzansi_profile_provider.dart'; import 'package:mzansi_innovation_hub/mih_config/mih_env.dart'; +import 'package:mzansi_innovation_hub/mih_services/mih_file_services.dart'; +import 'package:provider/provider.dart'; +import 'package:supertokens_flutter/supertokens.dart'; import '../mih_components/mih_pop_up_messages/mih_error_message.dart'; import 'package:supertokens_flutter/http.dart' as http; @@ -75,8 +80,9 @@ class MihBusinessDetailsServices { } Future getBusinessDetailsByUser( - String app_id, + BuildContext context, ) async { + String app_id = await SuperTokens.getUserId(); var response = await http.get( Uri.parse("${AppEnviroment.baseApiUrl}/business/app_id/$app_id"), headers: { @@ -86,7 +92,9 @@ class MihBusinessDetailsServices { if (response.statusCode == 200) { String body = response.body; var jsonBody = jsonDecode(body); - return Business.fromJson(jsonBody); + Business? business = Business.fromJson(jsonBody); + context.read().setBusiness(newBusiness: business); + return business; } else { return null; } @@ -175,6 +183,7 @@ class MihBusinessDetailsServices { String businessWebsite, String businessRating, String businessMissionVision, + MzansiProfileProvider provider, BuildContext context, ) async { showDialog( @@ -183,6 +192,7 @@ class MihBusinessDetailsServices { return const Mihloadingcircle(); }, ); + var filePath = "$business_id/business_files/$business_logo_name"; var response = await http.put( Uri.parse("${AppEnviroment.baseApiUrl}/business/update/v2/"), headers: { @@ -194,7 +204,7 @@ class MihBusinessDetailsServices { "type": business_type, "registration_no": business_registration_no, "logo_name": business_logo_name, - "logo_path": "$business_id/business_files/$business_logo_name", + "logo_path": filePath, "contact_no": business_phone_number, "bus_email": business_email, "gps_location": business_location, @@ -205,8 +215,29 @@ class MihBusinessDetailsServices { "mission_vision": businessMissionVision, }), ); - Navigator.of(context).pop(); + context.pop(); if (response.statusCode == 200) { + provider.setBusiness( + newBusiness: Business( + business_id, + business_name, + business_type, + business_registration_no, + business_logo_name, + filePath, + business_phone_number, + business_email, + provider.business!.app_id, + business_location, + business_practice_no, + business_vat_no, + businessWebsite, + businessRating, + businessMissionVision, + ), + ); + String newProPicUrl = await MihFileApi.getMinioFileUrl(filePath, context); + provider.setBusinessProfilePicUrl(newProPicUrl); return 200; } else { return 500; diff --git a/Frontend/lib/mih_services/mih_file_services.dart b/Frontend/lib/mih_services/mih_file_services.dart index fa983869..88746f66 100644 --- a/Frontend/lib/mih_services/mih_file_services.dart +++ b/Frontend/lib/mih_services/mih_file_services.dart @@ -1,6 +1,7 @@ import 'dart:convert'; import 'package:file_picker/file_picker.dart'; +import 'package:go_router/go_router.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_error_message.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_loading_circle.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_success_message.dart'; @@ -75,7 +76,7 @@ class MihFileApi { request.files.add(await http2.MultipartFile.fromBytes('file', file!.bytes!, filename: file.name.replaceAll(RegExp(r' '), '-'))); var response = await request.send(); - Navigator.of(context).pop(); // Pop loading dialog + context.pop(); // Pop loading dialog return response.statusCode; } @@ -99,7 +100,7 @@ class MihFileApi { "env": env, }), ); - Navigator.of(context).pop(); // Pop loading dialog + context.pop(); // Pop loading dialog return response.statusCode; } diff --git a/Frontend/lib/mih_services/mih_my_business_user_services.dart b/Frontend/lib/mih_services/mih_my_business_user_services.dart index e1481493..5b0f5349 100644 --- a/Frontend/lib/mih_services/mih_my_business_user_services.dart +++ b/Frontend/lib/mih_services/mih_my_business_user_services.dart @@ -1,15 +1,22 @@ import 'dart:convert'; +import 'package:go_router/go_router.dart'; +import 'package:ken_logger/ken_logger.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_objects/business_user.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_loading_circle.dart'; import 'package:flutter/material.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_providers/mzansi_profile_provider.dart'; import 'package:mzansi_innovation_hub/mih_config/mih_env.dart'; +import 'package:mzansi_innovation_hub/mih_services/mih_file_services.dart'; +import 'package:provider/provider.dart'; +import 'package:supertokens_flutter/supertokens.dart'; import '../mih_components/mih_pop_up_messages/mih_error_message.dart'; import 'package:supertokens_flutter/http.dart' as http; class MihMyBusinessUserServices { Future getBusinessUser( - String app_id, + BuildContext context, ) async { + String app_id = await SuperTokens.getUserId(); var response = await http.get( Uri.parse("${AppEnviroment.baseApiUrl}/business-user/$app_id"), headers: { @@ -17,7 +24,13 @@ class MihMyBusinessUserServices { }, ); if (response.statusCode == 200) { - return BusinessUser.fromJson(jsonDecode(response.body)); + KenLogger.success(response.body); + BusinessUser? businessUser = + BusinessUser.fromJson(jsonDecode(response.body)); + context + .read() + .setBusinessUser(newBusinessUser: businessUser); + return businessUser; } else { return null; } @@ -51,7 +64,7 @@ class MihMyBusinessUserServices { "access": access, }), ); - Navigator.of(context).pop(); + context.pop(); if (response.statusCode == 201) { return 201; } else { @@ -67,6 +80,7 @@ class MihMyBusinessUserServices { String bUserTitle, String bUserAccess, String signatureFileName, + MzansiProfileProvider provider, BuildContext context, ) async { showDialog( @@ -75,6 +89,7 @@ class MihMyBusinessUserServices { return const Mihloadingcircle(); }, ); + var filePath = "$app_id/business_files/$signatureFileName"; var response = await http.put( Uri.parse("${AppEnviroment.baseApiUrl}/business-user/update/"), headers: { @@ -84,32 +99,26 @@ class MihMyBusinessUserServices { "business_id": business_id, "app_id": app_id, "signature": signatureFileName, - "sig_path": "$app_id/business_files/$signatureFileName", + "sig_path": filePath, "title": bUserTitle, "access": bUserAccess, }), ); - // var response = await http.put( - // Uri.parse("${AppEnviroment.baseApiUrl}/business/update/"), - // headers: { - // "Content-Type": "application/json; charset=UTF-8" - // }, - // body: jsonEncode({ - // "business_id": business_id, - // "Name": business_name, - // "type": business_type, - // "registration_no": business_registration_no, - // "logo_name": business_logo_name, - // "logo_path": "$business_id/business_files/$business_logo_name", - // "contact_no": business_phone_number, - // "bus_email": business_email, - // "gps_location": business_location, - // "practice_no": business_practice_no, - // "vat_no": business_vat_no, - // }), - // ); - Navigator.of(context).pop(); + context.pop(); if (response.statusCode == 200) { + provider.setBusinessUser( + newBusinessUser: BusinessUser( + provider.businessUser!.idbusiness_users, + business_id, + app_id, + signatureFileName, + filePath, + bUserTitle, + bUserAccess, + ), + ); + String newProPicUrl = await MihFileApi.getMinioFileUrl(filePath, context); + provider.setBusinessUserSignatureUrl(newProPicUrl); return 200; } else { internetConnectionPopUp(context); diff --git a/Frontend/lib/mih_services/mih_service_calls.dart b/Frontend/lib/mih_services/mih_service_calls.dart index 411ec8c7..9375c2ec 100644 --- a/Frontend/lib/mih_services/mih_service_calls.dart +++ b/Frontend/lib/mih_services/mih_service_calls.dart @@ -61,7 +61,7 @@ class MIHApiCalls { // Get Userdata var uid = await SuperTokens.getUserId(); - AppUser? user = await MihUserServices().getUserDetails(uid, context); + AppUser? user = await MihUserServices().getUserDetails(context); if (user != null) { userData = user; } else { @@ -70,7 +70,7 @@ class MIHApiCalls { // Get BusinessUserdata BusinessUser? businessUser = - await MihMyBusinessUserServices().getBusinessUser(uid); + await MihMyBusinessUserServices().getBusinessUser(context); if (businessUser != null) { bUserData = businessUser; } else { @@ -79,9 +79,7 @@ class MIHApiCalls { // Get Businessdata Business? business = - await MihBusinessDetailsServices().getBusinessDetailsByUser( - uid, - ); + await MihBusinessDetailsServices().getBusinessDetailsByUser(context); if (business != null) { busData = business; } else { diff --git a/Frontend/lib/mih_services/mih_user_consent_services.dart b/Frontend/lib/mih_services/mih_user_consent_services.dart index f4246916..f55424f6 100644 --- a/Frontend/lib/mih_services/mih_user_consent_services.dart +++ b/Frontend/lib/mih_services/mih_user_consent_services.dart @@ -1,31 +1,39 @@ import 'dart:convert'; +import 'package:flutter/material.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_objects/user_consent.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_providers/mzansi_profile_provider.dart'; import 'package:mzansi_innovation_hub/mih_config/mih_env.dart'; +import 'package:provider/provider.dart'; import 'package:supertokens_flutter/http.dart' as http; import 'package:supertokens_flutter/supertokens.dart'; class MihUserConsentServices { - Future getUserConsentStatus() async { + Future getUserConsentStatus( + BuildContext context, + ) async { var app_id = await SuperTokens.getUserId(); final response = await http.get( Uri.parse("${AppEnviroment.baseApiUrl}/user-consent/user/$app_id")); if (response.statusCode == 200) { Map userMap = jsonDecode(response.body); UserConsent userConsent = UserConsent.fromJson(userMap); - return userConsent; - } else { - return null; + context.read().setUserConsent(userConsent); + // return userConsent; } + // else { + // return null; + // } } Future insertUserConsentStatus( - String app_id, String latestPrivacyPolicyDate, String latestTermOfServiceDate, + MzansiProfileProvider provider, + BuildContext context, ) async { UserConsent userConsent = UserConsent( - app_id: app_id, + app_id: provider.user!.app_id, privacy_policy_accepted: DateTime.parse(latestPrivacyPolicyDate), terms_of_services_accepted: DateTime.parse(latestTermOfServiceDate), ); @@ -34,16 +42,18 @@ class MihUserConsentServices { headers: {"Content-Type": "application/json"}, body: jsonEncode(userConsent.toJson()), ); + provider.setUserConsent(userConsent); return response.statusCode; } Future updateUserConsentStatus( - String app_id, String latestPrivacyPolicyDate, String latestTermOfServiceDate, + MzansiProfileProvider provider, + BuildContext context, ) async { UserConsent userConsent = UserConsent( - app_id: app_id, + app_id: provider.user!.app_id, privacy_policy_accepted: DateTime.parse(latestPrivacyPolicyDate), terms_of_services_accepted: DateTime.parse(latestTermOfServiceDate), ); @@ -52,6 +62,7 @@ class MihUserConsentServices { headers: {"Content-Type": "application/json"}, body: jsonEncode(userConsent.toJson()), ); + provider.setUserConsent(userConsent); return response.statusCode; } } diff --git a/Frontend/lib/mih_services/mih_user_services.dart b/Frontend/lib/mih_services/mih_user_services.dart index 44f83c87..ff74e988 100644 --- a/Frontend/lib/mih_services/mih_user_services.dart +++ b/Frontend/lib/mih_services/mih_user_services.dart @@ -7,9 +7,12 @@ import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_ import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_alert.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_error_message.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_loading_circle.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_providers/mzansi_profile_provider.dart'; import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart'; import 'package:mzansi_innovation_hub/mih_config/mih_env.dart'; import 'package:flutter/material.dart'; +import 'package:mzansi_innovation_hub/mih_services/mih_file_services.dart'; +import 'package:provider/provider.dart'; import 'package:supertokens_flutter/http.dart' as http; import 'package:supertokens_flutter/supertokens.dart'; @@ -94,9 +97,9 @@ class MihUserServices { } Future getUserDetails( - String app_id, BuildContext context, ) async { + String app_id = await SuperTokens.getUserId(); var response = await http.get( Uri.parse("${AppEnviroment.baseApiUrl}/user/$app_id"), headers: { @@ -107,6 +110,9 @@ class MihUserServices { if (response.statusCode == 200) { String body = response.body; var jsonBody = jsonDecode(body); + context.read().setUser( + newUser: AppUser.fromJson(jsonBody), + ); return AppUser.fromJson(jsonBody); } else { return null; @@ -147,6 +153,21 @@ class MihUserServices { }), ); if (response.statusCode == 200) { + context.read().setUser( + newUser: AppUser( + signedInUser.idUser, + signedInUser.email, + firstName, + lastName, + profileType, + signedInUser.app_id, + username, + filePath, + purpose, + ), + ); + String newProPicUrl = await MihFileApi.getMinioFileUrl(filePath, context); + context.read().setUserProfilePicUrl(newProPicUrl); return response.statusCode; } else { return response.statusCode; @@ -192,7 +213,7 @@ class MihUserServices { } static Future deleteAccount( - String app_id, + MzansiProfileProvider provider, BuildContext context, ) async { loadingPopUp(context); @@ -202,7 +223,7 @@ class MihUserServices { "Content-Type": "application/json; charset=UTF-8" }, body: jsonEncode({ - "app_id": app_id, + "app_id": provider.user!.app_id, "env": AppEnviroment.getEnv(), }), ); @@ -212,18 +233,12 @@ class MihUserServices { print(error); }); if (await SuperTokens.doesSessionExist() == false) { - // Navigator.of(context).pop(); // Pop loading dialog - // Navigator.of(context).pop(); // Pop delete account dialog - // Navigator.of(context).pop(); // Pop Mzansi Profile - // Navigator.of(context).popAndPushNamed( - // '/', - // arguments: AuthArguments(true, false), - // ); //Pop and push to login page successPopUp( "Account Deleted Successfully", "Your account has been successfully deleted. We are sorry to see you go, but we respect your decision.", context, ); // Show success message. + provider.dispose(); } } else { Navigator.of(context).pop(); // Pop loading dialog diff --git a/backend/routers/users.py b/backend/routers/users.py index 5aede146..a065e41b 100644 --- a/backend/routers/users.py +++ b/backend/routers/users.py @@ -249,6 +249,7 @@ async def delete_users_data_by_app_id(itemRequest: userDeleteRequest, session: "DELETE FROM patient_manager.patient_notes where app_id = %s", "DELETE FROM patient_manager.patient_files where app_id = %s", "DELETE FROM patient_manager.claim_statement_file where app_id = %s", + "DELETE FROM app_data.user_consent where app_id = %s", "DELETE FROM app_data.users where app_id = %s", ] # Delete user from all tables