diff --git a/Frontend/android/app/src/main/AndroidManifest.xml b/Frontend/android/app/src/main/AndroidManifest.xml index 29db9a4d..95a24205 100644 --- a/Frontend/android/app/src/main/AndroidManifest.xml +++ b/Frontend/android/app/src/main/AndroidManifest.xml @@ -2,6 +2,7 @@ xmlns:tools="http://schemas.android.com/tools"> + @@ -42,6 +43,18 @@ + + + + + + + + + diff --git a/Frontend/android/app/src/main/res/drawable-hdpi-v31/android12branding.png b/Frontend/android/app/src/main/res/drawable-hdpi-v31/android12branding.png index 20c34e66..24b3d384 100644 Binary files a/Frontend/android/app/src/main/res/drawable-hdpi-v31/android12branding.png and b/Frontend/android/app/src/main/res/drawable-hdpi-v31/android12branding.png differ diff --git a/Frontend/android/app/src/main/res/drawable-hdpi/android12splash.png b/Frontend/android/app/src/main/res/drawable-hdpi/android12splash.png index 5ca29860..c8b90f04 100644 Binary files a/Frontend/android/app/src/main/res/drawable-hdpi/android12splash.png and b/Frontend/android/app/src/main/res/drawable-hdpi/android12splash.png differ diff --git a/Frontend/android/app/src/main/res/drawable-hdpi/branding.png b/Frontend/android/app/src/main/res/drawable-hdpi/branding.png index 20c34e66..24b3d384 100644 Binary files a/Frontend/android/app/src/main/res/drawable-hdpi/branding.png and b/Frontend/android/app/src/main/res/drawable-hdpi/branding.png differ diff --git a/Frontend/android/app/src/main/res/drawable-hdpi/splash.png b/Frontend/android/app/src/main/res/drawable-hdpi/splash.png index b18ce424..c8b90f04 100644 Binary files a/Frontend/android/app/src/main/res/drawable-hdpi/splash.png and b/Frontend/android/app/src/main/res/drawable-hdpi/splash.png differ diff --git a/Frontend/android/app/src/main/res/drawable-mdpi-v31/android12branding.png b/Frontend/android/app/src/main/res/drawable-mdpi-v31/android12branding.png index e1061999..c82d522c 100644 Binary files a/Frontend/android/app/src/main/res/drawable-mdpi-v31/android12branding.png and b/Frontend/android/app/src/main/res/drawable-mdpi-v31/android12branding.png differ diff --git a/Frontend/android/app/src/main/res/drawable-mdpi/android12splash.png b/Frontend/android/app/src/main/res/drawable-mdpi/android12splash.png index ddb164e6..53e4ced6 100644 Binary files a/Frontend/android/app/src/main/res/drawable-mdpi/android12splash.png and b/Frontend/android/app/src/main/res/drawable-mdpi/android12splash.png differ diff --git a/Frontend/android/app/src/main/res/drawable-mdpi/branding.png b/Frontend/android/app/src/main/res/drawable-mdpi/branding.png index e1061999..c82d522c 100644 Binary files a/Frontend/android/app/src/main/res/drawable-mdpi/branding.png and b/Frontend/android/app/src/main/res/drawable-mdpi/branding.png differ diff --git a/Frontend/android/app/src/main/res/drawable-mdpi/splash.png b/Frontend/android/app/src/main/res/drawable-mdpi/splash.png index 111b07d4..53e4ced6 100644 Binary files a/Frontend/android/app/src/main/res/drawable-mdpi/splash.png and b/Frontend/android/app/src/main/res/drawable-mdpi/splash.png differ diff --git a/Frontend/android/app/src/main/res/drawable-night-hdpi-v31/android12branding.png b/Frontend/android/app/src/main/res/drawable-night-hdpi-v31/android12branding.png index 20c34e66..24b3d384 100644 Binary files a/Frontend/android/app/src/main/res/drawable-night-hdpi-v31/android12branding.png and b/Frontend/android/app/src/main/res/drawable-night-hdpi-v31/android12branding.png differ diff --git a/Frontend/android/app/src/main/res/drawable-night-hdpi/android12splash.png b/Frontend/android/app/src/main/res/drawable-night-hdpi/android12splash.png index 5ca29860..c8b90f04 100644 Binary files a/Frontend/android/app/src/main/res/drawable-night-hdpi/android12splash.png and b/Frontend/android/app/src/main/res/drawable-night-hdpi/android12splash.png differ diff --git a/Frontend/android/app/src/main/res/drawable-night-mdpi-v31/android12branding.png b/Frontend/android/app/src/main/res/drawable-night-mdpi-v31/android12branding.png index e1061999..c82d522c 100644 Binary files a/Frontend/android/app/src/main/res/drawable-night-mdpi-v31/android12branding.png and b/Frontend/android/app/src/main/res/drawable-night-mdpi-v31/android12branding.png differ diff --git a/Frontend/android/app/src/main/res/drawable-night-mdpi/android12splash.png b/Frontend/android/app/src/main/res/drawable-night-mdpi/android12splash.png index ddb164e6..53e4ced6 100644 Binary files a/Frontend/android/app/src/main/res/drawable-night-mdpi/android12splash.png and b/Frontend/android/app/src/main/res/drawable-night-mdpi/android12splash.png differ diff --git a/Frontend/android/app/src/main/res/drawable-night-xhdpi-v31/android12branding.png b/Frontend/android/app/src/main/res/drawable-night-xhdpi-v31/android12branding.png index 6bf213bd..7d34377d 100644 Binary files a/Frontend/android/app/src/main/res/drawable-night-xhdpi-v31/android12branding.png and b/Frontend/android/app/src/main/res/drawable-night-xhdpi-v31/android12branding.png differ diff --git a/Frontend/android/app/src/main/res/drawable-night-xhdpi/android12splash.png b/Frontend/android/app/src/main/res/drawable-night-xhdpi/android12splash.png index a288538c..5071f829 100644 Binary files a/Frontend/android/app/src/main/res/drawable-night-xhdpi/android12splash.png and b/Frontend/android/app/src/main/res/drawable-night-xhdpi/android12splash.png differ diff --git a/Frontend/android/app/src/main/res/drawable-night-xxhdpi-v31/android12branding.png b/Frontend/android/app/src/main/res/drawable-night-xxhdpi-v31/android12branding.png index abac6898..844f6592 100644 Binary files a/Frontend/android/app/src/main/res/drawable-night-xxhdpi-v31/android12branding.png and b/Frontend/android/app/src/main/res/drawable-night-xxhdpi-v31/android12branding.png differ diff --git a/Frontend/android/app/src/main/res/drawable-night-xxhdpi/android12splash.png b/Frontend/android/app/src/main/res/drawable-night-xxhdpi/android12splash.png index 262763a1..c198ddbf 100644 Binary files a/Frontend/android/app/src/main/res/drawable-night-xxhdpi/android12splash.png and b/Frontend/android/app/src/main/res/drawable-night-xxhdpi/android12splash.png differ diff --git a/Frontend/android/app/src/main/res/drawable-night-xxxhdpi-v31/android12branding.png b/Frontend/android/app/src/main/res/drawable-night-xxxhdpi-v31/android12branding.png index 041582d2..f2d86a92 100644 Binary files a/Frontend/android/app/src/main/res/drawable-night-xxxhdpi-v31/android12branding.png and b/Frontend/android/app/src/main/res/drawable-night-xxxhdpi-v31/android12branding.png differ diff --git a/Frontend/android/app/src/main/res/drawable-night-xxxhdpi/android12splash.png b/Frontend/android/app/src/main/res/drawable-night-xxxhdpi/android12splash.png index aa4e2c8f..a2709e12 100644 Binary files a/Frontend/android/app/src/main/res/drawable-night-xxxhdpi/android12splash.png and b/Frontend/android/app/src/main/res/drawable-night-xxxhdpi/android12splash.png differ diff --git a/Frontend/android/app/src/main/res/drawable-v21/background.png b/Frontend/android/app/src/main/res/drawable-v21/background.png index 47cd7af3..83987bcc 100644 Binary files a/Frontend/android/app/src/main/res/drawable-v21/background.png and b/Frontend/android/app/src/main/res/drawable-v21/background.png differ diff --git a/Frontend/android/app/src/main/res/drawable-xhdpi-v31/android12branding.png b/Frontend/android/app/src/main/res/drawable-xhdpi-v31/android12branding.png index 6bf213bd..7d34377d 100644 Binary files a/Frontend/android/app/src/main/res/drawable-xhdpi-v31/android12branding.png and b/Frontend/android/app/src/main/res/drawable-xhdpi-v31/android12branding.png differ diff --git a/Frontend/android/app/src/main/res/drawable-xhdpi/android12splash.png b/Frontend/android/app/src/main/res/drawable-xhdpi/android12splash.png index a288538c..5071f829 100644 Binary files a/Frontend/android/app/src/main/res/drawable-xhdpi/android12splash.png and b/Frontend/android/app/src/main/res/drawable-xhdpi/android12splash.png differ diff --git a/Frontend/android/app/src/main/res/drawable-xhdpi/branding.png b/Frontend/android/app/src/main/res/drawable-xhdpi/branding.png index 6bf213bd..7d34377d 100644 Binary files a/Frontend/android/app/src/main/res/drawable-xhdpi/branding.png and b/Frontend/android/app/src/main/res/drawable-xhdpi/branding.png differ diff --git a/Frontend/android/app/src/main/res/drawable-xhdpi/splash.png b/Frontend/android/app/src/main/res/drawable-xhdpi/splash.png index 1b05f2f1..5071f829 100644 Binary files a/Frontend/android/app/src/main/res/drawable-xhdpi/splash.png and b/Frontend/android/app/src/main/res/drawable-xhdpi/splash.png differ diff --git a/Frontend/android/app/src/main/res/drawable-xxhdpi-v31/android12branding.png b/Frontend/android/app/src/main/res/drawable-xxhdpi-v31/android12branding.png index abac6898..844f6592 100644 Binary files a/Frontend/android/app/src/main/res/drawable-xxhdpi-v31/android12branding.png and b/Frontend/android/app/src/main/res/drawable-xxhdpi-v31/android12branding.png differ diff --git a/Frontend/android/app/src/main/res/drawable-xxhdpi/android12splash.png b/Frontend/android/app/src/main/res/drawable-xxhdpi/android12splash.png index 262763a1..c198ddbf 100644 Binary files a/Frontend/android/app/src/main/res/drawable-xxhdpi/android12splash.png and b/Frontend/android/app/src/main/res/drawable-xxhdpi/android12splash.png differ diff --git a/Frontend/android/app/src/main/res/drawable-xxhdpi/branding.png b/Frontend/android/app/src/main/res/drawable-xxhdpi/branding.png index abac6898..844f6592 100644 Binary files a/Frontend/android/app/src/main/res/drawable-xxhdpi/branding.png and b/Frontend/android/app/src/main/res/drawable-xxhdpi/branding.png differ diff --git a/Frontend/android/app/src/main/res/drawable-xxhdpi/splash.png b/Frontend/android/app/src/main/res/drawable-xxhdpi/splash.png index ab6a0135..c198ddbf 100644 Binary files a/Frontend/android/app/src/main/res/drawable-xxhdpi/splash.png and b/Frontend/android/app/src/main/res/drawable-xxhdpi/splash.png differ diff --git a/Frontend/android/app/src/main/res/drawable-xxxhdpi-v31/android12branding.png b/Frontend/android/app/src/main/res/drawable-xxxhdpi-v31/android12branding.png index 041582d2..f2d86a92 100644 Binary files a/Frontend/android/app/src/main/res/drawable-xxxhdpi-v31/android12branding.png and b/Frontend/android/app/src/main/res/drawable-xxxhdpi-v31/android12branding.png differ diff --git a/Frontend/android/app/src/main/res/drawable-xxxhdpi/android12splash.png b/Frontend/android/app/src/main/res/drawable-xxxhdpi/android12splash.png index aa4e2c8f..a2709e12 100644 Binary files a/Frontend/android/app/src/main/res/drawable-xxxhdpi/android12splash.png and b/Frontend/android/app/src/main/res/drawable-xxxhdpi/android12splash.png differ diff --git a/Frontend/android/app/src/main/res/drawable-xxxhdpi/branding.png b/Frontend/android/app/src/main/res/drawable-xxxhdpi/branding.png index 041582d2..f2d86a92 100644 Binary files a/Frontend/android/app/src/main/res/drawable-xxxhdpi/branding.png and b/Frontend/android/app/src/main/res/drawable-xxxhdpi/branding.png differ diff --git a/Frontend/android/app/src/main/res/drawable-xxxhdpi/splash.png b/Frontend/android/app/src/main/res/drawable-xxxhdpi/splash.png index c14c0a9b..a2709e12 100644 Binary files a/Frontend/android/app/src/main/res/drawable-xxxhdpi/splash.png and b/Frontend/android/app/src/main/res/drawable-xxxhdpi/splash.png differ diff --git a/Frontend/android/app/src/main/res/drawable/background.png b/Frontend/android/app/src/main/res/drawable/background.png index 47cd7af3..83987bcc 100644 Binary files a/Frontend/android/app/src/main/res/drawable/background.png and b/Frontend/android/app/src/main/res/drawable/background.png differ diff --git a/Frontend/devtools_options.yaml b/Frontend/devtools_options.yaml index fa0b357c..7e9e9477 100644 --- a/Frontend/devtools_options.yaml +++ b/Frontend/devtools_options.yaml @@ -1,3 +1,3 @@ description: This file stores settings for Dart & Flutter DevTools. documentation: https://docs.flutter.dev/tools/devtools/extensions#configure-extension-enablement-states -extensions: +extensions: \ No newline at end of file diff --git a/Frontend/ios/Podfile.lock b/Frontend/ios/Podfile.lock index eca87e34..53f8781d 100644 --- a/Frontend/ios/Podfile.lock +++ b/Frontend/ios/Podfile.lock @@ -40,7 +40,7 @@ PODS: - fl_downloader (0.0.1): - Flutter - Flutter (1.0.0) - - flutter_native_splash (0.0.1): + - flutter_native_splash (2.4.3): - Flutter - flutter_tts (0.0.1): - Flutter @@ -65,6 +65,8 @@ PODS: - FlutterMacOS - printing (1.0.0): - Flutter + - screen_brightness_ios (0.1.0): + - Flutter - SDWebImage (5.20.0): - SDWebImage/Core (= 5.20.0) - SDWebImage/Core (5.20.0) @@ -73,6 +75,9 @@ PODS: - shared_preferences_foundation (0.0.1): - Flutter - FlutterMacOS + - sqflite_darwin (0.0.4): + - Flutter + - FlutterMacOS - SwiftyGif (5.4.5) - syncfusion_flutter_pdfviewer (0.0.1): - Flutter @@ -96,8 +101,10 @@ DEPENDENCIES: - mobile_scanner (from `.symlinks/plugins/mobile_scanner/darwin`) - path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`) - printing (from `.symlinks/plugins/printing/ios`) + - screen_brightness_ios (from `.symlinks/plugins/screen_brightness_ios/ios`) - share_plus (from `.symlinks/plugins/share_plus/ios`) - shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`) + - sqflite_darwin (from `.symlinks/plugins/sqflite_darwin/darwin`) - syncfusion_flutter_pdfviewer (from `.symlinks/plugins/syncfusion_flutter_pdfviewer/ios`) - url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`) - webview_flutter_wkwebview (from `.symlinks/plugins/webview_flutter_wkwebview/darwin`) @@ -138,10 +145,14 @@ EXTERNAL SOURCES: :path: ".symlinks/plugins/path_provider_foundation/darwin" printing: :path: ".symlinks/plugins/printing/ios" + screen_brightness_ios: + :path: ".symlinks/plugins/screen_brightness_ios/ios" share_plus: :path: ".symlinks/plugins/share_plus/ios" shared_preferences_foundation: :path: ".symlinks/plugins/shared_preferences_foundation/darwin" + sqflite_darwin: + :path: ".symlinks/plugins/sqflite_darwin/darwin" syncfusion_flutter_pdfviewer: :path: ".symlinks/plugins/syncfusion_flutter_pdfviewer/ios" url_launcher_ios: @@ -157,7 +168,7 @@ SPEC CHECKSUMS: file_picker: a0560bc09d61de87f12d246fc47d2119e6ef37be fl_downloader: dc99aa8dd303f862cccb830087f37acc9b0156ee Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7 - flutter_native_splash: 35ddbc7228eafcb3969dcc5f1fbbe27c1145a4f0 + flutter_native_splash: c32d145d68aeda5502d5f543ee38c192065986cf flutter_tts: b88dbc8655d3dc961bc4a796e4e16a4cc1795833 geolocator_apple: ab36aa0e8b7d7a2d7639b3b4e48308394e8cef5e Google-Mobile-Ads-SDK: 1dfb0c3cb46c7e2b00b0f4de74a1e06d9ea25d67 @@ -167,9 +178,11 @@ SPEC CHECKSUMS: mobile_scanner: 9157936403f5a0644ca3779a38ff8404c5434a93 path_provider_foundation: 080d55be775b7414fd5a5ef3ac137b97b097e564 printing: 54ff03f28fe9ba3aa93358afb80a8595a071dd07 + screen_brightness_ios: 9953fd7da5bd480f1a93990daeec2eb42d4f3b52 SDWebImage: 73c6079366fea25fa4bb9640d5fb58f0893facd8 share_plus: 50da8cb520a8f0f65671c6c6a99b3617ed10a58a shared_preferences_foundation: 9e1978ff2562383bd5676f64ec4e9aa8fa06a6f7 + sqflite_darwin: 20b2a3a3b70e43edae938624ce550a3cbf66a3d0 SwiftyGif: 706c60cf65fa2bc5ee0313beece843c8eb8194d4 syncfusion_flutter_pdfviewer: 90dc48305d2e33d4aa20681d1e98ddeda891bc14 url_launcher_ios: 694010445543906933d732453a59da0a173ae33d diff --git a/Frontend/ios/Runner.xcodeproj/project.pbxproj b/Frontend/ios/Runner.xcodeproj/project.pbxproj index c9660c5a..17117b47 100644 --- a/Frontend/ios/Runner.xcodeproj/project.pbxproj +++ b/Frontend/ios/Runner.xcodeproj/project.pbxproj @@ -44,6 +44,7 @@ /* Begin PBXFileReference section */ 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; + 2059B8BD2E7405B800139A50 /* Runner.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Runner.entitlements; sourceTree = ""; }; 209959071B4259A271891D6D /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; 244BDC62FF4364AA78470B4E /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; 277EDD110F2042FAAC4E5333 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -152,6 +153,7 @@ 97C146F01CF9000F007C117D /* Runner */ = { isa = PBXGroup; children = ( + 2059B8BD2E7405B800139A50 /* Runner.entitlements */, 97C146FA1CF9000F007C117D /* Main.storyboard */, 97C146FD1CF9000F007C117D /* Assets.xcassets */, 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, @@ -485,6 +487,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; + CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; DEVELOPMENT_TEAM = B88N73P46W; ENABLE_BITCODE = NO; @@ -667,6 +670,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; + CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; DEVELOPMENT_TEAM = B88N73P46W; ENABLE_BITCODE = NO; @@ -693,6 +697,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; + CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; DEVELOPMENT_TEAM = B88N73P46W; ENABLE_BITCODE = NO; diff --git a/Frontend/ios/Runner/Assets.xcassets/BrandingImage.imageset/BrandingImage.png b/Frontend/ios/Runner/Assets.xcassets/BrandingImage.imageset/BrandingImage.png index e1061999..c82d522c 100644 Binary files a/Frontend/ios/Runner/Assets.xcassets/BrandingImage.imageset/BrandingImage.png and b/Frontend/ios/Runner/Assets.xcassets/BrandingImage.imageset/BrandingImage.png differ diff --git a/Frontend/ios/Runner/Assets.xcassets/BrandingImage.imageset/BrandingImage@2x.png b/Frontend/ios/Runner/Assets.xcassets/BrandingImage.imageset/BrandingImage@2x.png index 6bf213bd..7d34377d 100644 Binary files a/Frontend/ios/Runner/Assets.xcassets/BrandingImage.imageset/BrandingImage@2x.png and b/Frontend/ios/Runner/Assets.xcassets/BrandingImage.imageset/BrandingImage@2x.png differ diff --git a/Frontend/ios/Runner/Assets.xcassets/BrandingImage.imageset/BrandingImage@3x.png b/Frontend/ios/Runner/Assets.xcassets/BrandingImage.imageset/BrandingImage@3x.png index abac6898..844f6592 100644 Binary files a/Frontend/ios/Runner/Assets.xcassets/BrandingImage.imageset/BrandingImage@3x.png and b/Frontend/ios/Runner/Assets.xcassets/BrandingImage.imageset/BrandingImage@3x.png differ diff --git a/Frontend/ios/Runner/Assets.xcassets/LaunchBackground.imageset/background.png b/Frontend/ios/Runner/Assets.xcassets/LaunchBackground.imageset/background.png index 47cd7af3..83987bcc 100644 Binary files a/Frontend/ios/Runner/Assets.xcassets/LaunchBackground.imageset/background.png and b/Frontend/ios/Runner/Assets.xcassets/LaunchBackground.imageset/background.png differ diff --git a/Frontend/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png b/Frontend/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png index 111b07d4..53e4ced6 100644 Binary files a/Frontend/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png and b/Frontend/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png differ diff --git a/Frontend/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png b/Frontend/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png index 1b05f2f1..5071f829 100644 Binary files a/Frontend/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png and b/Frontend/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png differ diff --git a/Frontend/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png b/Frontend/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png index ab6a0135..c198ddbf 100644 Binary files a/Frontend/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png and b/Frontend/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png differ diff --git a/Frontend/ios/Runner/Base.lproj/LaunchScreen.storyboard b/Frontend/ios/Runner/Base.lproj/LaunchScreen.storyboard index 9d41a3a2..313e34f5 100644 --- a/Frontend/ios/Runner/Base.lproj/LaunchScreen.storyboard +++ b/Frontend/ios/Runner/Base.lproj/LaunchScreen.storyboard @@ -41,7 +41,7 @@ - + diff --git a/Frontend/ios/Runner/Info.plist b/Frontend/ios/Runner/Info.plist index 9a4bd087..66f13c22 100644 --- a/Frontend/ios/Runner/Info.plist +++ b/Frontend/ios/Runner/Info.plist @@ -1,77 +1,77 @@ - - GADApplicationIdentifier - ca-app-pub-4781880856775334~6935644635 - CADisableMinimumFrameDurationOnPhone - - CFBundleDevelopmentRegion - $(DEVELOPMENT_LANGUAGE) - CFBundleDisplayName - MIH - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - mzansi_innovation_hub - CFBundlePackageType - APPL - CFBundleShortVersionString - $(FLUTTER_BUILD_NAME) - CFBundleSignature - ???? - CFBundleVersion - $(FLUTTER_BUILD_NUMBER) - LSApplicationQueriesSchemes - - sms - tel - - LSRequiresIPhoneOS - - LSSupportsOpeningDocumentsInPlace - - NSCameraUsageDescription - This app needs camera access to scan QR codes - NSFaceIDUsageDescription - Why is my app authenticating using face id? - NSLocationWhenInUseUsageDescription - This app needs access to location when open. - NSPhotoLibraryUsageDescription - This app needs to access your photo library to select images. - NSDownloadsFolderUsageDescription - This app needs to access your downloads folder to select files from there. - UIApplicationSupportsIndirectInputEvents - - UIBackgroundModes - - fetch - remote-notification - - UIFileSharingEnabled - - UILaunchStoryboardName - LaunchScreen - UIMainStoryboardFile - Main - UIStatusBarHidden - - UISupportedInterfaceOrientations - - UIInterfaceOrientationPortrait - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - UISupportedInterfaceOrientations~ipad - - UIInterfaceOrientationPortrait - UIInterfaceOrientationPortraitUpsideDown - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - + + GADApplicationIdentifier + ca-app-pub-4781880856775334~6935644635 + CADisableMinimumFrameDurationOnPhone + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleDisplayName + MIH + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + mzansi_innovation_hub + CFBundlePackageType + APPL + CFBundleShortVersionString + $(FLUTTER_BUILD_NAME) + CFBundleSignature + ???? + CFBundleVersion + $(FLUTTER_BUILD_NUMBER) + LSApplicationQueriesSchemes + + sms + tel + + LSRequiresIPhoneOS + + LSSupportsOpeningDocumentsInPlace + + NSCameraUsageDescription + This app needs camera access to scan QR codes + NSFaceIDUsageDescription + Why is my app authenticating using face id? + NSLocationWhenInUseUsageDescription + This app needs access to location when open. + NSPhotoLibraryUsageDescription + This app needs to access your photo library to select images. + NSDownloadsFolderUsageDescription + This app needs to access your downloads folder to select files from there. + UIApplicationSupportsIndirectInputEvents + + UIBackgroundModes + + fetch + remote-notification + + UIFileSharingEnabled + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIStatusBarHidden + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + diff --git a/Frontend/ios/Runner/Runner.entitlements b/Frontend/ios/Runner/Runner.entitlements new file mode 100644 index 00000000..5cf09c4f --- /dev/null +++ b/Frontend/ios/Runner/Runner.entitlements @@ -0,0 +1,10 @@ + + + + + com.apple.developer.associated-domains + + applinks:app.mzansi-innovation-hub.co.za + + + diff --git a/Frontend/lib/main.dart b/Frontend/lib/main.dart index b2812def..483df2b2 100644 --- a/Frontend/lib/main.dart +++ b/Frontend/lib/main.dart @@ -1,12 +1,14 @@ import 'package:flutter/material.dart'; +import 'package:go_router/go_router.dart'; import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart'; import 'mih_config/mih_env.dart'; -import 'mih_config/mih_routeGenerator.dart'; import 'mih_config/mih_theme.dart'; class MzansiInnovationHub extends StatefulWidget { + final GoRouter router; const MzansiInnovationHub({ super.key, + required this.router, }); @override @@ -53,18 +55,9 @@ class _MzansiInnovationHubState extends State { @override void initState() { theme = MihTheme(); - // var systemTheme = - // SchedulerBinding.instance.platformDispatcher.platformBrightness; - // bool isDarkMode = systemTheme == Brightness.dark; - // if (isDarkMode) { - // theme.mode = "Dark"; - // } else { - // theme.mode = "Light"; - // } super.initState(); theme.mode = "Dark"; theme.platform = Theme.of(context).platform; - //doInit(); } @override @@ -72,14 +65,13 @@ class _MzansiInnovationHubState extends State { double width = MediaQuery.sizeOf(context).width; theme.setScreenType(width); precacheImage(theme.loadingImage(), context); - return MaterialApp( + return MaterialApp.router( title: getTitle(), themeMode: ThemeMode.dark, theme: theme.getThemeData(), darkTheme: theme.getThemeData(), debugShowCheckedModeBanner: false, - initialRoute: '/', - onGenerateRoute: RouteGenerator.generateRoute, + routerConfig: widget.router, ); } -} +} \ No newline at end of file diff --git a/Frontend/lib/main_dev.dart b/Frontend/lib/main_dev.dart index 560a9477..81ca7e45 100644 --- a/Frontend/lib/main_dev.dart +++ b/Frontend/lib/main_dev.dart @@ -3,8 +3,10 @@ import 'package:flutter/material.dart'; import 'package:flutter_native_splash/flutter_native_splash.dart'; import 'package:flutter_web_plugins/url_strategy.dart' if (dart.library.html) 'package:flutter_web_plugins/url_strategy.dart'; +import 'package:go_router/go_router.dart'; import 'package:google_mobile_ads/google_mobile_ads.dart'; import 'package:mzansi_innovation_hub/main.dart'; +import 'package:mzansi_innovation_hub/mih_config/mih_go_router.dart'; import 'package:pwa_install/pwa_install.dart'; import 'mih_config/mih_env.dart'; import 'package:supertokens_flutter/supertokens.dart'; @@ -25,6 +27,7 @@ void main() async { PWAInstall().setup(installCallback: () { debugPrint('APP INSTALLED!'); }); + final GoRouter appRouter = MihGoRouter().mihRouter; FlutterNativeSplash.remove(); - runApp(const MzansiInnovationHub()); + runApp(MzansiInnovationHub(router: appRouter,)); } diff --git a/Frontend/lib/main_prod.dart b/Frontend/lib/main_prod.dart index 51008267..2facd8be 100644 --- a/Frontend/lib/main_prod.dart +++ b/Frontend/lib/main_prod.dart @@ -3,8 +3,10 @@ import 'package:flutter/material.dart'; import 'package:flutter_native_splash/flutter_native_splash.dart'; import 'package:flutter_web_plugins/url_strategy.dart' if (dart.library.html) 'package:flutter_web_plugins/url_strategy.dart'; +import 'package:go_router/go_router.dart'; import 'package:google_mobile_ads/google_mobile_ads.dart'; import 'package:mzansi_innovation_hub/main.dart'; +import 'package:mzansi_innovation_hub/mih_config/mih_go_router.dart'; import 'package:pwa_install/pwa_install.dart'; import 'mih_config/mih_env.dart'; import 'package:supertokens_flutter/supertokens.dart'; @@ -25,6 +27,7 @@ void main() async { PWAInstall().setup(installCallback: () { debugPrint('APP INSTALLED!'); }); + final GoRouter appRouter = MihGoRouter().mihRouter; FlutterNativeSplash.remove(); - runApp(const MzansiInnovationHub()); + runApp(MzansiInnovationHub(router: appRouter,)); } diff --git a/Frontend/lib/mih_components/mih_package_components/Example/package_test.dart b/Frontend/lib/mih_components/mih_package_components/Example/package_test.dart index 3c473292..b52d15b9 100644 --- a/Frontend/lib/mih_components/mih_package_components/Example/package_test.dart +++ b/Frontend/lib/mih_components/mih_package_components/Example/package_test.dart @@ -1,3 +1,4 @@ +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.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_action.dart'; @@ -32,11 +33,16 @@ class _PackageTestState extends State { icon: const Icon(Icons.arrow_back), iconSize: 35, onTap: () { - Navigator.of(context).pop(); - Navigator.of(context).popAndPushNamed( - '/', - arguments: AuthArguments(true, false), + context.goNamed( + 'mihHome', + extra: true, ); + FocusScope.of(context).unfocus(); + // Navigator.of(context).pop(); + // Navigator.of(context).popAndPushNamed( + // '/', + // arguments: AuthArguments(true, false), + // ); }, ); } @@ -124,7 +130,7 @@ class _PackageTestState extends State { List toolBodies = [ PackageToolOne( user: widget.arguments.user, - business: widget.arguments.business!, + business: widget.arguments.business, ), const PackageToolTwo(), ]; diff --git a/Frontend/lib/mih_components/mih_package_components/Example/package_tiles/test_package_tile.dart b/Frontend/lib/mih_components/mih_package_components/Example/package_tiles/test_package_tile.dart new file mode 100644 index 00000000..7ef12f06 --- /dev/null +++ b/Frontend/lib/mih_components/mih_package_components/Example/package_tiles/test_package_tile.dart @@ -0,0 +1,58 @@ +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_objects/app_user.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_package_components/mih_package_tile.dart'; +import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart'; + +class TestPackageTile extends StatefulWidget { + final AppUser signedInUser; + final Business? business; + final double packageSize; + const TestPackageTile({ + super.key, + required this.signedInUser, + required this.business, + required this.packageSize, + }); + + @override + State createState() => _TestPackageTileState(); +} + +class _TestPackageTileState extends State { + @override + Widget build(BuildContext context) { + return MihPackageTile( + onTap: () { + context.goNamed( + 'testPackage', + extra: TestArguments( + widget.signedInUser, + widget.business, + ), + ); + // Navigator.of(context).pushNamed( + // '/package-dev', + // arguments: TestArguments( + // widget.signedInUser, + // widget.business, + // ), + // ); + }, + appName: "Test", + appIcon: Icon( + Icons.warning_amber_rounded, + color: MihColors.getSecondaryColor( + MzansiInnovationHub.of(context)!.theme.mode == "Dark"), + ), + iconSize: widget.packageSize, + primaryColor: MihColors.getSecondaryColor( + MzansiInnovationHub.of(context)!.theme.mode == "Dark"), + secondaryColor: MihColors.getPrimaryColor( + MzansiInnovationHub.of(context)!.theme.mode == "Dark"), + ); + } +} diff --git a/Frontend/lib/mih_components/mih_package_components/Example/package_tools/package_tool_one.dart b/Frontend/lib/mih_components/mih_package_components/Example/package_tools/package_tool_one.dart index ad71ced0..16d0bd2c 100644 --- a/Frontend/lib/mih_components/mih_package_components/Example/package_tools/package_tool_one.dart +++ b/Frontend/lib/mih_components/mih_package_components/Example/package_tools/package_tool_one.dart @@ -38,7 +38,7 @@ import 'package:redacted/redacted.dart'; class PackageToolOne extends StatefulWidget { final AppUser user; - final Business business; + final Business? business; const PackageToolOne({ super.key, required this.user, @@ -393,17 +393,19 @@ class _PackageToolOneState extends State { .replaceAll("Latitude: ", "") .replaceAll("Longitude: ", ""); print("My Location is this: $myLocation"); - return MihBusinessProfilePreview( - business: widget.business, - myLocation: myLocation, - ); + return widget.business != null + ? MihBusinessProfilePreview( + business: widget.business!, + myLocation: myLocation, + ) + : Text("NoBusiness Data"); } }), - const SizedBox(height: 10), - Text("This text should be redacted").redacted( - context: context, - redact: true, - ), + // const SizedBox(height: 10), + // Text("This text should be redacted").redacted( + // context: context, + // redact: true, + // ), MihBusinessCard( business: Business( "business_id", diff --git a/Frontend/lib/mih_components/mih_package_components/assets/images/branding_text.png b/Frontend/lib/mih_components/mih_package_components/assets/images/branding_text.png deleted file mode 100644 index 69044f5c..00000000 Binary files a/Frontend/lib/mih_components/mih_package_components/assets/images/branding_text.png and /dev/null differ diff --git a/Frontend/lib/mih_components/mih_package_components/assets/images/splash_screen/mih_branding_splash.png b/Frontend/lib/mih_components/mih_package_components/assets/images/splash_screen/mih_branding_splash.png new file mode 100644 index 00000000..a737b7f7 Binary files /dev/null and b/Frontend/lib/mih_components/mih_package_components/assets/images/splash_screen/mih_branding_splash.png differ diff --git a/Frontend/lib/mih_components/mih_package_components/assets/images/splash_screen/mih_branding_splash_temp.gif b/Frontend/lib/mih_components/mih_package_components/assets/images/splash_screen/mih_branding_splash_temp.gif new file mode 100644 index 00000000..eea9f00f Binary files /dev/null and b/Frontend/lib/mih_components/mih_package_components/assets/images/splash_screen/mih_branding_splash_temp.gif differ diff --git a/Frontend/lib/mih_components/mih_package_components/assets/images/splash_screen/mih_image_splash.png b/Frontend/lib/mih_components/mih_package_components/assets/images/splash_screen/mih_image_splash.png new file mode 100644 index 00000000..b045151d Binary files /dev/null and b/Frontend/lib/mih_components/mih_package_components/assets/images/splash_screen/mih_image_splash.png differ diff --git a/Frontend/lib/mih_components/mih_package_components/assets/images/splash_screen/mih_image_splash_temp.gif b/Frontend/lib/mih_components/mih_package_components/assets/images/splash_screen/mih_image_splash_temp.gif new file mode 100644 index 00000000..d4a7864b Binary files /dev/null and b/Frontend/lib/mih_components/mih_package_components/assets/images/splash_screen/mih_image_splash_temp.gif differ diff --git a/Frontend/lib/mih_components/mih_package_components/assets/images/splash_screen/splash_screen_icon.png b/Frontend/lib/mih_components/mih_package_components/assets/images/splash_screen/splash_screen_icon.png deleted file mode 100644 index 7540afb8..00000000 Binary files a/Frontend/lib/mih_components/mih_package_components/assets/images/splash_screen/splash_screen_icon.png and /dev/null differ diff --git a/Frontend/lib/mih_components/mih_package_components/mih_circle_avatar.dart b/Frontend/lib/mih_components/mih_package_components/mih_circle_avatar.dart index 0585adeb..5001a343 100644 --- a/Frontend/lib/mih_components/mih_package_components/mih_circle_avatar.dart +++ b/Frontend/lib/mih_components/mih_package_components/mih_circle_avatar.dart @@ -4,6 +4,7 @@ import 'package:file_picker/file_picker.dart'; import 'package:flutter/material.dart'; import 'package:mzansi_innovation_hub/main.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_icons.dart'; +import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart'; class MihCircleAvatar extends StatefulWidget { final ImageProvider? imageFile; @@ -54,7 +55,6 @@ class _MihCircleAvatarState extends State { @override void initState() { super.initState(); - print("Avatar started"); setState(() { imagePreview = getAvatar(); }); @@ -72,21 +72,20 @@ class _MihCircleAvatarState extends State { children: [ Visibility( visible: imagePreview != null, - child: CircleAvatar( - radius: widget.width / 2.2, - backgroundColor: widget.backgroundColor, - backgroundImage: imagePreview, + child: Positioned( + child: CircleAvatar( + radius: widget.width / 2.2, + backgroundColor: widget.backgroundColor, + backgroundImage: imagePreview, + ), ), ), Visibility( visible: imagePreview != null, - child: FittedBox( - fit: BoxFit.fill, - child: Icon( - size: widget.width, - MihIcons.mihRing, - color: widget.frameColor, - ), + child: Icon( + size: widget.width, + MihIcons.mihRing, + color: widget.frameColor, ), ), Visibility( @@ -103,6 +102,12 @@ class _MihCircleAvatarState extends State { bottom: 0, right: 0, child: IconButton.filled( + style: ButtonStyle( + backgroundColor: WidgetStateProperty.all( + MihColors.getGreenColor( + MzansiInnovationHub.of(context)!.theme.mode == "Dark"), + ), + ), onPressed: () async { try { FilePickerResult? result = @@ -154,7 +159,9 @@ class _MihCircleAvatarState extends State { print("Error: $e"); } }, - icon: const Icon(Icons.edit), + icon: Icon( + Icons.edit, + ), ), ), ), 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 72986d0d..c33fe4f7 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 @@ -76,11 +76,11 @@ class _MihImageDisplayState extends State { Visibility( visible: widget.editable, child: Positioned( - bottom: 0, - right: 0, + bottom: 5, + right: 5, child: IconButton.filled( style: IconButton.styleFrom( - backgroundColor: MihColors.getSecondaryColor( + backgroundColor: MihColors.getGreenColor( MzansiInnovationHub.of(context)!.theme.mode == "Dark"), ), color: MihColors.getPrimaryColor( diff --git a/Frontend/lib/mih_components/mih_package_components/mih_package.dart b/Frontend/lib/mih_components/mih_package_components/mih_package.dart index f7718a09..b431df5f 100644 --- a/Frontend/lib/mih_components/mih_package_components/mih_package.dart +++ b/Frontend/lib/mih_components/mih_package_components/mih_package.dart @@ -1,4 +1,8 @@ +import 'package:flutter/services.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_scack_bar.dart'; import 'package:mzansi_innovation_hub/mih_packages/mih_home/components/mih_app_drawer.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_tools.dart'; import 'package:flutter/material.dart'; @@ -31,6 +35,7 @@ class _MihPackageState extends State with SingleTickerProviderStateMixin { late PageController _pageController; late AnimationController _animationController; + DateTime? lastPressedAt; void unfocusAll() { FocusScope.of(context).unfocus(); @@ -113,69 +118,96 @@ class _MihPackageState extends State Size screenSize = MediaQuery.of(context).size; return GestureDetector( onTap: unfocusAll, - child: Scaffold( - drawer: widget.actionDrawer, - body: SafeArea( - bottom: false, - minimum: EdgeInsets.only(bottom: 0), - child: Container( - width: screenSize.width, - height: screenSize.height, - //color: Colors.black, - padding: const EdgeInsets.only(top: 5), - child: Column( - children: [ - Row( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - widget.appActionButton, - const SizedBox( - width: 10, - ), - Expanded( - child: Container( - // alignment: Alignment.center, - // alignment: Alignment.centerRight, - alignment: Alignment.centerLeft, - // color: Colors.black, - child: FittedBox( - child: Text( - widget.appToolTitles != null - ? widget - .appToolTitles![widget.selectedbodyIndex] - : "", - style: const TextStyle( - fontSize: 23, - fontWeight: FontWeight.w600, + child: PopScope( + canPop: false, + onPopInvokedWithResult: (bool didPop, Object? result) { + if (GoRouterState.of(context).name == 'mihHome' || + GoRouterState.of(context).name == 'mihAuthentication') { + if (lastPressedAt == null || + DateTime.now().difference(lastPressedAt!) > + const Duration(seconds: 2)) { + // First press: show a message and update the timestamp. + lastPressedAt = DateTime.now(); + ScaffoldMessenger.of(context).showSnackBar( + MihSnackBar( + child: Text("Press back again to exit"), + ), + ); + } else { + // Second press within 2 seconds: exit the app. + KenLogger.warning('Exiting app...'); // Your custom logger + SystemChannels.platform.invokeMethod('SystemNavigator.pop'); + } + } else { + context.goNamed( + 'mihHome', + extra: true, + ); + } + }, + child: Scaffold( + drawer: widget.actionDrawer, + body: SafeArea( + bottom: false, + minimum: EdgeInsets.only(bottom: 0), + child: Container( + width: screenSize.width, + height: screenSize.height, + //color: Colors.black, + padding: const EdgeInsets.only(top: 5), + child: Column( + children: [ + Row( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + widget.appActionButton, + const SizedBox( + width: 10, + ), + Expanded( + child: Container( + // alignment: Alignment.center, + // alignment: Alignment.centerRight, + alignment: Alignment.centerLeft, + // color: Colors.black, + child: FittedBox( + child: Text( + widget.appToolTitles != null + ? widget + .appToolTitles![widget.selectedbodyIndex] + : "", + style: const TextStyle( + fontSize: 23, + fontWeight: FontWeight.w600, + ), ), ), ), ), - ), - const SizedBox( - width: 5, - ), - widget.appTools, - ], - ), - const SizedBox(height: 5), - Expanded( - child: PageView.builder( - controller: _pageController, - itemCount: widget.appBody.length, - itemBuilder: (context, index) { - return widget.appBody[index]; - }, - onPageChanged: (index) { - setState(() { - widget.selectedbodyIndex = index; - widget.onIndexChange(widget.selectedbodyIndex); - }); - }, + const SizedBox(width: 5), + widget.appTools, + const SizedBox(width: 5), + ], ), - ), - ], + const SizedBox(height: 5), + Expanded( + child: PageView.builder( + controller: _pageController, + itemCount: widget.appBody.length, + itemBuilder: (context, index) { + return widget.appBody[index]; + }, + onPageChanged: (index) { + setState(() { + widget.selectedbodyIndex = index; + widget.onIndexChange(widget.selectedbodyIndex); + }); + }, + ), + ), + ], + ), ), ), ), diff --git a/Frontend/lib/mih_components/mih_package_components/mih_package_tile.dart b/Frontend/lib/mih_components/mih_package_components/mih_package_tile.dart index 0e85a771..93538ce0 100644 --- a/Frontend/lib/mih_components/mih_package_components/mih_package_tile.dart +++ b/Frontend/lib/mih_components/mih_package_components/mih_package_tile.dart @@ -1,4 +1,9 @@ +import 'package:app_settings/app_settings.dart'; +import 'package:flutter/foundation.dart'; +import 'package:local_auth/local_auth.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_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_yt_video_player.dart'; import 'package:flutter/material.dart'; @@ -12,6 +17,7 @@ class MihPackageTile extends StatefulWidget { final double iconSize; final Color primaryColor; final Color secondaryColor; + final bool? authenticateUser; const MihPackageTile({ super.key, required this.onTap, @@ -21,6 +27,7 @@ class MihPackageTile extends StatefulWidget { required this.iconSize, required this.primaryColor, required this.secondaryColor, + this.authenticateUser, }); @override @@ -28,6 +35,8 @@ class MihPackageTile extends StatefulWidget { } class _MihPackageTileState extends State { + final LocalAuthentication _auth = LocalAuthentication(); + void displayHint() { if (widget.ytVideoID != null) { showDialog( @@ -49,6 +58,128 @@ class _MihPackageTileState extends State { } } + Future isUserAuthenticated() async { + final bool canAuthWithBio = await _auth.canCheckBiometrics; + final bool canAuthenticate = + canAuthWithBio || await _auth.isDeviceSupported(); + print("Auth Available: $canAuthenticate"); + if (canAuthenticate) { + try { + final bool didBioAuth = await _auth.authenticate( + localizedReason: "Authenticate to access ${widget.appName}", + options: const AuthenticationOptions( + biometricOnly: false, + ), + ); + if (didBioAuth) { + return true; + } else { + authErrorPopUp(); + } + // print("Authenticated: $didBioAuth"); + } catch (error) { + print("Auth Error: $error"); + authErrorPopUp(); + } + } else { + print("Auth Error: No Biometrics Available"); + authErrorPopUp(); + } + return false; + } + + void authErrorPopUp() { + Widget alertpopUp = MihPackageAlert( + alertIcon: Icon( + Icons.fingerprint, + color: MihColors.getRedColor( + MzansiInnovationHub.of(context)!.theme.mode == "Dark"), + size: 100, + ), + alertTitle: "Biometric Authentication Required", + alertBody: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + "Hi there! To jump into the ${widget.appName} Package, you'll need to authenticate yourself with your devices biometrics, please set up biometric authentication (like fingerprint, face ID, pattern or pin) on your device first.\n\nIf you have already set up biometric authentication, press \"Authenticate now\" to try again or press \"Set Up Authentication\" to go to your device settings.", + style: TextStyle( + fontSize: 15, + color: MihColors.getSecondaryColor( + MzansiInnovationHub.of(context)!.theme.mode == "Dark"), + ), + ), + const SizedBox(height: 20), + Wrap( + runAlignment: WrapAlignment.center, + crossAxisAlignment: WrapCrossAlignment.center, + spacing: 10, + runSpacing: 10, + children: [ + MihButton( + onPressed: () { + AppSettings.openAppSettings( + type: AppSettingsType.security, + ); + Navigator.of(context).pop(); + }, + buttonColor: MihColors.getSecondaryColor( + MzansiInnovationHub.of(context)!.theme.mode == "Dark"), + width: 300, + child: Text( + "Set Up Authentication", + style: TextStyle( + color: MihColors.getPrimaryColor( + MzansiInnovationHub.of(context)!.theme.mode == "Dark"), + fontSize: 20, + fontWeight: FontWeight.bold, + ), + ), + ), + MihButton( + onPressed: () { + Navigator.of(context).pop(); + authenticateUser(); + }, + buttonColor: MihColors.getGreenColor( + MzansiInnovationHub.of(context)!.theme.mode == "Dark"), + width: 300, + child: Text( + "Authenticate Now", + 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"), + ); + showDialog( + context: context, + builder: (context) { + return alertpopUp; + }, + ); + } + + Future authenticateUser() async { + if (widget.authenticateUser != null && + widget.authenticateUser! && + !kIsWeb) { + if (await isUserAuthenticated()) { + widget.onTap(); + } + } else { + widget.onTap(); + } + } + @override Widget build(BuildContext context) { return Container( @@ -57,7 +188,9 @@ class _MihPackageTileState extends State { // width: widget.iconSize, // height: widget.iconSize + widget.iconSize / 3, child: GestureDetector( - onTap: widget.onTap, + onTap: () async { + authenticateUser(); + }, onLongPress: null, // Do this later child: Column( children: [ diff --git a/Frontend/lib/mih_components/mih_package_components/mih_scack_bar.dart b/Frontend/lib/mih_components/mih_package_components/mih_scack_bar.dart new file mode 100644 index 00000000..4a38e860 --- /dev/null +++ b/Frontend/lib/mih_components/mih_package_components/mih_scack_bar.dart @@ -0,0 +1,18 @@ +import 'package:flutter/material.dart'; + +SnackBar MihSnackBar({ + required Widget child, +}) { + return SnackBar( + content: child, + shape: StadiumBorder(), + behavior: SnackBarBehavior.floating, + duration: Duration(seconds: 2), + width: null, + action: SnackBarAction( + label: "Dismiss", + onPressed: () {}, + ), + // elevation: 30, + ); +} diff --git a/Frontend/lib/mih_config/mih_env.dart b/Frontend/lib/mih_config/mih_env.dart index 0cfe35b8..e9dcdd2f 100644 --- a/Frontend/lib/mih_config/mih_env.dart +++ b/Frontend/lib/mih_config/mih_env.dart @@ -6,6 +6,7 @@ enum Enviroment { dev, prod } // abstract class AppEnviroment { + static late String baseAppUrl; static late String baseApiUrl; static late String baseAiUrl; static late String baseFileUrl; @@ -21,6 +22,7 @@ abstract class AppEnviroment { { if (kIsWeb) { //================= Web Dev Urls ================= + baseAppUrl = "http://localhost:80"; baseApiUrl = "http://localhost:8080"; baseFileUrl = "http://localhost:9000"; baseAiUrl = "http://localhost:11434"; @@ -28,12 +30,14 @@ abstract class AppEnviroment { break; } else if (Platform.isAndroid) { //================= Android Dev Urls ================= + baseAppUrl = "http://10.0.2.2:80"; baseApiUrl = "http://10.0.2.2:8080"; baseFileUrl = "http://10.0.2.2:9000"; baseAiUrl = "http://10.0.2.2:11434"; bannerAdUnitId = 'ca-app-pub-3940256099942544/9214589741'; } else { //================= Web & iOS Dev Urls ================= + baseAppUrl = "http://localhost:80"; baseApiUrl = "http://localhost:8080"; baseFileUrl = "http://localhost:9000"; baseAiUrl = "http://localhost:11434"; @@ -43,6 +47,7 @@ abstract class AppEnviroment { } case Enviroment.prod: { + baseAppUrl = "https://app.mzansi-innovation-hub.co.za"; baseApiUrl = "https://api.mzansi-innovation-hub.co.za"; baseFileUrl = "https://minio.mzansi-innovation-hub.co.za"; baseAiUrl = "https://ai.mzansi-innovation-hub.co.za"; diff --git a/Frontend/lib/mih_config/mih_go_router.dart b/Frontend/lib/mih_config/mih_go_router.dart new file mode 100644 index 00000000..bbddb323 --- /dev/null +++ b/Frontend/lib/mih_config/mih_go_router.dart @@ -0,0 +1,479 @@ +import 'package:flutter/material.dart'; +import 'package:go_router/go_router.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_layout/mih_print_prevew.dart'; +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_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'; +import 'package:mzansi_innovation_hub/mih_packages/calendar/mzansi_calendar.dart'; +import 'package:mzansi_innovation_hub/mih_packages/mih_authentication/mih_auth_forgot_password.dart'; +import 'package:mzansi_innovation_hub/mih_packages/mih_authentication/mih_auth_password_reset.dart'; +import 'package:mzansi_innovation_hub/mih_packages/mih_authentication/mih_authentication.dart'; +import 'package:mzansi_innovation_hub/mih_packages/mih_home/mih_home.dart'; +import 'package:mzansi_innovation_hub/mih_packages/mzansi_ai/mzansi_ai.dart'; +import 'package:mzansi_innovation_hub/mih_packages/mzansi_directory/mzansi_directory.dart'; +import 'package:mzansi_innovation_hub/mih_packages/mzansi_profile/business_profile/mzansi_business_profile.dart'; +import 'package:mzansi_innovation_hub/mih_packages/mzansi_profile/business_profile/mzansi_business_profile_view.dart'; +import 'package:mzansi_innovation_hub/mih_packages/mzansi_profile/business_profile/profile_business_add.dart'; +import 'package:mzansi_innovation_hub/mih_packages/mzansi_profile/personal_profile/mzansi_profile.dart'; +import 'package:mzansi_innovation_hub/mih_packages/mzansi_profile/personal_profile/mzansi_profile_view.dart'; +import 'package:ken_logger/ken_logger.dart'; +import 'package:mzansi_innovation_hub/mih_packages/mzansi_wallet/components/mih_barcode_scanner.dart'; +import 'package:mzansi_innovation_hub/mih_packages/mzansi_wallet/mih_wallet.dart'; +import 'package:mzansi_innovation_hub/mih_packages/patient_profile/pat_manager/pat_manager.dart'; +import 'package:mzansi_innovation_hub/mih_packages/patient_profile/pat_profile/add_or_view_patient.dart'; +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:supertokens_flutter/supertokens.dart'; + +class MihGoRouterPaths { + // External + static const String resetPassword = '/auth/reset-password'; + static const String privacyPolicyExternal = '/privacy-policy'; + static const String termsOfServiceExternal = '/terms-of-service'; + + // Internal + // static const String authCheck = '/'; + static const String mihAuthentication = '/mih-authentication'; + static const String mihHome = '/'; + static const String notifications = '/notifications'; + static const String forgotPassword = '/mih-authentication/forgot-password'; + static const String aboutMih = '/about'; + static const String mzansiProfileManage = '/mzansi-profile'; + static const String mzansiProfileView = '/mzansi-profile/view'; + static const String businessProfileSetup = '/business-profile/set-up'; + static const String businessProfileManage = '/business-profile/manage'; + static const String businessProfileView = '/business-profile/view'; + static const String patientProfile = '/patient-profile'; + static const String patientProfileSetup = '/patient-profile/set-up'; + static const String patientProfileEdit = '/patient-profile/edit'; + static const String mzansiWallet = '/mzansi-wallet'; + static const String mzansiDirectory = '/mzansi-directory'; + static const String mihAccess = '/mih-access'; + static const String calendar = '/calendar'; + static const String appointments = '/appointments'; + static const String patientManager = '/patient-manager'; + static const String patientManagerPatient = '/patient-manager/patient'; + static const String fileViewer = '/file-veiwer'; + static const String printPreview = '/file-veiwer/print-preview'; + static const String barcodeScanner = '/scanner'; + static const String calculator = '/calculator'; + static const String mzansiAi = '/mzansi-ai'; + static const String packageDevTest = '/package-dev'; +} + +class MihGoRouter { + final GoRouter mihRouter = GoRouter( + initialLocation: MihGoRouterPaths.mihHome, + redirect: (BuildContext context, GoRouterState state) async { + final bool isUserSignedIn = await SuperTokens.doesSessionExist(); + final unauthenticatedPaths = [ + MihGoRouterPaths.mihAuthentication, + MihGoRouterPaths.forgotPassword, + MihGoRouterPaths.resetPassword, + MihGoRouterPaths.aboutMih, + MihGoRouterPaths.businessProfileView, + ]; + KenLogger.success( + "Redirect Check: ${state.fullPath}, isUserSignedIn: $isUserSignedIn"); + if (!isUserSignedIn && !unauthenticatedPaths.contains(state.fullPath)) { + return MihGoRouterPaths.mihAuthentication; + } + if (isUserSignedIn && + unauthenticatedPaths.contains(state.fullPath) && + state.fullPath != MihGoRouterPaths.aboutMih && + state.fullPath != MihGoRouterPaths.businessProfileView) { + return MihGoRouterPaths.mihHome; + } + return null; // Stay on current route + }, + routes: [ + // ========================== MIH Auth ================================== + GoRoute( + name: "mihAuthentication", + path: MihGoRouterPaths.mihAuthentication, + builder: (BuildContext context, GoRouterState state) { + KenLogger.success("MihGoRouter: mihAuthentication"); + return MihAuthentication(); + }, + ), + GoRoute( + name: "forgotPassword", + path: MihGoRouterPaths.forgotPassword, + builder: (BuildContext context, GoRouterState state) { + KenLogger.success("MihGoRouter: forgotPassword"); + return const MihAuthForgotPassword(); + }, + ), + GoRoute( + name: "resetPassword", + path: MihGoRouterPaths.resetPassword, + builder: (BuildContext context, GoRouterState state) { + KenLogger.success("MihGoRouter: resetPassword"); + String? token = state.uri.queryParameters['token']; + KenLogger.success("token: $token"); + if (token == null) { + WidgetsBinding.instance.addPostFrameCallback((_) { + context.go(MihGoRouterPaths.mihHome); + }); + return const SizedBox.shrink(); + } + return MihAuthPasswordReset(token: token); + }, + ), + // ========================== MIH Home ================================== + GoRoute( + name: "mihHome", + 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, + ); + }, + ), + // ========================== About MIH ================================== + GoRoute( + name: "aboutMih", + path: MihGoRouterPaths.aboutMih, + builder: (BuildContext context, GoRouterState state) { + KenLogger.success("MihGoRouter: aboutMih"); + final int? packageIndex = state.extra as int?; + int index = 0; + if (packageIndex != null) { + index = packageIndex; + } + return AboutMih(packageIndex: index); + }, + ), + // ========================== Mzansi Profile Personal ================================== + GoRoute( + name: "mzansiProfileManage", + path: MihGoRouterPaths.mzansiProfileManage, + builder: (BuildContext context, GoRouterState state) { + KenLogger.success("MihGoRouter: mzansiProfileManage"); + final AppProfileUpdateArguments? args = + state.extra as AppProfileUpdateArguments?; + if (args == null) { + WidgetsBinding.instance.addPostFrameCallback((_) { + context.go(MihGoRouterPaths.mihHome); + }); + return const SizedBox.shrink(); + } + return MzansiProfile(arguments: args); + }, + ), + GoRoute( + name: "mzansiProfileView", + path: MihGoRouterPaths.mzansiProfileView, + builder: (BuildContext context, GoRouterState state) { + KenLogger.success("MihGoRouter: mzansiProfileView"); + final AppUser? user = state.extra as AppUser?; + if (user == null) { + WidgetsBinding.instance.addPostFrameCallback((_) { + context.go(MihGoRouterPaths.mihHome); + }); + return const SizedBox.shrink(); + } + return MzansiProfileView(user: user); + }, + ), + // ========================== Mzansi Profile Business ================================== + GoRoute( + name: "businessProfileManage", + path: MihGoRouterPaths.businessProfileManage, + builder: (BuildContext context, GoRouterState state) { + KenLogger.success("MihGoRouter: businessProfileManage"); + final BusinessArguments? args = state.extra as BusinessArguments?; + if (args == null) { + WidgetsBinding.instance.addPostFrameCallback((_) { + context.go(MihGoRouterPaths.mihHome); + }); + return const SizedBox.shrink(); + } + return MzansiBusinessProfile( + key: UniqueKey(), + arguments: args, + ); + }, + ), + GoRoute( + name: "businessProfileView", + path: MihGoRouterPaths.businessProfileView, + builder: (BuildContext context, GoRouterState state) { + KenLogger.success("MihGoRouter: businessProfileView"); + String? businessId = state.uri.queryParameters['business_id']; + KenLogger.success("businessId: $businessId"); + final BusinessViewArguments? args = + state.extra as BusinessViewArguments?; + if (args == null && businessId == null) { + WidgetsBinding.instance.addPostFrameCallback((_) { + context.go(MihGoRouterPaths.mihHome); + }); + return const SizedBox.shrink(); + } + return MzansiBusinessProfileView( + key: UniqueKey(), + arguments: args, + businessId: businessId, + ); + }, + ), + GoRoute( + name: "businessProfileSetup", + path: MihGoRouterPaths.businessProfileSetup, + builder: (BuildContext context, GoRouterState state) { + KenLogger.success("MihGoRouter: businessProfileSetup"); + final AppUser? signedInUser = state.extra as AppUser?; + return ProfileBusinessAdd(signedInUser: signedInUser!); + }, + ), + // ========================== MIH Calculator ================================== + GoRoute( + name: "mihCalculator", + path: MihGoRouterPaths.calculator, + builder: (BuildContext context, GoRouterState state) { + KenLogger.success("MihGoRouter: mihCalculator"); + final bool? personalSelected = state.extra as bool?; + bool personal = true; + if (personalSelected != null) { + personal = personalSelected; + } + return MIHCalculator(personalSelected: personal); + }, + ), + // ========================== MIH Calculator ================================== + GoRoute( + name: "mihCalendar", + path: MihGoRouterPaths.calendar, + builder: (BuildContext context, GoRouterState state) { + KenLogger.success("MihGoRouter: mihCalendar"); + final CalendarArguments? args = state.extra as CalendarArguments?; + if (args == null) { + WidgetsBinding.instance.addPostFrameCallback((_) { + context.go(MihGoRouterPaths.mihHome); + }); + return const SizedBox.shrink(); + } + return MzansiCalendar( + key: UniqueKey(), + arguments: args, + ); + }, + ), + // ========================== Mzansi AI ================================== + GoRoute( + name: "mzansiAi", + path: MihGoRouterPaths.mzansiAi, + builder: (BuildContext context, GoRouterState state) { + KenLogger.success("MihGoRouter: mzansiAi"); + final MzansiAiArguments? args = state.extra as MzansiAiArguments?; + if (args == null) { + WidgetsBinding.instance.addPostFrameCallback((_) { + context.go(MihGoRouterPaths.mihHome); + }); + return const SizedBox.shrink(); + } + return MzansiAi(arguments: args); + }, + ), + // ========================== Mzansi Wallet ================================== + GoRoute( + name: "mzansiWallet", + path: MihGoRouterPaths.mzansiWallet, + builder: (BuildContext context, GoRouterState state) { + KenLogger.success("MihGoRouter: mzansiWallet"); + final WalletArguments? args = state.extra as WalletArguments?; + if (args == null) { + WidgetsBinding.instance.addPostFrameCallback((_) { + context.go(MihGoRouterPaths.mihHome); + }); + return const SizedBox.shrink(); + } + return MihWallet( + key: UniqueKey(), + arguments: args, + ); + }, + ), + GoRoute( + name: "barcodeScanner", + path: MihGoRouterPaths.barcodeScanner, + builder: (BuildContext context, GoRouterState state) { + KenLogger.success("MihGoRouter: barcodeScanner"); + final TextEditingController? args = + state.extra as TextEditingController?; + if (args == null) { + WidgetsBinding.instance.addPostFrameCallback((_) { + context.go(MihGoRouterPaths.mihHome); + }); + return const SizedBox.shrink(); + } + return MihBarcodeScanner(cardNumberController: args); + }, + ), + // ========================== Test Package ================================== + GoRoute( + name: "testPackage", + path: MihGoRouterPaths.packageDevTest, + builder: (BuildContext context, GoRouterState state) { + KenLogger.success("MihGoRouter: testPackage"); + final TestArguments? args = state.extra as TestArguments?; + if (args == null) { + WidgetsBinding.instance.addPostFrameCallback((_) { + context.go(MihGoRouterPaths.mihHome); + }); + return const SizedBox.shrink(); + } + return PackageTest(arguments: args); + }, + ), + // ========================== MIH Access Controls ================================== + GoRoute( + name: "mihAccess", + path: MihGoRouterPaths.mihAccess, + builder: (BuildContext context, GoRouterState state) { + final AppUser? signedInUser = state.extra as AppUser?; + if (signedInUser == null) { + WidgetsBinding.instance.addPostFrameCallback((_) { + context.go(MihGoRouterPaths.mihHome); + }); + return const SizedBox.shrink(); + } + return MihAccess( + key: UniqueKey(), + signedInUser: signedInUser, + ); + }, + ), + // ========================== Patient Profile ================================== + GoRoute( + name: "patientProfile", + path: MihGoRouterPaths.patientProfile, + builder: (BuildContext context, GoRouterState state) { + final PatientViewArguments? args = + state.extra as PatientViewArguments?; + if (args == null) { + WidgetsBinding.instance.addPostFrameCallback((_) { + context.go(MihGoRouterPaths.mihHome); + }); + return const SizedBox.shrink(); + } + return AddOrViewPatient( + key: UniqueKey(), + arguments: args, + ); + }, + ), + GoRoute( + name: "patientProfileEdit", + path: MihGoRouterPaths.patientProfileEdit, + builder: (BuildContext context, GoRouterState state) { + final PatientEditArguments? args = + state.extra as PatientEditArguments?; + if (args == null) { + WidgetsBinding.instance.addPostFrameCallback((_) { + context.go(MihGoRouterPaths.mihHome); + }); + return const SizedBox.shrink(); + } + return EditPatient( + signedInUser: args.signedInUser, + selectedPatient: args.selectedPatient, + ); + }, + ), + GoRoute( + name: "patientManager", + path: MihGoRouterPaths.patientManager, + builder: (BuildContext context, GoRouterState state) { + final PatManagerArguments? args = state.extra as PatManagerArguments?; + if (args == null) { + WidgetsBinding.instance.addPostFrameCallback((_) { + context.go(MihGoRouterPaths.mihHome); + }); + return const SizedBox.shrink(); + } + return PatManager( + key: UniqueKey(), + arguments: args, + ); + }, + ), + GoRoute( + name: "patientManagerPatient", + path: MihGoRouterPaths.patientManagerPatient, + builder: (BuildContext context, GoRouterState state) { + final PatientViewArguments? args = + state.extra as PatientViewArguments?; + if (args == null) { + WidgetsBinding.instance.addPostFrameCallback((_) { + context.go(MihGoRouterPaths.mihHome); + }); + return const SizedBox.shrink(); + } + return PatientProfile(arguments: args); + }, + ), + // ========================== Mzansi Directory ================================== + GoRoute( + name: "mzansiDirectory", + path: MihGoRouterPaths.mzansiDirectory, + builder: (BuildContext context, GoRouterState state) { + final MzansiDirectoryArguments? args = + state.extra as MzansiDirectoryArguments?; + if (args == null) { + WidgetsBinding.instance.addPostFrameCallback((_) { + context.go(MihGoRouterPaths.mihHome); + }); + return const SizedBox.shrink(); + } + return MzansiDirectory(arguments: args); + }, + ), + // ========================== End ================================== + GoRoute( + name: "fileViewer", + path: MihGoRouterPaths.fileViewer, + builder: (BuildContext context, GoRouterState state) { + final FileViewArguments? args = state.extra as FileViewArguments?; + return FullScreenFileViewer(arguments: args!); + }, + ), + GoRoute( + name: "printPreview", + path: MihGoRouterPaths.printPreview, + builder: (BuildContext context, GoRouterState state) { + final PrintPreviewArguments? args = + state.extra as PrintPreviewArguments?; + return MIHPrintPreview(arguments: args!); + }, + ), + // ========================== End ================================== +// GoRoute( +// name: "notifications", +// path: MihGoRouterPaths.notifications, +// builder: (BuildContext context, GoRouterState state) { +// final NotificationArguments? args = state.extra as NotificationArguments?; +// return MIHNotificationMessage(arguments: args!); +// }, +// ), + ], + // 3. Error handling with `errorBuilder` and `redirect` + errorBuilder: (BuildContext context, GoRouterState state) { + KenLogger.error('Invalid Route'); + return const Placeholder(); + }, + ); +} diff --git a/Frontend/lib/mih_config/mih_routeGenerator.dart b/Frontend/lib/mih_config/mih_routeGenerator.dart deleted file mode 100644 index 44deba46..00000000 --- a/Frontend/lib/mih_config/mih_routeGenerator.dart +++ /dev/null @@ -1,358 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:mzansi_innovation_hub/mih_components/mih_layout/mih_print_prevew.dart'; -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_pop_up_messages/mih_notification_message.dart'; -import 'package:mzansi_innovation_hub/mih_packages/about_mih/about_mih.dart'; -import 'package:mzansi_innovation_hub/mih_packages/about_mih/mih_policy_tos_ext/mih_privacy_polocy_external.dart'; -import 'package:mzansi_innovation_hub/mih_packages/about_mih/mih_policy_tos_ext/mih_terms_of_service_external.dart'; -import 'package:mzansi_innovation_hub/mih_packages/access_review/mih_access.dart'; -import 'package:mzansi_innovation_hub/mih_packages/authentication/auth_check.dart'; -import 'package:mzansi_innovation_hub/mih_packages/authentication/forgot_password.dart'; -import 'package:mzansi_innovation_hub/mih_packages/authentication/reset_password.dart'; -import 'package:mzansi_innovation_hub/mih_packages/calculator/mih_calculator.dart'; -import 'package:mzansi_innovation_hub/mih_packages/calendar/mzansi_calendar.dart'; -import 'package:mzansi_innovation_hub/mih_packages/mih_authentication/mih_authentication.dart'; -import 'package:mzansi_innovation_hub/mih_packages/mzansi_ai/mzansi_ai.dart'; -import 'package:mzansi_innovation_hub/mih_packages/mzansi_directory/mzansi_directory.dart'; -import 'package:mzansi_innovation_hub/mih_packages/mzansi_profile/business_profile/mzansi_business_profile.dart'; -import 'package:mzansi_innovation_hub/mih_packages/mzansi_profile/business_profile/mzansi_business_profile_view.dart'; -import 'package:mzansi_innovation_hub/mih_packages/mzansi_profile/business_profile/profile_business_add.dart'; -import 'package:mzansi_innovation_hub/mih_packages/mzansi_profile/personal_profile/mzansi_profile.dart'; -import 'package:mzansi_innovation_hub/mih_packages/mzansi_profile/personal_profile/mzansi_profile_view.dart'; -import 'package:mzansi_innovation_hub/mih_packages/mzansi_wallet/components/mih_barcode_scanner.dart'; -import 'package:mzansi_innovation_hub/mih_packages/mzansi_wallet/mih_wallet.dart'; -import 'package:mzansi_innovation_hub/mih_packages/patient_profile/pat_manager/pat_manager.dart'; -import 'package:mzansi_innovation_hub/mih_packages/patient_profile/pat_profile/add_or_view_patient.dart'; -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_add.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'; - -// 1. Define Route Names as Constants -// This prevents typos and allows for easier refactoring. -// Consider moving this to a separate `lib/constants/app_routes.dart` file -// if your project grows larger. -class AppRoutes { - // External - static const String resetPasswordExternal = '/auth/reset-password'; - static const String privacyPolicyExternal = '/privacy-policy'; - static const String termsOfServiceExternal = '/terms-of-service'; - - // Internal - static const String authCheck = '/'; - static const String mihAuthentication = '/mih-authentication'; - static const String notifications = '/notifications'; - static const String forgotPassword = '/forgot-password'; - static const String aboutMih = '/about'; - static const String mzansiProfile = '/mzansi-profile'; - static const String mzansiProfileView = '/mzansi-profile/view'; - static const String businessProfileSetup = '/business-profile/set-up'; - static const String businessProfileManage = '/business-profile/manage'; - static const String businessProfileView = '/business-profile/view'; - static const String patientProfile = '/patient-profile'; - static const String patientProfileSetup = '/patient-profile/set-up'; - static const String patientProfileEdit = '/patient-profile/edit'; - static const String mzansiWallet = '/mzansi-wallet'; - static const String mzansiDirectory = '/mzansi-directory'; - static const String mihAccess = '/mih-access'; - static const String calendar = '/calendar'; - static const String appointments = '/appointments'; - static const String patientManager = '/patient-manager'; - static const String patientManagerPatient = '/patient-manager/patient'; - static const String fileViewer = '/file-veiwer'; - static const String printPreview = '/file-veiwer/print-preview'; - static const String barcodeScanner = '/scanner'; - static const String calculator = '/calculator'; - static const String mzansiAi = '/mzansi-ai'; - static const String packageDevTest = '/package-dev'; -} - -class RouteGenerator { - static Route generateRoute(RouteSettings settings) { - final args = settings.arguments; - final extPath = - Uri.base.path; // Moved outside the internal switch for clarity - - // 2. Prioritize External Links - // Using an if-else if chain for external routes might be slightly - // more performant than a switch if there are many external routes, - // as it avoids string hashing for each case. For a small number, - // a switch is also fine. - if (extPath == AppRoutes.resetPasswordExternal) { - return MaterialPageRoute( - settings: settings, - builder: (_) => ResetPassword(token: Uri.base.queryParameters['token']), - ); - } else if (extPath == AppRoutes.privacyPolicyExternal) { - return MaterialPageRoute( - settings: settings, - builder: (_) => const MIHPrivacyPolocyExternal(), - ); - } else if (extPath == AppRoutes.termsOfServiceExternal) { - return MaterialPageRoute( - settings: settings, - builder: (_) => const MIHTermsOfServiceExternal(), - ); - } - - // 3. Handle Internal Navigation with a Switch Statement - // This switch now only deals with internal app routes, making it cleaner. - switch (settings.name) { - case AppRoutes.authCheck: - if (args is AuthArguments) { - return MaterialPageRoute( - settings: settings, - builder: (_) => AuthCheck( - personalSelected: args.personalSelected, - firstBoot: args.firstBoot, - ), - ); - } - break; // Use break and fall through to _errorRoute if argument type is wrong - - case AppRoutes.mihAuthentication: - // if (args is AuthArguments) { - return MaterialPageRoute( - settings: settings, - builder: (_) => MihAuthentication(), - ); - // } - // break; // Use break and fall through to _errorRoute if argument type is wrong - case AppRoutes.mzansiDirectory: - if (args is MzansiDirectoryArguments) { - return MaterialPageRoute( - settings: settings, - builder: (_) => MzansiDirectory(arguments: args), - ); - } - break; - case AppRoutes.notifications: - if (args is NotificationArguments) { - return MaterialPageRoute( - settings: settings, - builder: (_) => MIHNotificationMessage(arguments: args), - ); - } - break; - - case AppRoutes.forgotPassword: - return MaterialPageRoute( - settings: settings, builder: (_) => const ForgotPassword()); - - case AppRoutes.aboutMih: - if (args is int) { - return MaterialPageRoute( - settings: settings, - builder: (_) => AboutMih(packageIndex: args), - ); - } else { - return MaterialPageRoute( - settings: settings, - builder: (_) => AboutMih(), - ); - } - - case AppRoutes.mzansiProfile: - if (args is AppProfileUpdateArguments) { - return MaterialPageRoute( - settings: settings, - builder: (_) => MzansiProfile(arguments: args), - ); - } - break; - - case AppRoutes.mzansiProfileView: - if (args is AppUser) { - return MaterialPageRoute( - settings: settings, - builder: (_) => MzansiProfileView(user: args), - ); - } - break; - - case AppRoutes.businessProfileSetup: - if (args is AppUser) { - return MaterialPageRoute( - settings: settings, - builder: (_) => ProfileBusinessAdd(signedInUser: args), - ); - } - break; - - case AppRoutes.businessProfileManage: - if (args is BusinessArguments) { - return MaterialPageRoute( - settings: settings, - builder: (_) => MzansiBusinessProfile(arguments: args), - ); - } - break; - - case AppRoutes.businessProfileView: - if (args is BusinessViewArguments) { - return MaterialPageRoute( - settings: settings, - builder: (_) => MzansiBusinessProfileView(arguments: args), - ); - } - break; - - case AppRoutes.patientProfile: - if (args is PatientViewArguments) { - return MaterialPageRoute( - settings: settings, - builder: (_) => AddOrViewPatient(arguments: args), - ); - } - break; - - case AppRoutes.patientProfileSetup: - if (args is AppUser) { - return MaterialPageRoute( - settings: settings, - builder: (_) => AddPatient(signedInUser: args), - ); - } - break; - - case AppRoutes.patientProfileEdit: - if (args is PatientEditArguments) { - return MaterialPageRoute( - settings: settings, - builder: (_) => EditPatient( - signedInUser: args.signedInUser, - selectedPatient: args.selectedPatient, - ), - ); - } - break; - - case AppRoutes.mzansiWallet: - if (args is WalletArguments) { - return MaterialPageRoute( - settings: settings, - builder: (_) => MihWallet(arguments: args), - ); - } - break; - - case AppRoutes.mihAccess: - if (args is AppUser) { - return MaterialPageRoute( - settings: settings, - builder: (_) => MihAccess(signedInUser: args), - ); - } - break; - - // 4. Handle Calendar/Appointments - Unified to one case or keep separate as needed - case AppRoutes.calendar: - case AppRoutes - .appointments: // Fall-through if both lead to the same screen - if (args is CalendarArguments) { - return MaterialPageRoute( - settings: settings, - builder: (_) => MzansiCalendar(arguments: args), - ); - } - break; - - case AppRoutes.patientManager: - if (args is PatManagerArguments) { - return MaterialPageRoute( - settings: settings, - builder: (_) => PatManager(arguments: args), - ); - } - break; - - case AppRoutes.patientManagerPatient: - if (args is PatientViewArguments) { - return MaterialPageRoute( - settings: settings, - builder: (_) => PatientProfile(arguments: args), - ); - } - break; - - case AppRoutes.fileViewer: - if (args is FileViewArguments) { - return MaterialPageRoute( - settings: settings, - builder: (_) => FullScreenFileViewer(arguments: args), - ); - } - break; - - case AppRoutes.printPreview: - if (args is PrintPreviewArguments) { - return MaterialPageRoute( - settings: settings, - builder: (_) => MIHPrintPreview(arguments: args), - ); - } - break; - - case AppRoutes.barcodeScanner: - if (args is TextEditingController) { - return MaterialPageRoute( - settings: settings, - builder: (_) => MihBarcodeScanner(cardNumberController: args), - ); - } - break; - - case AppRoutes.calculator: - if (args is bool) { - return MaterialPageRoute( - settings: settings, - builder: (_) => MIHCalculator(personalSelected: args), - ); - } - break; - - case AppRoutes.mzansiAi: - if (args is MzansiAiArguments) { - return MaterialPageRoute( - settings: settings, - builder: (_) => MzansiAi(arguments: args), - ); - } - break; - - case AppRoutes.packageDevTest: - if (args is TestArguments) { - return MaterialPageRoute( - settings: settings, - builder: (_) => PackageTest(arguments: args), - ); - } - break; - - default: - // If no match is found, fall through to the error route - break; - } - - // 5. Consolidated Error Route Call - // If any of the internal cases fail (e.g., wrong argument type or no matching route), - // it will fall through here. - return _errorRoute(); - } - - // 6. Refined Error Route - // Providing a simple, clear error message or redirection. - static Route _errorRoute() { - debugPrint( - "Invalid Route or Missing/Incorrect Arguments"); // Use debugPrint for development logs - return MaterialPageRoute( - settings: const RouteSettings(name: AppRoutes.authCheck), - builder: (_) => const AuthCheck( - personalSelected: true, - firstBoot: true, - ), - ); - } -} diff --git a/Frontend/lib/mih_config/mih_theme.dart b/Frontend/lib/mih_config/mih_theme.dart index 5a836a42..e582f7cc 100644 --- a/Frontend/lib/mih_config/mih_theme.dart +++ b/Frontend/lib/mih_config/mih_theme.dart @@ -14,7 +14,7 @@ class MihTheme { late String loadingAssetText; late TargetPlatform platform; bool kIsWeb = const bool.fromEnvironment('dart.library.js_util'); - String latestVersion = "1.1.15"; + String latestVersion = "1.2.0"; // Options:- // f3f9d2 = Cream // f0f0c9 = cream2 diff --git a/Frontend/lib/mih_packages/about_mih/about_mih.dart b/Frontend/lib/mih_packages/about_mih/about_mih.dart index 52eb7286..7d89b12d 100644 --- a/Frontend/lib/mih_packages/about_mih/about_mih.dart +++ b/Frontend/lib/mih_packages/about_mih/about_mih.dart @@ -1,3 +1,4 @@ +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'; @@ -25,7 +26,7 @@ class _AboutMihState extends State { void initState() { super.initState(); setState(() { - if(widget.packageIndex == null) { + if (widget.packageIndex == null) { _selcetedIndex = 0; } else { _selcetedIndex = widget.packageIndex!; @@ -55,7 +56,10 @@ class _AboutMihState extends State { icon: const Icon(Icons.arrow_back), iconSize: 35, onTap: () { - Navigator.of(context).pop(); + context.goNamed( + 'mihHome', + extra: true, + ); FocusScope.of(context).unfocus(); }, ); diff --git a/Frontend/lib/mih_packages/about_mih/package_tile/about_mih_tile.dart b/Frontend/lib/mih_packages/about_mih/package_tile/about_mih_tile.dart index f8e1bba1..90759872 100644 --- a/Frontend/lib/mih_packages/about_mih/package_tile/about_mih_tile.dart +++ b/Frontend/lib/mih_packages/about_mih/package_tile/about_mih_tile.dart @@ -1,3 +1,4 @@ +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_tile.dart'; import 'package:flutter/material.dart'; @@ -20,10 +21,14 @@ class _AboutMihTileState extends State { Widget build(BuildContext context) { return MihPackageTile( onTap: () { - Navigator.of(context).pushNamed( - '/about', - arguments: 0, + context.goNamed( + "aboutMih", + extra: 0, ); + // Navigator.of(context).pushNamed( + // '/about', + // arguments: 0, + // ); }, appName: "About MIH", appIcon: Icon( diff --git a/Frontend/lib/mih_packages/access_review/builder/build_business_access_list.dart b/Frontend/lib/mih_packages/access_review/builder/build_business_access_list.dart index b7e76704..2aca7f2c 100644 --- a/Frontend/lib/mih_packages/access_review/builder/build_business_access_list.dart +++ b/Frontend/lib/mih_packages/access_review/builder/build_business_access_list.dart @@ -1,11 +1,13 @@ 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_package_alert.dart'; import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart'; -import 'package:mzansi_innovation_hub/mih_services/mih_service_calls.dart'; +import 'package:mzansi_innovation_hub/mih_services/mih_access_controls_services.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_window.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_success_message.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_warning_message.dart'; import 'package:mzansi_innovation_hub/mih_config/mih_env.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_objects/app_user.dart'; @@ -14,11 +16,13 @@ import 'package:mzansi_innovation_hub/mih_components/mih_objects/patient_access. class BuildBusinessAccessList extends StatefulWidget { final List patientAccessList; final AppUser signedInUser; + final void Function()? onSuccessUpate; const BuildBusinessAccessList({ super.key, required this.patientAccessList, required this.signedInUser, + required this.onSuccessUpate, }); @override @@ -47,18 +51,6 @@ class _BuildPatientsListState extends State { ); } - void successPopUp(String message) { - showDialog( - context: context, - builder: (context) { - return MIHSuccessMessage( - successType: "Success", - successMessage: message, - ); - }, - ); - } - void accessCancelledWarning() { showDialog( context: context, @@ -352,9 +344,10 @@ class _BuildPatientsListState extends State { spacing: 10, children: [ MihButton( - onPressed: () { + onPressed: () async { print("request declined"); - MIHApiCalls.updatePatientAccessAPICall( + int statusCode = await MihAccessControlsServices() + .updatePatientAccessAPICall( widget.patientAccessList[index].business_id, widget.patientAccessList[index].requested_by, widget.patientAccessList[index].app_id, @@ -363,6 +356,13 @@ class _BuildPatientsListState extends State { widget.signedInUser, context, ); + if (statusCode == 200) { + context.pop(); + successPopUp("Successfully Actioned Request", + "You have successfully Declined access request"); + } else { + internetConnectionPopUp(); + } }, buttonColor: MihColors.getRedColor( MzansiInnovationHub.of(context)!.theme.mode == @@ -380,9 +380,10 @@ class _BuildPatientsListState extends State { ), ), MihButton( - onPressed: () { + onPressed: () async { print("request approved"); - MIHApiCalls.updatePatientAccessAPICall( + int statusCode = await MihAccessControlsServices() + .updatePatientAccessAPICall( widget.patientAccessList[index].business_id, widget.patientAccessList[index].requested_by, widget.patientAccessList[index].app_id, @@ -391,6 +392,13 @@ class _BuildPatientsListState extends State { widget.signedInUser, context, ); + if (statusCode == 200) { + context.pop(); + successPopUp("Successfully Actioned Request", + "You have successfully Accepted access request"); + } else { + internetConnectionPopUp(); + } }, buttonColor: MihColors.getGreenColor( MzansiInnovationHub.of(context)!.theme.mode == @@ -421,6 +429,64 @@ class _BuildPatientsListState extends State { ); } + void successPopUp(String title, String message) { + 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: title, + 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(); + KenLogger.warning("dismissing pop up and refreshing list"); + if (widget.onSuccessUpate != null) { + widget.onSuccessUpate!(); + } + }, + 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"), + ); + }, + ); + } + @override void dispose() { super.dispose(); diff --git a/Frontend/lib/mih_packages/access_review/mih_access.dart b/Frontend/lib/mih_packages/access_review/mih_access.dart index 728a00c8..3812784a 100644 --- a/Frontend/lib/mih_packages/access_review/mih_access.dart +++ b/Frontend/lib/mih_packages/access_review/mih_access.dart @@ -1,3 +1,4 @@ +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'; @@ -40,7 +41,10 @@ class _MihAccessState extends State { icon: const Icon(Icons.arrow_back), iconSize: 35, onTap: () { - Navigator.of(context).pop(); + context.goNamed( + 'mihHome', + extra: true, + ); FocusScope.of(context).unfocus(); }, ); diff --git a/Frontend/lib/mih_packages/access_review/package_tile/mih_access_tile.dart b/Frontend/lib/mih_packages/access_review/package_tile/mih_access_tile.dart index 561755ca..1e5a4ea7 100644 --- a/Frontend/lib/mih_packages/access_review/package_tile/mih_access_tile.dart +++ b/Frontend/lib/mih_packages/access_review/package_tile/mih_access_tile.dart @@ -1,3 +1,4 @@ +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_tile.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_icons.dart'; @@ -23,11 +24,16 @@ class _MihAccessTileState extends State { @override Widget build(BuildContext context) { return MihPackageTile( + authenticateUser: true, onTap: () { - Navigator.of(context).pushNamed( - '/mih-access', - arguments: widget.signedInUser, + context.goNamed( + "mihAccess", + extra: widget.signedInUser, ); + // Navigator.of(context).pushNamed( + // '/mih-access', + // arguments: widget.signedInUser, + // ); }, appName: "Access Controls", appIcon: Icon( diff --git a/Frontend/lib/mih_packages/access_review/package_tools/mih_access_requests.dart b/Frontend/lib/mih_packages/access_review/package_tools/mih_access_requests.dart index 49cfe479..aca607c2 100644 --- a/Frontend/lib/mih_packages/access_review/package_tools/mih_access_requests.dart +++ b/Frontend/lib/mih_packages/access_review/package_tools/mih_access_requests.dart @@ -1,3 +1,5 @@ +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_icons.dart'; import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart'; @@ -5,7 +7,6 @@ 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_dropdwn_field.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_tool_body.dart'; -import 'package:mzansi_innovation_hub/mih_components/mih_objects/arguments.dart'; import 'package:flutter/material.dart'; import '../../../mih_services/mih_service_calls.dart'; import '../../../mih_components/mih_layout/mih_action.dart'; @@ -105,12 +106,11 @@ class _MihAccessRequestState extends State { icon: const Icon(Icons.arrow_back), iconSize: 35, onTap: () { - Navigator.of(context).pop(); - - Navigator.of(context).popAndPushNamed( - '/', - arguments: AuthArguments(true, false), + context.goNamed( + 'mihHome', + extra: false, ); + FocusScope.of(context).unfocus(); }, ); } @@ -164,6 +164,7 @@ class _MihAccessRequestState extends State { setState(() { forceRefresh = true; }); + KenLogger.warning("Refreshing Access List"); refreshList(); }, icon: const Icon( @@ -186,6 +187,12 @@ class _MihAccessRequestState extends State { return BuildBusinessAccessList( signedInUser: widget.signedInUser, patientAccessList: accessRequestList, + onSuccessUpate: () { + setState(() { + forceRefresh = true; + }); + refreshList(); + }, ); } else { return Padding( diff --git a/Frontend/lib/mih_packages/authentication/auth_check.dart b/Frontend/lib/mih_packages/authentication/auth_check.dart deleted file mode 100644 index 5aed287b..00000000 --- a/Frontend/lib/mih_packages/authentication/auth_check.dart +++ /dev/null @@ -1,92 +0,0 @@ -import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_loading_circle.dart'; -import 'package:mzansi_innovation_hub/mih_packages/authentication/biometric_check.dart'; -import 'package:flutter/material.dart'; -import 'package:mzansi_innovation_hub/mih_packages/mih_authentication/mih_authentication.dart'; - -import 'package:supertokens_flutter/supertokens.dart'; -// import 'package:no_screenshot/no_screenshot.dart'; - -class AuthCheck extends StatefulWidget { - final bool personalSelected; - final bool firstBoot; - const AuthCheck({ - super.key, - required this.personalSelected, - required this.firstBoot, - }); - - @override - State createState() => _AuthCheckState(); -} - -class _AuthCheckState extends State { - // final _noScreenshot = NoScreenshot.instance; - - Future doesSessionExist() async { - //wait - //await Future.delayed(const Duration(seconds: 1)); - bool signedIn = await SuperTokens.doesSessionExist(); - return signedIn; - } - - // void disableScreenshot() async { - // try { - // bool result = await _noScreenshot.screenshotOff(); - // print('Screenshot Off: $result'); - // } on Exception { - // print("Web"); - // } - // } - - @override - void initState() { - //signedIn = doesSessionExist(); - // disableScreenshot(); Screenshot - // var brightness = - // SchedulerBinding.instance.platformDispatcher.platformBrightness; - // bool isDarkMode = brightness == Brightness.dark; - // if (isDarkMode) { - // MzansiInnovationHub.of(context)!.theme.mode = "Dark"; - // } else { - // MzansiInnovationHub.of(context)!.theme.mode = "Light"; - // } - super.initState(); - } - - @override - Widget build(BuildContext context) { - return Scaffold( - body: OrientationBuilder( - builder: (BuildContext context, Orientation orientation) { - // Return a widget tree based on the orientation - return FutureBuilder( - future: doesSessionExist(), - builder: (context, snapshot) { - //print(snapshot.data); - if (snapshot.data == true) { - return BiometricCheck( - personalSelected: widget.personalSelected, - firstBoot: widget.firstBoot, - ); - } else if (snapshot.data == false) { - return MihAuthentication(); - } else { - return - // const SizedBox(width: 5, height: 5); - const Mihloadingcircle(); - } - }); - }, - // child: FutureBuilder( - // future: signedIn, - // builder: (context, snapshot) { - // if (snapshot.data == true) { - // return const MIHProfileGetter(); - // } else { - // return const SignInOrRegister(); - // } - // }), - ), - ); - } -} diff --git a/Frontend/lib/mih_packages/authentication/biometric_check.dart b/Frontend/lib/mih_packages/authentication/biometric_check.dart deleted file mode 100644 index a80aefb5..00000000 --- a/Frontend/lib/mih_packages/authentication/biometric_check.dart +++ /dev/null @@ -1,300 +0,0 @@ -import 'package:mzansi_innovation_hub/main.dart'; -import 'package:mzansi_innovation_hub/mih_components/mih_layout/mih_action.dart'; -import 'package:mzansi_innovation_hub/mih_components/mih_layout/mih_body.dart'; -import 'package:mzansi_innovation_hub/mih_components/mih_layout/mih_header.dart'; -import 'package:mzansi_innovation_hub/mih_components/mih_layout/mih_layout_builder.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_alert.dart'; -import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_icons.dart'; -import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart'; -import 'package:mzansi_innovation_hub/mih_packages/mih_home/mih_profile_getter.dart'; -import 'package:flutter/material.dart'; -import 'package:local_auth/local_auth.dart'; -import 'package:supertokens_flutter/supertokens.dart'; -import 'package:app_settings/app_settings.dart'; - -class BiometricCheck extends StatefulWidget { - final bool personalSelected; - final bool firstBoot; - const BiometricCheck({ - super.key, - required this.personalSelected, - required this.firstBoot, - }); - - @override - State createState() => _BiometricCheckState(); -} - -class _BiometricCheckState extends State { - bool _isBioAuthenticated = false; - final LocalAuthentication _auth = LocalAuthentication(); - - MIHAction getActionButton() { - return MIHAction( - icon: Padding( - padding: const EdgeInsets.all(10.0), - child: SizedBox( - height: 50, - child: FittedBox( - child: Icon( - MihIcons.mihLogo, - color: MihColors.getSecondaryColor( - MzansiInnovationHub.of(context)!.theme.mode == "Dark"), - ), - ), - ), - ), - iconSize: 35, - onTap: () async { - await SuperTokens.signOut(completionHandler: (error) { - print(error); - }); - if (await SuperTokens.doesSessionExist() == false) { - Navigator.of(context).popAndPushNamed('/'); - } - // Navigator.of(context).pushNamed( - // '/about', - // //arguments: widget.signedInUser, - // ); - }, - ); - } - - MIHHeader getHeader() { - return const MIHHeader( - headerAlignment: MainAxisAlignment.center, - headerItems: [ - Text( - "", - style: TextStyle( - fontWeight: FontWeight.bold, - fontSize: 25, - ), - ), - ], - ); - } - - void authenticateUser() async { - final bool canAuthWithBio = await _auth.canCheckBiometrics; - final bool canAuthenticate = - canAuthWithBio || await _auth.isDeviceSupported(); - print("Auth Available: $canAuthenticate"); - if (canAuthenticate) { - try { - final bool didBioAuth = await _auth.authenticate( - localizedReason: "Authenticate to access MIH", - options: const AuthenticationOptions( - biometricOnly: false, - ), - ); - if (didBioAuth) { - setState(() { - _isBioAuthenticated = true; - }); - } else { - authErrorPopUp(); - } - // print("Authenticated: $didBioAuth"); - } catch (error) { - print("Auth Error: $error"); - authErrorPopUp(); - } - } else { - print("Auth Error: No Biometrics Available"); - authErrorPopUp(); - } - } - - void authErrorPopUp() { - Widget alertpopUp = MihPackageAlert( - alertIcon: Icon( - Icons.fingerprint, - color: MihColors.getRedColor( - MzansiInnovationHub.of(context)!.theme.mode == "Dark"), - size: 100, - ), - alertTitle: "Biometric Authentication Error", - alertBody: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text( - "Hi there! To jump into the MIH Home Package, you'll need to authenticate yourself with your phones biometrics, please set up biometric authentication (like fingerprint, face ID, pattern or pin) on your device first.\n\nIf you have already set up biometric authentication, press \"Authenticate now\" to try again or press \"Set Up Authentication\" to go to your device settings.", - style: TextStyle( - fontSize: 15, - color: MihColors.getSecondaryColor( - MzansiInnovationHub.of(context)!.theme.mode == "Dark"), - ), - ), - const SizedBox(height: 20), - Wrap( - runAlignment: WrapAlignment.center, - crossAxisAlignment: WrapCrossAlignment.center, - spacing: 10, - runSpacing: 10, - children: [ - MihButton( - onPressed: () { - AppSettings.openAppSettings( - type: AppSettingsType.security, - ); - Navigator.of(context).pop(); - }, - buttonColor: MihColors.getSecondaryColor( - MzansiInnovationHub.of(context)!.theme.mode == "Dark"), - width: 300, - child: Text( - "Set Up Authentication", - style: TextStyle( - color: MihColors.getPrimaryColor( - MzansiInnovationHub.of(context)!.theme.mode == "Dark"), - fontSize: 20, - fontWeight: FontWeight.bold, - ), - ), - ), - MihButton( - onPressed: () { - Navigator.of(context).pop(); - authenticateUser(); - }, - buttonColor: MihColors.getGreenColor( - MzansiInnovationHub.of(context)!.theme.mode == "Dark"), - width: 300, - child: Text( - "Authenticate Now", - 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"), - ); - showDialog( - context: context, - builder: (context) { - return alertpopUp; - }, - ); - } - - MIHBody getBody() { - return MIHBody( - borderOn: false, - bodyItems: [ - SafeArea( - child: Center( - child: Padding( - padding: const EdgeInsets.all(25.0), - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - //logo - Icon( - Icons.fingerprint, - size: 100, - color: MihColors.getSecondaryColor( - MzansiInnovationHub.of(context)!.theme.mode == "Dark"), - ), - //spacer - const SizedBox(height: 10), - //Heading - Text( - 'Biomentric Authentication', - textAlign: TextAlign.center, - style: TextStyle( - fontSize: 25, - fontWeight: FontWeight.bold, - color: MihColors.getSecondaryColor( - MzansiInnovationHub.of(context)!.theme.mode == - "Dark"), - ), - ), - //spacer - const SizedBox(height: 25), - // if (!_isBioAuthenticated) - Icon( - Icons.lock, - size: 200, - color: MihColors.getSecondaryColor( - MzansiInnovationHub.of(context)!.theme.mode == "Dark"), - ), - const SizedBox(height: 30), - MihButton( - onPressed: () { - authenticateUser(); - }, - buttonColor: MihColors.getGreenColor( - MzansiInnovationHub.of(context)!.theme.mode == "Dark"), - width: 300, - child: Text( - "Authenticate Now", - style: TextStyle( - color: MihColors.getPrimaryColor( - MzansiInnovationHub.of(context)!.theme.mode == - "Dark"), - fontSize: 20, - fontWeight: FontWeight.bold, - ), - ), - ), - ], - ), - ), - ), - ), - ], - ); - } - - Widget getBiomentricAuthScreen() { - return MIHLayoutBuilder( - actionButton: getActionButton(), - header: getHeader(), - secondaryActionButton: null, - body: getBody(), - actionDrawer: null, - secondaryActionDrawer: null, - bottomNavBar: null, - pullDownToRefresh: false, - onPullDown: () async {}, - ); - } - - @override - void initState() { - // TODO: implement initState - super.initState(); - if (widget.firstBoot == true) authenticateUser(); - } - - @override - Widget build(BuildContext context) { - if (MzansiInnovationHub.of(context)!.theme.getPlatform() == "Web") { - return MIHProfileGetter( - personalSelected: widget.personalSelected, - ); - } else if (!widget.firstBoot) { - return MIHProfileGetter( - personalSelected: widget.personalSelected, - ); - } else { - if (_isBioAuthenticated) { - return MIHProfileGetter( - personalSelected: widget.personalSelected, - ); - } else { - return getBiomentricAuthScreen(); - } - } - } -} diff --git a/Frontend/lib/mih_packages/authentication/forgot_password.dart b/Frontend/lib/mih_packages/authentication/forgot_password.dart deleted file mode 100644 index a6e6bb00..00000000 --- a/Frontend/lib/mih_packages/authentication/forgot_password.dart +++ /dev/null @@ -1,352 +0,0 @@ -import 'dart:convert'; - -import 'package:flutter/material.dart'; -import 'package:flutter/services.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'; -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_alert.dart'; -import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_text_form_field.dart'; -import '../../main.dart'; -import 'package:supertokens_flutter/http.dart' as http; -import '../../mih_components/mih_layout/mih_action.dart'; -import '../../mih_components/mih_layout/mih_body.dart'; -import '../../mih_components/mih_layout/mih_header.dart'; -import '../../mih_components/mih_layout/mih_layout_builder.dart'; -import '../../mih_components/mih_pop_up_messages/mih_error_message.dart'; -import '../../mih_components/mih_pop_up_messages/mih_loading_circle.dart'; -import '../../mih_components/mih_pop_up_messages/mih_success_message.dart'; -import '../../mih_config/mih_env.dart'; - -class ForgotPassword extends StatefulWidget { - const ForgotPassword({super.key}); - - @override - State createState() => _ForgotPasswordState(); -} - -class _ForgotPasswordState extends State { - final emailController = TextEditingController(); - final _formKey = GlobalKey(); - - //bool _obscureText = true; - bool successfulForgotPassword = false; - bool acceptWarning = false; - // focus node to capture keyboard events - final FocusNode _focusNode = FocusNode(); - - final baseAPI = AppEnviroment.baseApiUrl; - - Future submitPasswodReset() async { - showDialog( - context: context, - builder: (context) { - return const Mihloadingcircle(); - }, - ); - - try { - var response = await http.post( - Uri.parse("$baseAPI/auth/user/password/reset/token"), - body: - '{"formFields": [{"id": "email","value": "${emailController.text}"}]}', - headers: { - 'Content-type': 'application/json', - 'Accept': 'application/json', - //"Authorization": "leatucczyixqwkqqdrhayiwzeofkltds" - }, - ); - //print(response.body[]) - if (response.statusCode == 200) { - //print(response.body); - var userSignedin = jsonDecode(response.body); - if (userSignedin["status"] == "OK") { - //print("here"); - setState(() { - successfulForgotPassword = true; - }); - Navigator.of(context).pop(); - } else { - Navigator.of(context).pop(); - //loginError(); - } - } - } on Exception { - Navigator.of(context).pop(); - //loginError(); - } - } - - Color getPrim() { - return MihColors.getSecondaryColor( - MzansiInnovationHub.of(context)!.theme.mode == "Dark"); - } - - Color getSec() { - return MihColors.getPrimaryColor( - MzansiInnovationHub.of(context)!.theme.mode == "Dark"); - } - - void prePassResteWarning() { - showDialog( - context: context, - builder: (context) { - return MihPackageAlert( - alertIcon: Icon( - Icons.warning_amber_rounded, - size: 100, - color: MihColors.getSecondaryColor( - MzansiInnovationHub.of(context)!.theme.mode == "Dark"), - ), - alertTitle: "Password Reset Confirmation", - alertBody: Column( - //mainAxisSize: MainAxisSize.max, - children: [ - Padding( - padding: const EdgeInsets.symmetric(horizontal: 25.0), - child: Text( - "Before you reset your password, please be aware that you'll receive an email with a link to confirm your identity and set a new password. Make sure to check your inbox, including spam or junk folders. If you don't receive the email within a few minutes, please try resending the reset request.", - style: TextStyle( - color: MihColors.getSecondaryColor( - MzansiInnovationHub.of(context)!.theme.mode == "Dark"), - fontSize: 15.0, - fontWeight: FontWeight.bold, - ), - ), - ), - const SizedBox(height: 25), - MihButton( - onPressed: () { - setState(() { - acceptWarning = true; - }); - Navigator.of(context).pop(); - validateInput(); - }, - buttonColor: MihColors.getGreenColor( - MzansiInnovationHub.of(context)!.theme.mode == "Dark"), - width: 300, - child: Text( - "Continue", - style: TextStyle( - color: MihColors.getPrimaryColor( - MzansiInnovationHub.of(context)!.theme.mode == "Dark"), - fontSize: 20, - fontWeight: FontWeight.bold, - ), - ), - ), - ], - ), - alertColour: MihColors.getSecondaryColor( - MzansiInnovationHub.of(context)!.theme.mode == "Dark"), - ); - }, - ); - } - - void loginError() { - showDialog( - context: context, - builder: (context) { - return const MIHErrorMessage(errorType: "Invalid Credentials"); - }, - ); - } - - void resetLinkSentSuccessfully() { - showDialog( - context: context, - builder: (context) { - return const MIHSuccessMessage( - successType: "Success", - successMessage: - "We've sent a password reset link to your email address. Please check your inbox, including spam or junk folders.\n\nOnce you find the email, click on the link to reset your password.\n\nIf you don't receive the email within a few minutes, please try resending the reset request.\n\nThe reset link will expire after 2 hours"); - }, - ); - } - - void validateInput() async { - if (emailController.text.isEmpty) { - showDialog( - context: context, - builder: (context) { - return const MIHErrorMessage(errorType: "Input Error"); - }, - ); - } else { - await submitPasswodReset(); - if (successfulForgotPassword) { - Navigator.of(context).pushNamedAndRemoveUntil('/', (route) => false); - resetLinkSentSuccessfully(); - } - } - } - - MIHAction getActionButton() { - return MIHAction( - icon: const Icon(Icons.arrow_back), - iconSize: 35, - onTap: () { - Navigator.of(context).pop(); - }, - ); - } - - MIHHeader getHeader() { - return const MIHHeader( - headerAlignment: MainAxisAlignment.center, - headerItems: [ - Text( - "", - style: TextStyle( - fontWeight: FontWeight.bold, - fontSize: 25, - ), - ), - ], - ); - } - - MIHBody getBody(double width) { - return MIHBody( - borderOn: false, - bodyItems: [ - KeyboardListener( - focusNode: _focusNode, - autofocus: true, - onKeyEvent: (event) async { - if (event is KeyDownEvent && - event.logicalKey == LogicalKeyboardKey.enter) { - validateInput(); - } - }, - child: SafeArea( - child: Center( - child: SingleChildScrollView( - physics: const BouncingScrollPhysics(), - child: Padding( - padding: MzansiInnovationHub.of(context)!.theme.screenType == - "desktop" - ? EdgeInsets.symmetric( - vertical: 25, horizontal: width * 0.2) - : EdgeInsets.symmetric( - vertical: 25, horizontal: width * 0.075), - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - //logo - Icon( - Icons.lock, - size: 100, - color: MihColors.getSecondaryColor( - MzansiInnovationHub.of(context)!.theme.mode == - "Dark"), - ), - //spacer - const SizedBox(height: 10), - //Heading - Text( - 'Forgot Password', - style: TextStyle( - fontSize: 25, - fontWeight: FontWeight.bold, - color: MihColors.getSecondaryColor( - MzansiInnovationHub.of(context)!.theme.mode == - "Dark"), - ), - ), - const SizedBox(height: 25), - MihForm( - formKey: _formKey, - formFields: [ - 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: "Email", - validator: (value) { - return MihValidationServices() - .validateEmail(value); - }, - ), - //spacer - const SizedBox(height: 20), - Align( - alignment: Alignment.center, - child: MihButton( - onPressed: () { - if (_formKey.currentState!.validate()) { - prePassResteWarning(); - } else { - MihAlertServices() - .formNotFilledCompletely(context); - } - }, - buttonColor: MihColors.getGreenColor( - MzansiInnovationHub.of(context)!.theme.mode == - "Dark"), - width: 300, - child: Text( - "Reset Password", - style: TextStyle( - color: MihColors.getPrimaryColor( - MzansiInnovationHub.of(context)! - .theme - .mode == - "Dark"), - fontSize: 20, - fontWeight: FontWeight.bold, - ), - ), - ), - ), - ], - ), - ], - ), - ), - ), - ), - ), - ), - ], - ); - } - - @override - void dispose() { - emailController.dispose(); - _focusNode.dispose(); - super.dispose(); - } - - @override - void initState() { - super.initState(); - } - - @override - Widget build(BuildContext context) { - double screenWidth = MediaQuery.of(context).size.width; - return MIHLayoutBuilder( - actionButton: getActionButton(), - header: getHeader(), - secondaryActionButton: null, - body: getBody(screenWidth), - actionDrawer: null, - secondaryActionDrawer: null, - bottomNavBar: null, - pullDownToRefresh: false, - onPullDown: () async {}, - ); - } -} diff --git a/Frontend/lib/mih_packages/authentication/register.dart b/Frontend/lib/mih_packages/authentication/register.dart deleted file mode 100644 index aa3e5c61..00000000 --- a/Frontend/lib/mih_packages/authentication/register.dart +++ /dev/null @@ -1,518 +0,0 @@ -import 'dart:convert'; - -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_install_services.dart'; -import 'package:mzansi_innovation_hub/mih_services/mih_validation_services.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_icons.dart'; -import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_text_form_field.dart'; -import 'package:mzansi_innovation_hub/mih_components/mih_objects/arguments.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; -import '../../main.dart'; -import 'package:supertokens_flutter/http.dart' as http; -import 'package:supertokens_flutter/supertokens.dart'; -import '../../mih_components/mih_layout/mih_action.dart'; -import '../../mih_components/mih_layout/mih_body.dart'; -import '../../mih_components/mih_layout/mih_header.dart'; -import '../../mih_components/mih_layout/mih_layout_builder.dart'; -import '../../mih_components/mih_pop_up_messages/mih_error_message.dart'; -import '../../mih_components/mih_pop_up_messages/mih_loading_circle.dart'; -import '../../mih_components/mih_pop_up_messages/mih_success_message.dart'; -import '../../mih_config/mih_env.dart'; - -class Register extends StatefulWidget { - final Function()? onTap; - const Register({super.key, required this.onTap}); - - @override - State createState() => _RegisterState(); -} - -class _RegisterState extends State { - final emailController = TextEditingController(); - final passwordController = TextEditingController(); - final confirmPasswordController = TextEditingController(); - final officeID = TextEditingController(); - final baseAPI = AppEnviroment.baseApiUrl; - final FocusNode _focusNode = FocusNode(); - final _formKey = GlobalKey(); - bool _obscureText = true; - - bool successfulSignUp = false; - - Future addUserAPICall(String email, String uid) async { - //await getOfficeIdByUser(docOfficeIdApiUrl + widget.userEmail); - //print(futureDocOfficeId.toString()); - var response = await http.post( - Uri.parse("$baseAPI/user/insert/"), - headers: { - "Content-Type": "application/json; charset=UTF-8" - }, - body: jsonEncode({ - "email": email, - "app_id": uid, - }), - ); - if (response.statusCode == 201) { - Navigator.of(context).pushNamedAndRemoveUntil( - '/', - (route) => false, - arguments: AuthArguments( - true, - true, - ), - ); - // signUpSuccess(); - // setState(() { - // successfulSignUp = true; - // }); - } else { - internetConnectionPopUp(); - } - } - - //sign user in - Future signUserUp() async { - if (!validEmail()) { - emailError(); - } else if (passwordController.text != confirmPasswordController.text) { - passwordError(); - } else { - //var _backgroundColor = Colors.transparent; - - showDialog( - context: context, - builder: (context) { - return const Mihloadingcircle(); - }, - ); - - try { - Uri uri = Uri.parse( - "$baseAPI/auth/emailpassword/email/exists?email=${emailController.text}"); - //print("Here"); - var response = await http.get(uri); - //print(response.body); - //print("response 1: ${response.statusCode}"); - if (response.statusCode == 200) { - var userExists = jsonDecode(response.body); - if (userExists["exists"]) { - Navigator.of(context).pop(); - signUpError(); - } else { - var response2 = await http.post( - Uri.parse("$baseAPI/auth/signup"), - body: - '{"formFields": [{"id": "email","value": "${emailController.text}"}, {"id": "password","value": "${passwordController.text}"}]}', - headers: { - 'Content-type': 'application/json', - 'Accept': 'application/json', - "Authorization": "leatucczyixqwkqqdrhayiwzeofkltds" - }, - ); - //print("response 2: ${response2.statusCode}"); - if (response2.statusCode == 200) { - //print("response 2: ${response2.body}"); - var userCreated = jsonDecode(response2.body); - //print("Created user $userCreated"); - if (userCreated["status"] == "OK") { - //print("Here1"); - //Creat user in db - String uid = await SuperTokens.getUserId(); - //print("uid: $uid"); - addUserAPICall(emailController.text, uid); - Navigator.of(context).pop(); - //print("Here1"); - } else if (userCreated["status"] == "FIELD_ERROR") { - Navigator.of(context).pop(); - passwordReqError(); - } else { - Navigator.of(context).pop(); - internetConnectionPopUp(); - } - } - } - } - } on Exception catch (error) { - Navigator.of(context).pop(); - loginError(error.toString()); - emailController.clear(); - passwordController.clear(); - confirmPasswordController.clear(); - } - } - } - - bool validEmail() { - String text = emailController.text; - var regex = RegExp(r'^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$'); - return regex.hasMatch(text); - } - - void internetConnectionPopUp() { - showDialog( - context: context, - builder: (context) { - return const MIHErrorMessage(errorType: "Internet Connection"); - }, - ); - } - - void signUpSuccess() { - showDialog( - context: context, - builder: (context) { - return const MIHSuccessMessage( - successType: "Success", - successMessage: - "Congratulations! Your account has been created successfully. You are logged in and can start exploring.\n\nPlease note: more apps will appear once you update your profile."); - }, - ); - } - - void signUpError() { - showDialog( - context: context, - builder: (context) { - return const MIHErrorMessage(errorType: "User Exists"); - }, - ); - } - - void passwordError() { - showDialog( - context: context, - builder: (context) { - return const MIHErrorMessage(errorType: "Password Match"); - }, - ); - } - - void emailError() { - showDialog( - context: context, - builder: (context) { - return const MIHErrorMessage(errorType: "Invalid Email"); - }, - ); - } - - void passwordReqError() { - showDialog( - context: context, - builder: (context) { - return const MIHErrorMessage(errorType: "Password Requirements"); - }, - ); - } - - void loginError(error) { - showDialog( - context: context, - builder: (context) { - return AlertDialog( - title: Text(error), - ); - }, - ); - } - - void submitFormInput() async { - await signUserUp(); - } - - void toggle() { - setState(() { - _obscureText = !_obscureText; - }); - } - - Widget getSecondaryActionButton() { - return Visibility( - visible: MzansiInnovationHub.of(context)!.theme.getPlatform() == "Web", - child: MIHAction( - icon: Padding( - padding: const EdgeInsets.all(10.0), - child: MihButton( - onPressed: () { - MihInstallServices().installMihTrigger(context); - }, - buttonColor: MihColors.getGreenColor( - MzansiInnovationHub.of(context)!.theme.mode == "Dark"), - width: 150, - child: Text( - "Install MIH", - style: TextStyle( - color: MihColors.getPrimaryColor( - MzansiInnovationHub.of(context)!.theme.mode == "Dark"), - fontSize: 20, - fontWeight: FontWeight.bold, - ), - ), - ), - ), - iconSize: 35, - onTap: () { - MihInstallServices().installMihTrigger(context); - }, - ), - ); - } - - MIHAction getActionButton() { - return MIHAction( - icon: Padding( - padding: const EdgeInsets.all(10.0), - child: SizedBox( - height: 50, - child: FittedBox( - child: Icon( - MihIcons.mihLogo, - color: MihColors.getSecondaryColor( - MzansiInnovationHub.of(context)!.theme.mode == "Dark"), - ), - ), - ), - ), - iconSize: 35, - onTap: () { - Navigator.of(context).pushNamed( - '/about', - arguments: 0, - ); - }, - ); - } - - MIHHeader getHeader() { - return const MIHHeader( - headerAlignment: MainAxisAlignment.center, - headerItems: [ - Text( - "", - style: TextStyle( - fontWeight: FontWeight.bold, - fontSize: 25, - ), - ), - ], - ); - } - - MIHBody getBody(double width) { - return MIHBody( - borderOn: false, - bodyItems: [ - KeyboardListener( - focusNode: _focusNode, - autofocus: true, - onKeyEvent: (event) async { - if (event is KeyDownEvent && - event.logicalKey == LogicalKeyboardKey.enter) { - if (_formKey.currentState!.validate()) { - submitFormInput(); - } else { - MihAlertServices().formNotFilledCompletely(context); - } - } - }, - child: SafeArea( - child: Center( - child: SingleChildScrollView( - physics: const BouncingScrollPhysics(), - 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.center, - children: [ - //logo - Icon( - Icons.lock, - size: 100, - color: MihColors.getSecondaryColor( - MzansiInnovationHub.of(context)!.theme.mode == - "Dark"), - ), - //spacer - const SizedBox(height: 10), - //Heading - Text( - 'Create an Account', - style: TextStyle( - fontSize: 25, - fontWeight: FontWeight.bold, - color: MihColors.getSecondaryColor( - MzansiInnovationHub.of(context)!.theme.mode == - "Dark"), - ), - ), - //spacer - // const SizedBox(height: 20), - MihForm( - formKey: _formKey, - formFields: [ - //email input - 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: "Email", - autofillHints: const [AutofillHints.email], - validator: (value) { - return MihValidationServices().validateEmail(value); - }, - ), - //spacer - const SizedBox(height: 10), - //password input - MihTextFormField( - fillColor: MihColors.getSecondaryColor( - MzansiInnovationHub.of(context)!.theme.mode == - "Dark"), - inputColor: MihColors.getPrimaryColor( - MzansiInnovationHub.of(context)!.theme.mode == - "Dark"), - controller: passwordController, - multiLineInput: false, - requiredText: true, - hintText: "Password", - passwordMode: true, - autofillHints: const [AutofillHints.password], - validator: (value) { - return MihValidationServices() - .validatePassword(value); - }, - ), - //spacer - const SizedBox(height: 10), - MihTextFormField( - fillColor: MihColors.getSecondaryColor( - MzansiInnovationHub.of(context)!.theme.mode == - "Dark"), - inputColor: MihColors.getPrimaryColor( - MzansiInnovationHub.of(context)!.theme.mode == - "Dark"), - controller: confirmPasswordController, - multiLineInput: false, - requiredText: true, - hintText: "Confirm Password", - passwordMode: true, - autofillHints: const [AutofillHints.password], - validator: (value) { - return MihValidationServices() - .validatePassword(value); - }, - ), - //spacer - const SizedBox(height: 20), - // sign up button - Center( - child: Wrap( - alignment: WrapAlignment.center, - runAlignment: WrapAlignment.center, - spacing: 10, - runSpacing: 10, - children: [ - MihButton( - onPressed: () { - if (_formKey.currentState!.validate()) { - submitFormInput(); - } else { - MihAlertServices() - .formNotFilledCompletely(context); - } - }, - buttonColor: MihColors.getGreenColor( - MzansiInnovationHub.of(context)! - .theme - .mode == - "Dark"), - width: 300, - child: Text( - "Create New Account", - style: TextStyle( - color: MihColors.getPrimaryColor( - MzansiInnovationHub.of(context)! - .theme - .mode == - "Dark"), - fontSize: 20, - fontWeight: FontWeight.bold, - ), - ), - ), - MihButton( - onPressed: widget.onTap, - buttonColor: MihColors.getSecondaryColor( - MzansiInnovationHub.of(context)! - .theme - .mode == - "Dark"), - width: 300, - child: Text( - "I have an account", - style: TextStyle( - color: MihColors.getPrimaryColor( - MzansiInnovationHub.of(context)! - .theme - .mode == - "Dark"), - fontSize: 20, - fontWeight: FontWeight.bold, - ), - ), - ), - ], - ), - ), - - //here - ], - ) - ], - ), - ), - ), - )), - ), - ], - ); - } - - @override - void dispose() { - emailController.dispose(); - passwordController.dispose(); - officeID.dispose(); - _focusNode.dispose(); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - double screenWidth = MediaQuery.of(context).size.width; - return MIHLayoutBuilder( - actionButton: getActionButton(), - header: getHeader(), - secondaryActionButton: getSecondaryActionButton(), - body: getBody(screenWidth), - actionDrawer: null, - secondaryActionDrawer: null, - bottomNavBar: null, - pullDownToRefresh: false, - onPullDown: () async {}, - ); - } -} diff --git a/Frontend/lib/mih_packages/authentication/reset_password.dart b/Frontend/lib/mih_packages/authentication/reset_password.dart deleted file mode 100644 index 272445d8..00000000 --- a/Frontend/lib/mih_packages/authentication/reset_password.dart +++ /dev/null @@ -1,353 +0,0 @@ -import 'dart:convert'; - -import 'package:flutter/material.dart'; -import 'package:flutter/services.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'; -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_text_form_field.dart'; -import '../../main.dart'; -import 'package:supertokens_flutter/http.dart' as http; -import '../../mih_components/mih_layout/mih_action.dart'; -import '../../mih_components/mih_layout/mih_body.dart'; -import '../../mih_components/mih_layout/mih_header.dart'; -import '../../mih_components/mih_layout/mih_layout_builder.dart'; -import '../../mih_components/mih_pop_up_messages/mih_error_message.dart'; -import '../../mih_components/mih_pop_up_messages/mih_loading_circle.dart'; -import '../../mih_components/mih_pop_up_messages/mih_success_message.dart'; -import '../../mih_config/mih_env.dart'; - -class ResetPassword extends StatefulWidget { - final String? token; - const ResetPassword({ - super.key, - required this.token, - }); - - @override - State createState() => _ResetPasswordState(); -} - -class _ResetPasswordState extends State { - final passwordController = TextEditingController(); - final confirmPasswordController = TextEditingController(); - - //bool _obscureText = true; - bool successfulResetPassword = false; - bool acceptWarning = false; - // focus node to capture keyboard events - final FocusNode _focusNode = FocusNode(); - final _formKey = GlobalKey(); - - final baseAPI = AppEnviroment.baseApiUrl; - - Future submitPasswodReset() async { - showDialog( - context: context, - builder: (context) { - return const Mihloadingcircle(); - }, - ); - - try { - var callBody = - '{"method": "token","formFields": [{"id": "password","value": "${passwordController.text}"}],"token": "${widget.token}"}'; - //print(callBody); - var response = await http.post( - Uri.parse("$baseAPI/auth/user/password/reset"), - body: callBody, - headers: { - 'Content-type': 'application/json; charset=utf-8', - // 'Accept': 'application/json', - //"Authorization": "leatucczyixqwkqqdrhayiwzeofkltds" - }, - ); - //print(response.body[]) - if (response.statusCode == 200) { - //print(response.body); - var userPassReset = jsonDecode(response.body); - if (userPassReset["status"] == "OK") { - //print("here"); - setState(() { - successfulResetPassword = true; - }); - Navigator.of(context).pop(); - Navigator.of(context).pushNamed('/'); - } else if (userPassReset["status"] == "FIELD_ERROR") { - Navigator.of(context).pop(); - passwordReqError(); - } else { - Navigator.of(context).pop(); - loginError(); - } - } - } on Exception { - Navigator.of(context).pop(); - //loginError(); - } - } - - void passwordReqError() { - showDialog( - context: context, - builder: (context) { - return const MIHErrorMessage(errorType: "Password Requirements"); - }, - ); - } - - Color getPrim() { - return MihColors.getSecondaryColor( - MzansiInnovationHub.of(context)!.theme.mode == "Dark"); - } - - Color getSec() { - return MihColors.getPrimaryColor( - MzansiInnovationHub.of(context)!.theme.mode == "Dark"); - } - - void loginError() { - showDialog( - context: context, - builder: (context) { - return const MIHErrorMessage(errorType: "Invalid Credentials"); - }, - ); - } - - void resetSuccessfully() { - showDialog( - context: context, - builder: (context) { - return const MIHSuccessMessage( - successType: "Success", - successMessage: - "Great news! Your password reset is complete. You can now log in to Mzansi Innovation Hub using your new password."); - }, - ); - } - - void passwordError() { - showDialog( - context: context, - builder: (context) { - return const MIHErrorMessage(errorType: "Password Match"); - }, - ); - } - - void submitFormInput() async { - if (passwordController.text != confirmPasswordController.text) { - passwordError(); - } else { - await submitPasswodReset(); - if (successfulResetPassword) { - resetSuccessfully(); - } - } - } - - MIHAction getActionButton() { - return MIHAction( - icon: Padding( - padding: const EdgeInsets.all(10.0), - child: SizedBox( - height: 50, - child: Image.asset( - 'lib/mih_components/mih_package_components/assets/images/logo_light.png'), - ), - ), - iconSize: 35, - onTap: () { - // Navigator.of(context).pushNamed( - // '/about', - // //arguments: widget.signedInUser, - // ); - }, - ); - } - - MIHHeader getHeader() { - return const MIHHeader( - headerAlignment: MainAxisAlignment.center, - headerItems: [ - Text( - "", - style: TextStyle( - fontWeight: FontWeight.bold, - fontSize: 25, - ), - ), - ], - ); - } - - MIHBody getBody(double width) { - return MIHBody( - borderOn: false, - bodyItems: [ - KeyboardListener( - focusNode: _focusNode, - autofocus: true, - onKeyEvent: (event) async { - if (event is KeyDownEvent && - event.logicalKey == LogicalKeyboardKey.enter) { - if (_formKey.currentState!.validate()) { - submitFormInput(); - } else { - MihAlertServices().formNotFilledCompletely(context); - } - } - }, - child: SafeArea( - child: Center( - child: SingleChildScrollView( - physics: const BouncingScrollPhysics(), - 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.center, - children: [ - //logo - Icon( - Icons.lock, - size: 100, - color: MihColors.getSecondaryColor( - MzansiInnovationHub.of(context)!.theme.mode == - "Dark"), - ), - //spacer - const SizedBox(height: 10), - //Heading - Text( - 'Reset Password', - style: TextStyle( - fontSize: 25, - fontWeight: FontWeight.bold, - color: MihColors.getSecondaryColor( - MzansiInnovationHub.of(context)!.theme.mode == - "Dark"), - ), - ), - //spacer - const SizedBox(height: 25), - MihForm( - formKey: _formKey, - formFields: [ - MihTextFormField( - fillColor: MihColors.getSecondaryColor( - MzansiInnovationHub.of(context)!.theme.mode == - "Dark"), - inputColor: MihColors.getPrimaryColor( - MzansiInnovationHub.of(context)!.theme.mode == - "Dark"), - controller: passwordController, - multiLineInput: false, - requiredText: true, - hintText: "Password", - passwordMode: true, - autofillHints: const [AutofillHints.password], - validator: (value) { - return MihValidationServices() - .validatePassword(value); - }, - ), - //spacer - const SizedBox(height: 10), - MihTextFormField( - fillColor: MihColors.getSecondaryColor( - MzansiInnovationHub.of(context)!.theme.mode == - "Dark"), - inputColor: MihColors.getPrimaryColor( - MzansiInnovationHub.of(context)!.theme.mode == - "Dark"), - controller: confirmPasswordController, - multiLineInput: false, - requiredText: true, - hintText: "Confirm Password", - passwordMode: true, - autofillHints: const [AutofillHints.password], - validator: (value) { - return MihValidationServices() - .validatePassword(value); - }, - ), - - //spacer - const SizedBox(height: 25), - // sign in button - Center( - child: MihButton( - onPressed: () { - if (_formKey.currentState!.validate()) { - submitFormInput(); - } else { - MihAlertServices() - .formNotFilledCompletely(context); - } - }, - buttonColor: MihColors.getGreenColor( - MzansiInnovationHub.of(context)!.theme.mode == - "Dark"), - width: 300, - child: Text( - "Reset Password", - style: TextStyle( - color: MihColors.getPrimaryColor( - MzansiInnovationHub.of(context)! - .theme - .mode == - "Dark"), - fontSize: 20, - fontWeight: FontWeight.bold, - ), - ), - ), - ), - ], - ), - ], - ), - ), - ), - ), - ), - ), - ], - ); - } - - @override - void dispose() { - passwordController.dispose(); - confirmPasswordController.dispose(); - _focusNode.dispose(); - super.dispose(); - } - - @override - void initState() { - super.initState(); - } - - @override - Widget build(BuildContext context) { - double screenWidth = MediaQuery.of(context).size.width; - return MIHLayoutBuilder( - actionButton: getActionButton(), - header: getHeader(), - secondaryActionButton: null, - body: getBody(screenWidth), - actionDrawer: null, - secondaryActionDrawer: null, - bottomNavBar: null, - pullDownToRefresh: false, - onPullDown: () async {}, - ); - } -} diff --git a/Frontend/lib/mih_packages/authentication/signin.dart b/Frontend/lib/mih_packages/authentication/signin.dart deleted file mode 100644 index 1e86ba77..00000000 --- a/Frontend/lib/mih_packages/authentication/signin.dart +++ /dev/null @@ -1,701 +0,0 @@ -import 'dart:convert'; -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_install_services.dart'; -import 'package:mzansi_innovation_hub/mih_services/mih_validation_services.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_icons.dart'; -import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_text_form_field.dart'; -import 'package:mzansi_innovation_hub/mih_components/mih_objects/arguments.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; -import '../../main.dart'; -import 'package:supertokens_flutter/http.dart' as http; -import '../../mih_components/mih_layout/mih_action.dart'; -import '../../mih_components/mih_layout/mih_body.dart'; -import '../../mih_components/mih_layout/mih_header.dart'; -import '../../mih_components/mih_layout/mih_layout_builder.dart'; -import '../../mih_components/mih_layout/mih_tile.dart'; -import '../../mih_components/mih_pop_up_messages/mih_error_message.dart'; -import '../../mih_components/mih_pop_up_messages/mih_loading_circle.dart'; -import '../../mih_config/mih_env.dart'; - -class SignIn extends StatefulWidget { - final Function() onTap; - const SignIn({super.key, required this.onTap}); - - @override - State createState() => _SignInState(); -} - -class _SignInState extends State { - final emailController = TextEditingController(); - final passwordController = TextEditingController(); - //bool _obscureText = true; - bool successfulSignIn = false; - bool showProfiles = false; - - // focus node to capture keyboard events - final FocusNode _focusNode = FocusNode(); - final _formKey = GlobalKey(); - - final baseAPI = AppEnviroment.baseApiUrl; - - late List sandboxProfileList = []; - - //sign user in - Future signUserIn() async { - //var _backgroundColor = Colors.transparent; - showDialog( - context: context, - builder: (context) { - return const Mihloadingcircle(); - }, - ); - try { - var response = await http.post( - Uri.parse("$baseAPI/auth/signin"), - body: - '{"formFields": [{"id": "email","value": "${emailController.text}"}, {"id": "password","value": "${passwordController.text}"}]}', - headers: { - 'Content-type': 'application/json', - 'Accept': 'application/json', - "Authorization": "leatucczyixqwkqqdrhayiwzeofkltds" - }, - ); - //print(response.body[]) - if (response.statusCode == 200) { - //print(response.body); - var userSignedin = jsonDecode(response.body); - if (userSignedin["status"] == "OK") { - //print("here"); - setState(() { - successfulSignIn = true; - }); - Navigator.of(context).pop(); - } else { - Navigator.of(context).pop(); - loginError(); - passwordController.clear(); - } - } - } on Exception { - Navigator.of(context).pop(); - loginError(); - passwordController.clear(); - } - } - - Color getPrim() { - return MihColors.getSecondaryColor( - MzansiInnovationHub.of(context)!.theme.mode == "Dark"); - } - - Color getSec() { - return MihColors.getPrimaryColor( - MzansiInnovationHub.of(context)!.theme.mode == "Dark"); - } - - void setSandboxProfiles(List tileList) { - tileList.add(MIHTile( - onTap: () { - setState(() { - emailController.text = "testpatient@mzansi-innovation-hub.co.za"; - passwordController.text = "Testprofile@1234"; - }); - if (_formKey.currentState!.validate()) { - submitSignInForm(); - } else { - MihAlertServices().formNotFilledCompletely(context); - } - }, - tileName: "Patient", - tileIcon: Icon( - Icons.perm_identity_rounded, - color: getSec(), - size: 200, - ), - p: getPrim(), - s: getSec(), - )); - tileList.add(MIHTile( - onTap: () { - setState(() { - emailController.text = "testdoctor@mzansi-innovation-hub.co.za"; - passwordController.text = "Testprofile@1234"; - }); - if (_formKey.currentState!.validate()) { - submitSignInForm(); - } else { - MihAlertServices().formNotFilledCompletely(context); - } - }, - tileName: "Doctor", - tileIcon: Icon( - Icons.medical_services, - color: getSec(), - size: 200, - ), - p: getPrim(), - s: getSec(), - )); - //if (AppEnviroment.getEnv() == "Dev") { - tileList.add(MIHTile( - onTap: () { - setState(() { - emailController.text = "test-business@mzansi-innovation-hub.co.za"; - passwordController.text = "Testprofile@1234"; - }); - if (_formKey.currentState!.validate()) { - submitSignInForm(); - } else { - MihAlertServices().formNotFilledCompletely(context); - } - }, - tileName: "Business", - tileIcon: Icon( - Icons.business, - color: getSec(), - size: 200, - ), - p: getPrim(), - s: getSec(), - )); - tileList.add(MIHTile( - onTap: () { - setState(() { - emailController.text = "test@mzansi-innovation-hub.co.za"; - passwordController.text = "Testprofile@1234"; - }); - if (_formKey.currentState!.validate()) { - submitSignInForm(); - } else { - MihAlertServices().formNotFilledCompletely(context); - } - }, - tileName: "Test", - tileIcon: Icon( - Icons.warning_amber_rounded, - color: getSec(), - size: 200, - ), - p: getPrim(), - s: getSec(), - )); - //} - } - - void loginError() { - showDialog( - context: context, - builder: (context) { - return const MIHErrorMessage(errorType: "Invalid Credentials"); - }, - ); - } - - void submitSignInForm() async { - await signUserIn(); - if (successfulSignIn) { - Navigator.of(context).pushNamedAndRemoveUntil( - '/', - (route) => false, - arguments: AuthArguments( - true, - true, - ), - ); - } - } - - void showSandboxProfiles() { - showDialog( - context: context, - builder: (context) { - return Dialog( - //backgroundColor: MihColors.getPrimaryColor(MzansiInnovationHub.of(context)!.theme.mode == "Dark"), - child: Stack( - children: [ - Container( - padding: const EdgeInsets.all(10.0), - width: 500.0, - height: 500, - decoration: BoxDecoration( - color: MihColors.getPrimaryColor( - MzansiInnovationHub.of(context)!.theme.mode == "Dark"), - borderRadius: BorderRadius.circular(25.0), - border: Border.all( - color: MihColors.getSecondaryColor( - MzansiInnovationHub.of(context)!.theme.mode == - "Dark"), - width: 5.0), - ), - child: Column( - //mainAxisSize: MainAxisSize.max, - children: [ - Text( - "Sandbox Profiles", - textAlign: TextAlign.center, - style: TextStyle( - color: MihColors.getSecondaryColor( - MzansiInnovationHub.of(context)!.theme.mode == - "Dark"), - fontSize: 25.0, - fontWeight: FontWeight.bold, - ), - ), - const SizedBox(height: 10), - Text( - "NB: These accounts are used for test purposes. Please do not store personal information on these profiles.", - textAlign: TextAlign.center, - style: TextStyle( - color: MihColors.getSecondaryColor( - MzansiInnovationHub.of(context)!.theme.mode == - "Dark"), - fontSize: 15.0, - fontWeight: FontWeight.bold, - ), - ), - const SizedBox(height: 15), - Expanded( - child: GridView.builder( - // physics: , - // shrinkWrap: true, - itemCount: sandboxProfileList.length, - gridDelegate: - const SliverGridDelegateWithMaxCrossAxisExtent( - mainAxisSpacing: 10, maxCrossAxisExtent: 100), - itemBuilder: (context, index) { - return sandboxProfileList[index]; - }, - ), - ), - ], - ), - ), - Positioned( - top: 5, - right: 5, - width: 50, - height: 50, - child: IconButton( - onPressed: () { - Navigator.pop(context); - }, - icon: Icon( - Icons.close, - color: MihColors.getRedColor( - MzansiInnovationHub.of(context)!.theme.mode == "Dark"), - size: 35, - ), - ), - ), - ], - ), - ); - }, - ); - } - - Widget getSecondaryActionButton() { - return Visibility( - visible: MzansiInnovationHub.of(context)!.theme.getPlatform() == "Web", - child: MIHAction( - icon: Padding( - padding: const EdgeInsets.all(10.0), - child: MihButton( - onPressed: () { - MihInstallServices().installMihTrigger(context); - }, - buttonColor: MihColors.getGreenColor( - MzansiInnovationHub.of(context)!.theme.mode == "Dark"), - width: 150, - child: Text( - "Install MIH", - style: TextStyle( - color: MihColors.getPrimaryColor( - MzansiInnovationHub.of(context)!.theme.mode == "Dark"), - fontSize: 20, - fontWeight: FontWeight.bold, - ), - ), - ), - ), - iconSize: 35, - onTap: () { - Navigator.of(context).pushNamed( - '/about', - arguments: 0, - ); - }, - ), - ); - } - - MIHAction getActionButton() { - return MIHAction( - icon: Padding( - padding: const EdgeInsets.all(10.0), - child: SizedBox( - height: 50, - child: FittedBox( - child: Icon( - MihIcons.mihLogo, - color: MihColors.getSecondaryColor( - MzansiInnovationHub.of(context)!.theme.mode == "Dark"), - ), - ), - ), - ), - iconSize: 35, - onTap: () { - Navigator.of(context).pushNamed( - '/about', - arguments: 0, - ); - }, - ); - } - - MIHHeader getHeader() { - return const MIHHeader( - headerAlignment: MainAxisAlignment.center, - headerItems: [ - Text( - "", - style: TextStyle( - fontWeight: FontWeight.bold, - fontSize: 25, - ), - ), - ], - ); - } - - MIHBody getBody(double width) { - return MIHBody( - borderOn: false, - bodyItems: [ - KeyboardListener( - focusNode: _focusNode, - autofocus: true, - onKeyEvent: (event) async { - if (event is KeyDownEvent && - event.logicalKey == LogicalKeyboardKey.enter) { - if (_formKey.currentState!.validate()) { - submitSignInForm(); - } else { - MihAlertServices().formNotFilledCompletely(context); - } - } - }, - child: SafeArea( - child: Center( - child: SingleChildScrollView( - physics: const BouncingScrollPhysics(), - child: Padding( - padding: MzansiInnovationHub.of(context)!.theme.screenType == - "desktop" - ? EdgeInsets.symmetric(horizontal: width * 0.2) - : EdgeInsets.symmetric(horizontal: width * 0.075), - child: AutofillGroup( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - //logo - Icon( - Icons.lock, - size: 100, - color: MihColors.getSecondaryColor( - MzansiInnovationHub.of(context)!.theme.mode == - "Dark"), - ), - //spacer - const SizedBox(height: 10), - //Heading - Text( - 'Sign In', - style: TextStyle( - fontSize: 25, - fontWeight: FontWeight.bold, - color: MihColors.getSecondaryColor( - MzansiInnovationHub.of(context)!.theme.mode == - "Dark"), - ), - ), - //spacer - const SizedBox(height: 10), - MihForm( - formKey: _formKey, - formFields: [ - 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: "Email", - autofillHints: const [AutofillHints.email], - validator: (value) { - return MihValidationServices() - .validateEmail(value); - }, - ), - //spacer - const SizedBox(height: 10), - //password input - MihTextFormField( - fillColor: MihColors.getSecondaryColor( - MzansiInnovationHub.of(context)!.theme.mode == - "Dark"), - inputColor: MihColors.getPrimaryColor( - MzansiInnovationHub.of(context)!.theme.mode == - "Dark"), - controller: passwordController, - multiLineInput: false, - requiredText: true, - hintText: "Password", - passwordMode: true, - autofillHints: const [AutofillHints.password], - validator: (value) { - return MihValidationServices() - .validatePassword(value); - }, - ), - const SizedBox(height: 10), - SizedBox( - // width: 500.0, - //height: 100.0, - child: Row( - mainAxisAlignment: MainAxisAlignment.end, - children: [ - GestureDetector( - onTap: () { - Navigator.of(context).pushNamed( - '/forgot-password', - ); - }, - child: Text( - 'Forgot Password?', - style: TextStyle( - fontSize: 15, - color: MihColors.getSecondaryColor( - MzansiInnovationHub.of(context)! - .theme - .mode == - "Dark"), - fontWeight: FontWeight.bold, - ), - ), - ), - ], - ), - ), - - //spacer - const SizedBox(height: 20), - // sign in button - Center( - child: Wrap( - alignment: WrapAlignment.center, - runAlignment: WrapAlignment.center, - spacing: 10, - runSpacing: 10, - children: [ - MihButton( - onPressed: () { - if (_formKey.currentState!.validate()) { - submitSignInForm(); - } else { - MihAlertServices() - .formNotFilledCompletely(context); - } - }, - buttonColor: MihColors.getGreenColor( - MzansiInnovationHub.of(context)! - .theme - .mode == - "Dark"), - width: 300, - child: Text( - "Sign In", - style: TextStyle( - color: MihColors.getPrimaryColor( - MzansiInnovationHub.of(context)! - .theme - .mode == - "Dark"), - fontSize: 20, - fontWeight: FontWeight.bold, - ), - ), - ), - MihButton( - onPressed: widget.onTap, - buttonColor: MihColors.getSecondaryColor( - MzansiInnovationHub.of(context)! - .theme - .mode == - "Dark"), - width: 300, - child: Text( - "Create New Account", - style: TextStyle( - color: MihColors.getPrimaryColor( - MzansiInnovationHub.of(context)! - .theme - .mode == - "Dark"), - fontSize: 20, - fontWeight: FontWeight.bold, - ), - ), - ), - ], - ), - ), - - //spacer - const SizedBox(height: 35), - Center( - child: SizedBox( - width: width, - //height: 100.0, - child: Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - const Flexible( - flex: 1, - child: Padding( - padding: EdgeInsets.only(right: 10.0), - child: Divider(), - ), - ), - Flexible( - flex: 1, - child: GestureDetector( - child: Text( - 'Use Sandox Profile', - textAlign: TextAlign.center, - style: TextStyle( - fontWeight: FontWeight.bold, - fontSize: 15, - color: - MihColors.getSecondaryColor( - MzansiInnovationHub.of( - context)! - .theme - .mode == - "Dark")), - ), - onTap: () { - setState(() { - showProfiles = !showProfiles; - }); - }, - ), - ), - const Flexible( - flex: 1, - child: Padding( - padding: EdgeInsets.only(left: 10.0), - child: Divider(), - ), - ), - ], - ), - ), - ), - const SizedBox(height: 10), - Center( - child: Visibility( - visible: showProfiles, - child: SizedBox( - width: 500, - child: Column( - //mainAxisSize: MainAxisSize.max, - children: [ - GridView.builder( - physics: - const NeverScrollableScrollPhysics(), - shrinkWrap: true, - itemCount: sandboxProfileList.length, - gridDelegate: - const SliverGridDelegateWithMaxCrossAxisExtent( - mainAxisSpacing: 10, - maxCrossAxisExtent: 100), - itemBuilder: (context, index) { - return sandboxProfileList[index]; - }, - ), - const SizedBox(height: 20), - Text( - "NB: These accounts are used for test purposes. Please do not store personal information on these profiles.", - textAlign: TextAlign.center, - style: TextStyle( - color: MihColors.getSecondaryColor( - MzansiInnovationHub.of(context)! - .theme - .mode == - "Dark"), - fontSize: 15.0, - fontWeight: FontWeight.bold, - ), - ), - ], - ), - ), - ), - ), - ], - ), - ], - ), - ), - ), - ), - ), - ), - ), - ], - ); - } - - @override - void dispose() { - emailController.dispose(); - passwordController.dispose(); - _focusNode.dispose(); - TextInput.finishAutofillContext(); - super.dispose(); - } - - @override - void initState() { - setState(() { - setSandboxProfiles(sandboxProfileList); - }); - super.initState(); - } - - @override - Widget build(BuildContext context) { - double screenWidth = MediaQuery.of(context).size.width; - return MIHLayoutBuilder( - actionButton: getActionButton(), - header: getHeader(), - secondaryActionButton: getSecondaryActionButton(), - body: getBody(screenWidth), - actionDrawer: null, - secondaryActionDrawer: null, - bottomNavBar: null, - pullDownToRefresh: false, - onPullDown: () async {}, - ); - } -} diff --git a/Frontend/lib/mih_packages/authentication/signin_or_register.dart b/Frontend/lib/mih_packages/authentication/signin_or_register.dart deleted file mode 100644 index 17c83b2f..00000000 --- a/Frontend/lib/mih_packages/authentication/signin_or_register.dart +++ /dev/null @@ -1,35 +0,0 @@ -import 'package:flutter/material.dart'; - -import 'register.dart'; -import 'signin.dart'; - -class SignInOrRegister extends StatefulWidget { - const SignInOrRegister({super.key}); - - @override - State createState() => _SignInOrRegisterState(); -} - -class _SignInOrRegisterState extends State { - bool showSignInPage = true; - - void togglePages() { - setState(() { - showSignInPage = !showSignInPage; - }); - } - - @override - void dispose() { - super.dispose(); - } - - @override - Widget build(BuildContext context) { - if (showSignInPage) { - return SignIn(onTap: togglePages); - } else { - return Register(onTap: togglePages); - } - } -} diff --git a/Frontend/lib/mih_packages/calculator/mih_calculator.dart b/Frontend/lib/mih_packages/calculator/mih_calculator.dart index 60ecbb87..cf52264f 100644 --- a/Frontend/lib/mih_packages/calculator/mih_calculator.dart +++ b/Frontend/lib/mih_packages/calculator/mih_calculator.dart @@ -1,3 +1,4 @@ +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'; @@ -42,7 +43,10 @@ class _MIHCalculatorState extends State { icon: const Icon(Icons.arrow_back), iconSize: 35, onTap: () { - Navigator.of(context).pop(); + context.goNamed( + 'mihHome', + extra: widget.personalSelected, + ); FocusScope.of(context).unfocus(); }, ); 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 0e2ce86a..58c42944 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 @@ -1,3 +1,4 @@ +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_tile.dart'; import 'package:flutter/material.dart'; @@ -23,10 +24,14 @@ class _MihCalculatorTileState extends State { Widget build(BuildContext context) { return MihPackageTile( onTap: () { - Navigator.of(context).pushNamed( - '/calculator', - arguments: widget.personalSelected, + context.goNamed( + "mihCalculator", + extra: widget.personalSelected, ); + // Navigator.of(context).pushNamed( + // '/calculator', + // arguments: widget.personalSelected, + // ); }, appName: "Calculator", appIcon: Icon( diff --git a/Frontend/lib/mih_packages/calendar/builder/build_appointment_list.dart b/Frontend/lib/mih_packages/calendar/builder/build_appointment_list.dart index b6a206b2..b195fb75 100644 --- a/Frontend/lib/mih_packages/calendar/builder/build_appointment_list.dart +++ b/Frontend/lib/mih_packages/calendar/builder/build_appointment_list.dart @@ -1,5 +1,9 @@ import 'package:flutter_speed_dial/flutter_speed_dial.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_objects/arguments.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_alert.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_mzansi_calendar_services.dart'; @@ -198,7 +202,7 @@ class _BuildAppointmentListState extends State { ), ], onWindowTapClose: () { - Navigator.of(context).pop(); + context.pop(); widget.dateController.clear(); widget.timeController.clear(); widget.titleController.clear(); @@ -320,7 +324,7 @@ class _BuildAppointmentListState extends State { ), ], onWindowTapClose: () { - Navigator.of(context).pop(); + context.pop(); widget.dateController.clear(); widget.timeController.clear(); widget.titleController.clear(); @@ -421,7 +425,7 @@ class _BuildAppointmentListState extends State { .split('T')[1] .substring(0, 5); }); - Navigator.of(context).pop(); + context.pop(); }, windowBody: Padding( padding: @@ -552,10 +556,11 @@ class _BuildAppointmentListState extends State { ); } - void updateAppointmentCall(int index) { + Future updateAppointmentCall(int index) async { + int statusCode; if (isAppointmentInputValid()) { if (widget.personalSelected == true) { - MihMzansiCalendarApis.updatePersonalAppointment( + statusCode = await MihMzansiCalendarApis.updatePersonalAppointment( widget.signedInUser, widget.business, null, @@ -568,7 +573,7 @@ class _BuildAppointmentListState extends State { ); } else if (widget.personalSelected == false && widget.inWaitingRoom == false) { - MihMzansiCalendarApis.updateBusinessAppointment( + statusCode = await MihMzansiCalendarApis.updateBusinessAppointment( widget.signedInUser, widget.business, widget.businessUser, @@ -580,7 +585,7 @@ class _BuildAppointmentListState extends State { context, ); } else { - MihMzansiCalendarApis.updatePatientAppointment( + statusCode = await MihMzansiCalendarApis.updatePatientAppointment( widget.signedInUser, widget.business, widget.businessUser, @@ -592,6 +597,41 @@ class _BuildAppointmentListState extends State { context, ); } + if (statusCode == 200) { + context.pop(); + context.pop(); + if (!widget.inWaitingRoom) { + KenLogger.warning("calendar route"); + context.goNamed( + "mihCalendar", + extra: CalendarArguments( + widget.signedInUser, + widget.personalSelected, + widget.business, + widget.businessUser, + ), + ); + } else { + KenLogger.warning("waiting room route"); + // GoRouter.of(context).refresh(); + context.goNamed( + 'mihHome', + extra: false, + ); + context.goNamed( + 'patientManager', + extra: PatManagerArguments( + widget.signedInUser, + false, + widget.business, + widget.businessUser, + ), + ); + // context.pop(); + } + } else { + internetConnectionPopUp(); + } } else { showDialog( context: context, @@ -602,9 +642,8 @@ class _BuildAppointmentListState extends State { } } - void deleteAppointmentCall(int index) { - print("personal selected: ${widget.personalSelected}"); - MihMzansiCalendarApis.deleteAppointmentAPICall( + Future deleteAppointmentCall(int index) async { + int statucCode = await MihMzansiCalendarApis.deleteAppointmentAPICall( widget.signedInUser, widget.personalSelected, widget.business, @@ -613,6 +652,82 @@ class _BuildAppointmentListState extends State { widget.appointmentList[index].idappointments, context, ); + if (statucCode == 200) { + context.pop(); + context.pop(); + setState(() { + widget.appointmentList.removeAt(index); + }); + successPopUp("Successfully Deleted Appointment", + "You appointment has been successfully deleted from your calendar."); + } else { + internetConnectionPopUp(); + } + } + + void successPopUp(String title, String message) { + 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: title, + 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"), + ); + }, + ); + } + + void internetConnectionPopUp() { + showDialog( + context: context, + builder: (context) { + return const MIHErrorMessage( + errorType: "Internet Connection", + ); + }, + ); } bool canEditAppointment(int index) { diff --git a/Frontend/lib/mih_packages/calendar/mzansi_calendar.dart b/Frontend/lib/mih_packages/calendar/mzansi_calendar.dart index ed6c30a6..34819e20 100644 --- a/Frontend/lib/mih_packages/calendar/mzansi_calendar.dart +++ b/Frontend/lib/mih_packages/calendar/mzansi_calendar.dart @@ -1,3 +1,4 @@ +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'; @@ -41,7 +42,11 @@ class _MzansiCalendarState extends State { icon: const Icon(Icons.arrow_back), iconSize: 35, onTap: () { - Navigator.of(context).pop(); + // Navigator.of(context).pop(); + context.goNamed( + 'mihHome', + extra: true, + ); FocusScope.of(context).unfocus(); }, ); diff --git a/Frontend/lib/mih_packages/calendar/package_tiles/mzansi_calendar_tile.dart b/Frontend/lib/mih_packages/calendar/package_tiles/mzansi_calendar_tile.dart index 7ec7b80d..7abb6097 100644 --- a/Frontend/lib/mih_packages/calendar/package_tiles/mzansi_calendar_tile.dart +++ b/Frontend/lib/mih_packages/calendar/package_tiles/mzansi_calendar_tile.dart @@ -1,3 +1,4 @@ +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_tile.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_icons.dart'; @@ -24,10 +25,14 @@ class _MzansiCalendarTileState extends State { Widget build(BuildContext context) { return MihPackageTile( onTap: () { - Navigator.of(context).pushNamed( - '/calendar', - arguments: widget.arguments, + context.goNamed( + "mihCalendar", + extra: widget.arguments, ); + // Navigator.of(context).pushNamed( + // '/calendar', + // arguments: widget.arguments, + // ); }, appName: "Calendar", appIcon: Icon( diff --git a/Frontend/lib/mih_packages/calendar/package_tools/appointments.dart b/Frontend/lib/mih_packages/calendar/package_tools/appointments.dart index 31637f54..db9bb941 100644 --- a/Frontend/lib/mih_packages/calendar/package_tools/appointments.dart +++ b/Frontend/lib/mih_packages/calendar/package_tools/appointments.dart @@ -1,5 +1,7 @@ import 'package:flutter_speed_dial/flutter_speed_dial.dart'; +import 'package:go_router/go_router.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_icons.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_alert.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_mzansi_calendar_services.dart'; @@ -143,23 +145,6 @@ class _PatientAccessRequestState extends State { ), ), ); - // return Expanded( - // child: Padding( - // padding: const EdgeInsets.only(top: 35.0), - // child: Align( - // alignment: Alignment.center, - // child: Text( - // "No Appointments for $selectedDay", - // style: TextStyle( - // fontSize: 25, - // color: MihColors.getGreyColor(MzansiInnovationHub.of(context)!.theme.mode == "Dark"), - // ), - // textAlign: TextAlign.center, - // softWrap: true, - // ), - // ), - // ), - // ); } void addAppointmentWindow(double width) { @@ -284,10 +269,11 @@ class _PatientAccessRequestState extends State { } } - void addAppointmentCall() { + Future addAppointmentCall() async { if (isAppointmentInputValid()) { + int statusCode; if (widget.personalSelected == false) { - MihMzansiCalendarApis.addBusinessAppointment( + statusCode = await MihMzansiCalendarApis.addBusinessAppointment( widget.signedInUser, widget.business!, widget.businessUser!, @@ -299,7 +285,7 @@ class _PatientAccessRequestState extends State { context, ); } else { - MihMzansiCalendarApis.addPersonalAppointment( + statusCode = await MihMzansiCalendarApis.addPersonalAppointment( widget.signedInUser, _appointmentTitleController.text, _appointmentDescriptionIDController.text, @@ -308,6 +294,27 @@ class _PatientAccessRequestState extends State { context, ); } + if (statusCode == 201) { + context.pop(); + successPopUp("Successfully Added Appointment", + "You appointment has been successfully added to your calendar."); + setState(() { + if (widget.personalSelected) { + appointmentResults = MihMzansiCalendarApis.getPersonalAppointments( + widget.signedInUser.app_id, + selectedDay, + ); + } else { + appointmentResults = MihMzansiCalendarApis.getBusinessAppointments( + widget.business!.business_id, + false, + selectedDay, + ); + } + }); + } else { + internetConnectionPopUp(); + } } else { showDialog( context: context, @@ -319,6 +326,77 @@ class _PatientAccessRequestState extends State { checkforchange(); } + void successPopUp(String title, String message) { + 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: title, + 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(); + setState(() { + _appointmentDateController.clear(); + _appointmentTimeController.clear(); + _appointmentTitleController.clear(); + _appointmentDescriptionIDController.clear(); + }); + }, + 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"), + ); + }, + ); + } + + void internetConnectionPopUp() { + showDialog( + context: context, + builder: (context) { + return const MIHErrorMessage( + errorType: "Internet Connection", + ); + }, + ); + } + String getTitle() { if (widget.personalSelected == false) { return "Business Appointments"; diff --git a/Frontend/lib/mih_packages/mih_authentication/mih_auth_forgot_password.dart b/Frontend/lib/mih_packages/mih_authentication/mih_auth_forgot_password.dart new file mode 100644 index 00000000..e8854ebb --- /dev/null +++ b/Frontend/lib/mih_packages/mih_authentication/mih_auth_forgot_password.dart @@ -0,0 +1,66 @@ +import 'package:flutter/material.dart'; +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_packages/mih_authentication/package_tools/mih_forgot_password.dart'; + +class MihAuthForgotPassword extends StatefulWidget { + const MihAuthForgotPassword({super.key}); + + @override + State createState() => _MihAuthForgotPasswordState(); +} + +class _MihAuthForgotPasswordState extends State { + int _selcetedIndex = 0; + + @override + Widget build(BuildContext context) { + return MihPackage( + appActionButton: getAction(), + appTools: getTools(), + appBody: getToolBody(), + selectedbodyIndex: _selcetedIndex, + onIndexChange: (newValue) { + setState(() { + _selcetedIndex = newValue; + }); + }, + ); + } + + MihPackageAction getAction() { + return MihPackageAction( + icon: const Icon(Icons.arrow_back), + iconSize: 35, + onTap: () { + context.goNamed( + 'mihHome', + extra: true, + ); + FocusScope.of(context).unfocus(); + }, + ); + } + + MihPackageTools getTools() { + Map temp = {}; + temp[const Icon(Icons.question_mark_rounded)] = () { + setState(() { + _selcetedIndex = 0; + }); + }; + return MihPackageTools( + tools: temp, + selcetedIndex: _selcetedIndex, + ); + } + + List getToolBody() { + List toolBodies = [ + MihForgotPassword(), + ]; + return toolBodies; + } +} diff --git a/Frontend/lib/mih_packages/mih_authentication/mih_auth_password_reset.dart b/Frontend/lib/mih_packages/mih_authentication/mih_auth_password_reset.dart new file mode 100644 index 00000000..76cd7b4a --- /dev/null +++ b/Frontend/lib/mih_packages/mih_authentication/mih_auth_password_reset.dart @@ -0,0 +1,76 @@ +import 'package:flutter/material.dart'; +import 'package:go_router/go_router.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_icons.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_packages/mih_authentication/package_tools/mih_reset_password.dart'; + +class MihAuthPasswordReset extends StatefulWidget { + final String token; + const MihAuthPasswordReset({ + super.key, + required this.token, + }); + + @override + State createState() => _MihAuthPasswordResetState(); +} + +class _MihAuthPasswordResetState extends State { + int _selcetedIndex = 0; + + @override + Widget build(BuildContext context) { + return MihPackage( + appActionButton: getAction(), + appTools: getTools(), + appBody: getToolBody(), + selectedbodyIndex: _selcetedIndex, + onIndexChange: (newValue) { + setState(() { + _selcetedIndex = newValue; + }); + }, + ); + } + + Widget getAction() { + return Padding( + padding: const EdgeInsets.only(left: 5.0), + child: MihPackageAction( + icon: const Icon(MihIcons.mihLogo), + iconSize: 45, + onTap: () { + context.goNamed( + 'mihHome', + extra: true, + ); + FocusScope.of(context).unfocus(); + }, + ), + ); + } + + MihPackageTools getTools() { + Map temp = {}; + temp[const Icon(Icons.password_rounded)] = () { + setState(() { + _selcetedIndex = 0; + }); + }; + return MihPackageTools( + tools: temp, + selcetedIndex: _selcetedIndex, + ); + } + + List getToolBody() { + List toolBodies = [ + MihResetPassword( + token: widget.token, + ), + ]; + return toolBodies; + } +} diff --git a/Frontend/lib/mih_packages/mih_authentication/mih_authentication.dart b/Frontend/lib/mih_packages/mih_authentication/mih_authentication.dart index 1908e703..b255f91d 100644 --- a/Frontend/lib/mih_packages/mih_authentication/mih_authentication.dart +++ b/Frontend/lib/mih_packages/mih_authentication/mih_authentication.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:go_router/go_router.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_icons.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'; @@ -67,19 +68,16 @@ class _MihAuthenticationState extends State { ); } - MihPackageAction getAction() { - return MihPackageAction( - icon: Padding( - padding: const EdgeInsets.only(left: 10.0), - child: const Icon(MihIcons.mihLogo), + Widget getAction() { + return Padding( + padding: const EdgeInsets.only(left: 5.0), + child: MihPackageAction( + icon: const Icon(MihIcons.mihLogo), + iconSize: 45, + onTap: () { + context.goNamed("aboutMih", extra: 0); + }, ), - iconSize: 45, - onTap: () { - Navigator.of(context).pushNamed( - '/about', - arguments: 0, - ); - }, ); } } diff --git a/Frontend/lib/mih_packages/mih_authentication/package_tools/mih_forgot_password.dart b/Frontend/lib/mih_packages/mih_authentication/package_tools/mih_forgot_password.dart new file mode 100644 index 00000000..d6b7c970 --- /dev/null +++ b/Frontend/lib/mih_packages/mih_authentication/package_tools/mih_forgot_password.dart @@ -0,0 +1,295 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/services.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_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_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_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_config/mih_colors.dart'; +import 'package:mzansi_innovation_hub/mih_services/mih_alert_services.dart'; +import 'package:mzansi_innovation_hub/mih_services/mih_authentication_services.dart'; +import 'package:mzansi_innovation_hub/mih_services/mih_validation_services.dart'; + +class MihForgotPassword extends StatefulWidget { + const MihForgotPassword({super.key}); + + @override + State createState() => _MihForgotPasswordState(); +} + +class _MihForgotPasswordState extends State { + final emailController = TextEditingController(); + bool successfulForgotPassword = false; + final _formKey = GlobalKey(); + final FocusNode _focusNode = FocusNode(); + bool acceptWarning = false; + + Future submitPasswodReset() async { + showDialog( + context: context, + builder: (context) { + return const Mihloadingcircle(); + }, + ); + try { + var resetPassEmailSent = await MihAuthenticationServices() + .forgotPassword(emailController.text); + context.pop(); + if (resetPassEmailSent) { + setState(() { + successfulForgotPassword = true; + }); + } + } on Exception { + //loginError(); + } + } + + void prePassResteWarning() { + showDialog( + context: context, + builder: (context) { + return MihPackageAlert( + alertIcon: Icon( + Icons.warning_amber_rounded, + size: 100, + color: MihColors.getSecondaryColor( + MzansiInnovationHub.of(context)!.theme.mode == "Dark"), + ), + alertTitle: "Password Reset Confirmation", + alertBody: Column( + //mainAxisSize: MainAxisSize.max, + children: [ + Padding( + padding: const EdgeInsets.symmetric(horizontal: 25.0), + child: Text( + "Before you reset your password, please be aware that you'll receive an email with a link to confirm your identity and set a new password. Make sure to check your inbox, including spam or junk folders. If you don't receive the email within a few minutes, please try resending the reset request.", + style: TextStyle( + color: MihColors.getSecondaryColor( + MzansiInnovationHub.of(context)!.theme.mode == "Dark"), + fontSize: 15.0, + fontWeight: FontWeight.bold, + ), + ), + ), + const SizedBox(height: 25), + MihButton( + onPressed: () { + setState(() { + acceptWarning = true; + }); + Navigator.of(context).pop(); + validateInput(); + }, + buttonColor: MihColors.getGreenColor( + MzansiInnovationHub.of(context)!.theme.mode == "Dark"), + width: 300, + child: Text( + "Continue", + style: TextStyle( + color: MihColors.getPrimaryColor( + MzansiInnovationHub.of(context)!.theme.mode == "Dark"), + fontSize: 20, + fontWeight: FontWeight.bold, + ), + ), + ), + ], + ), + alertColour: MihColors.getSecondaryColor( + MzansiInnovationHub.of(context)!.theme.mode == "Dark"), + ); + }, + ); + } + + void resetLinkSentSuccessfully() { + 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 Sent Reset Link", + alertBody: Column( + children: [ + Text( + "We've sent a password reset link to your email address. Please check your inbox, including spam or junk folders.\n\nOnce you find the email, click on the link to reset your password.\n\nIf you don't receive the email within a few minutes, please try resending the reset request.\n\nThe reset link will expire after 2 hours", + 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: true, + ); + }, + 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 const MIHSuccessMessage( + // successType: "Success", + // successMessage: + // "We've sent a password reset link to your email address. Please check your inbox, including spam or junk folders.\n\nOnce you find the email, click on the link to reset your password.\n\nIf you don't receive the email within a few minutes, please try resending the reset request.\n\nThe reset link will expire after 2 hours"); + }, + ); + } + + void validateInput() async { + if (emailController.text.isEmpty) { + showDialog( + context: context, + builder: (context) { + return const MIHErrorMessage(errorType: "Input Error"); + }, + ); + } else { + await submitPasswodReset(); + if (successfulForgotPassword) { + // Navigator.of(context).pushNamedAndRemoveUntil('/', (route) => false); + resetLinkSentSuccessfully(); + } + } + } + + @override + Widget build(BuildContext context) { + double screenWidth = MediaQuery.of(context).size.width; + return MihPackageToolBody( + borderOn: false, + bodyItem: getBody(screenWidth), + ); + } + + Widget getBody(double width) { + return KeyboardListener( + focusNode: _focusNode, + autofocus: true, + onKeyEvent: (event) async { + if (event is KeyDownEvent && + event.logicalKey == LogicalKeyboardKey.enter) { + validateInput(); + } + }, + child: SafeArea( + child: SingleChildScrollView( + physics: const BouncingScrollPhysics(), + child: Padding( + padding: MzansiInnovationHub.of(context)!.theme.screenType == + "desktop" + ? EdgeInsets.symmetric(vertical: 25, horizontal: width * 0.2) + : EdgeInsets.symmetric(vertical: 25, horizontal: width * 0.075), + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisSize: MainAxisSize.max, + children: [ + //logo + Icon( + Icons.lock, + size: 100, + color: MihColors.getSecondaryColor( + MzansiInnovationHub.of(context)!.theme.mode == "Dark"), + ), + //spacer + const SizedBox(height: 10), + //Heading + Text( + 'Forgot Password', + style: TextStyle( + fontSize: 25, + fontWeight: FontWeight.bold, + color: MihColors.getSecondaryColor( + MzansiInnovationHub.of(context)!.theme.mode == "Dark"), + ), + ), + const SizedBox(height: 25), + MihForm( + formKey: _formKey, + formFields: [ + 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: "Email", + validator: (value) { + return MihValidationServices().validateEmail(value); + }, + ), + //spacer + const SizedBox(height: 20), + Align( + alignment: Alignment.center, + child: MihButton( + onPressed: () { + if (_formKey.currentState!.validate()) { + prePassResteWarning(); + } else { + MihAlertServices().formNotFilledCompletely(context); + } + }, + buttonColor: MihColors.getGreenColor( + MzansiInnovationHub.of(context)!.theme.mode == + "Dark"), + width: 300, + child: Text( + "Reset Password", + style: TextStyle( + color: MihColors.getPrimaryColor( + MzansiInnovationHub.of(context)!.theme.mode == + "Dark"), + fontSize: 20, + fontWeight: FontWeight.bold, + ), + ), + ), + ), + ], + ), + ], + ), + ), + ), + ), + ); + } +} diff --git a/Frontend/lib/mih_packages/mih_authentication/package_tools/mih_reset_password.dart b/Frontend/lib/mih_packages/mih_authentication/package_tools/mih_reset_password.dart new file mode 100644 index 00000000..307292a8 --- /dev/null +++ b/Frontend/lib/mih_packages/mih_authentication/package_tools/mih_reset_password.dart @@ -0,0 +1,266 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/services.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_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_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_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_config/mih_colors.dart'; +import 'package:mzansi_innovation_hub/mih_services/mih_alert_services.dart'; +import 'package:mzansi_innovation_hub/mih_services/mih_authentication_services.dart'; +import 'package:mzansi_innovation_hub/mih_services/mih_validation_services.dart'; + +class MihResetPassword extends StatefulWidget { + final String token; + const MihResetPassword({ + super.key, + required this.token, + }); + + @override + State createState() => _MihResetPasswordState(); +} + +class _MihResetPasswordState extends State { + final passwordController = TextEditingController(); + final confirmPasswordController = TextEditingController(); + final FocusNode _focusNode = FocusNode(); + final _formKey = GlobalKey(); + + void submitFormInput() async { + if (passwordController.text != confirmPasswordController.text) { + passwordError(); + } else { + showDialog( + context: context, + builder: (context) { + return const Mihloadingcircle(); + }, + ); + bool successfulResetPassword = await MihAuthenticationServices() + .resetPassword(widget.token, passwordController.text); + context.pop(); + if (successfulResetPassword) { + resetSuccessfully(); + } else { + loginError(); + } + } + } + + void resetSuccessfully() { + 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 Reset Password", + alertBody: Column( + children: [ + Text( + "Great news! Your password reset is complete. You can now log in to Mzansi Innovation Hub using your new password.", + 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: true, + ); + }, + 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 const MIHSuccessMessage( + // successType: "Success", + // successMessage: + // "We've sent a password reset link to your email address. Please check your inbox, including spam or junk folders.\n\nOnce you find the email, click on the link to reset your password.\n\nIf you don't receive the email within a few minutes, please try resending the reset request.\n\nThe reset link will expire after 2 hours"); + }, + ); + } + + void loginError() { + showDialog( + context: context, + builder: (context) { + return const MIHErrorMessage(errorType: "Invalid Credentials"); + }, + ); + } + + void passwordError() { + showDialog( + context: context, + builder: (context) { + return const MIHErrorMessage(errorType: "Password Match"); + }, + ); + } + + @override + Widget build(BuildContext context) { + double screenWidth = MediaQuery.of(context).size.width; + return MihPackageToolBody( + borderOn: false, + bodyItem: getBody(screenWidth), + ); + } + + Widget getBody(double width) { + return KeyboardListener( + focusNode: _focusNode, + autofocus: true, + onKeyEvent: (event) async { + if (event is KeyDownEvent && + event.logicalKey == LogicalKeyboardKey.enter) { + if (_formKey.currentState!.validate()) { + submitFormInput(); + } else { + MihAlertServices().formNotFilledCompletely(context); + } + } + }, + child: SafeArea( + child: SingleChildScrollView( + physics: const BouncingScrollPhysics(), + 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: [ + Text("Token: ${widget.token}"), // For testing purposes only + //logo + Icon( + Icons.lock, + size: 100, + color: MihColors.getSecondaryColor( + MzansiInnovationHub.of(context)!.theme.mode == "Dark"), + ), + //spacer + const SizedBox(height: 10), + //Heading + Text( + 'Reset Password', + style: TextStyle( + fontSize: 25, + fontWeight: FontWeight.bold, + color: MihColors.getSecondaryColor( + MzansiInnovationHub.of(context)!.theme.mode == "Dark"), + ), + ), + //spacer + const SizedBox(height: 25), + MihForm( + formKey: _formKey, + formFields: [ + MihTextFormField( + fillColor: MihColors.getSecondaryColor( + MzansiInnovationHub.of(context)!.theme.mode == + "Dark"), + inputColor: MihColors.getPrimaryColor( + MzansiInnovationHub.of(context)!.theme.mode == + "Dark"), + controller: passwordController, + multiLineInput: false, + requiredText: true, + hintText: "Password", + passwordMode: true, + autofillHints: const [AutofillHints.password], + validator: (value) { + return MihValidationServices().validatePassword(value); + }, + ), + //spacer + const SizedBox(height: 10), + MihTextFormField( + fillColor: MihColors.getSecondaryColor( + MzansiInnovationHub.of(context)!.theme.mode == + "Dark"), + inputColor: MihColors.getPrimaryColor( + MzansiInnovationHub.of(context)!.theme.mode == + "Dark"), + controller: confirmPasswordController, + multiLineInput: false, + requiredText: true, + hintText: "Confirm Password", + passwordMode: true, + autofillHints: const [AutofillHints.password], + validator: (value) { + return MihValidationServices().validatePassword(value); + }, + ), + //spacer + const SizedBox(height: 25), + // sign in button + Center( + child: MihButton( + onPressed: () { + if (_formKey.currentState!.validate()) { + submitFormInput(); + } else { + MihAlertServices().formNotFilledCompletely(context); + } + }, + buttonColor: MihColors.getGreenColor( + MzansiInnovationHub.of(context)!.theme.mode == + "Dark"), + width: 300, + child: Text( + "Reset Password", + style: TextStyle( + color: MihColors.getPrimaryColor( + MzansiInnovationHub.of(context)!.theme.mode == + "Dark"), + fontSize: 20, + fontWeight: FontWeight.bold, + ), + ), + ), + ), + ], + ), + ], + ), + ), + ), + ), + ); + } +} diff --git a/Frontend/lib/mih_packages/mih_authentication/package_tools/mih_sign_in.dart b/Frontend/lib/mih_packages/mih_authentication/package_tools/mih_sign_in.dart index e016fc4d..c6bb47f2 100644 --- a/Frontend/lib/mih_packages/mih_authentication/package_tools/mih_sign_in.dart +++ b/Frontend/lib/mih_packages/mih_authentication/package_tools/mih_sign_in.dart @@ -1,8 +1,8 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; +import 'package:go_router/go_router.dart'; import 'package:mzansi_innovation_hub/main.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_layout/mih_tile.dart'; -import 'package:mzansi_innovation_hub/mih_components/mih_objects/arguments.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'; @@ -59,13 +59,9 @@ class _MihSignInState extends State { void submitSignInForm() async { await signUserIn(); if (successfulSignIn) { - Navigator.of(context).pushNamedAndRemoveUntil( - '/', - (route) => false, - arguments: AuthArguments( - true, - true, - ), + context.goNamed( + 'mihHome', + extra: true, ); } } @@ -324,8 +320,11 @@ class _MihSignInState extends State { children: [ GestureDetector( onTap: () { - Navigator.of(context).pushNamed( - '/forgot-password', + // Navigator.of(context).pushNamed( + // '/forgot-password', + // ); + context.goNamed( + 'forgotPassword', ); }, child: Text( 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 e562e1a3..40cb8f85 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 @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:go_router/go_router.dart'; 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/mih_circle_avatar.dart'; @@ -32,23 +33,14 @@ class _MIHAppDrawerState extends State { } Widget displayProPic() { - // return MIHProfilePicture( - // profilePictureFile: widget.propicFile, - // proPicController: proPicController, - // proPic: null, - // width: 45, - // radius: 21, - // editable: false, - // onChange: (newProPic) {}, - // ), - //print(widget.propicFile); return GestureDetector( onTap: () { - Navigator.of(context).pop(); - Navigator.of(context).pushNamed( - '/mzansi-profile', - arguments: - AppProfileUpdateArguments(widget.signedInUser, widget.propicFile), + context.goNamed( + 'mzansiProfileManage', + extra: AppProfileUpdateArguments( + widget.signedInUser, + widget.propicFile, + ), ); }, child: MihCircleAvatar( @@ -208,10 +200,7 @@ class _MIHAppDrawerState extends State { ], ), onTap: () { - Navigator.of(context).pushNamed( - '/about', - arguments: 1, - ); + context.goNamed("aboutMih", extra: 1); }, ), ListTile( @@ -241,10 +230,7 @@ class _MIHAppDrawerState extends State { ], ), onTap: () { - Navigator.of(context).pushNamed( - '/about', - arguments: 2, - ); + context.goNamed("aboutMih", extra: 2); }, ), ListTile( @@ -280,11 +266,15 @@ class _MIHAppDrawerState extends State { }); if (await SuperTokens.doesSessionExist() == false) { - Navigator.of(context).pop(); - Navigator.of(context).popAndPushNamed( - '/', - arguments: AuthArguments(true, false), + context.goNamed( + 'mihHome', + extra: true, ); + // Navigator.of(context).pop(); + // Navigator.of(context).popAndPushNamed( + // '/', + // arguments: AuthArguments(true, false), + // ); } }, ), diff --git a/Frontend/lib/mih_packages/mih_home/mih_home.dart b/Frontend/lib/mih_packages/mih_home/mih_home.dart index a0b2ce0a..e56dee37 100644 --- a/Frontend/lib/mih_packages/mih_home/mih_home.dart +++ b/Frontend/lib/mih_packages/mih_home/mih_home.dart @@ -1,44 +1,45 @@ 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_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_package_components/mih_circle_avatar.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_user.dart'; -import 'package:mzansi_innovation_hub/mih_components/mih_objects/notification.dart'; -import 'package:mzansi_innovation_hub/mih_components/mih_objects/patients.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_loading_circle.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'; // ignore: must_be_immutable class MihHome extends StatefulWidget { - final AppUser signedInUser; - final BusinessUser? businessUser; - final Business? business; - final Patient? patient; - final List notifications; - final ImageProvider? propicFile; - final bool isUserNew; - final bool isBusinessUser; - final bool isBusinessUserNew; - final bool isDevActive; - bool personalSelected; - MihHome({ + // final AppUser signedInUser; + // final BusinessUser? businessUser; + // final Business? business; + // final Patient? patient; + // final List notifications; + // final ImageProvider? propicFile; + // final bool isUserNew; + // final bool isBusinessUser; + // final bool isBusinessUserNew; + // final bool isDevActive; + final bool personalSelected; + const MihHome({ super.key, - required this.signedInUser, - required this.businessUser, - required this.business, - required this.patient, - required this.notifications, - required this.propicFile, - required this.isUserNew, - required this.isBusinessUser, - required this.isBusinessUserNew, - required this.isDevActive, + // required this.signedInUser, + // required this.businessUser, + // required this.business, + // required this.patient, + // required this.notifications, + // required this.propicFile, + // required this.isUserNew, + // required this.isBusinessUser, + // required this.isBusinessUserNew, + // required this.isDevActive, required this.personalSelected, }); @@ -50,6 +51,7 @@ class _MihHomeState extends State { final proPicController = TextEditingController(); late int _selcetedIndex; late bool _personalSelected; + late Future profileData; @override void dispose() { @@ -59,7 +61,7 @@ class _MihHomeState extends State { @override void initState() { super.initState(); - + profileData = MIHApiCalls().getProfile(10, context); if (widget.personalSelected == true) { setState(() { _selcetedIndex = 0; @@ -83,36 +85,60 @@ class _MihHomeState extends State { @override Widget build(BuildContext context) { - return MihPackage( - appActionButton: getAction(), - appTools: getTools(), - appBody: getToolBody(), - appToolTitles: getToolTitle(), - actionDrawer: getActionDrawer(), - selectedbodyIndex: _selcetedIndex, - onIndexChange: (newValue) { - if (_selcetedIndex == 0) { - setState(() { - _selcetedIndex = newValue; - _personalSelected = true; - }); + return FutureBuilder( + future: profileData, + builder: (context, asyncSnapshot) { + if (asyncSnapshot.connectionState == ConnectionState.waiting) { + return Scaffold( + body: const Mihloadingcircle( + message: "Fetching your Data...", + ), + ); + } else if (asyncSnapshot.connectionState == ConnectionState.done && + asyncSnapshot.hasData) { + return 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; + }); + } + }, + ); } else { - setState(() { - _selcetedIndex = newValue; - _personalSelected = false; - }); + return MihHomeError( + errorMessage: asyncSnapshot.hasError + ? asyncSnapshot.error.toString() + : "An unknown error occurred", + ); } }, ); } - Widget getAction() { + Widget getAction(String proPicUrl) { return Builder(builder: (context) { return MihPackageAction( icon: Padding( padding: const EdgeInsets.only(left: 5.0), child: MihCircleAvatar( - imageFile: widget.propicFile, + imageFile: proPicUrl != "" ? NetworkImage(proPicUrl) : null, width: 50, editable: false, fileNameController: proPicController, @@ -147,14 +173,14 @@ class _MihHomeState extends State { }); } - MIHAppDrawer getActionDrawer() { + MIHAppDrawer getActionDrawer(AppUser signedInUser, String proPicUrl) { return MIHAppDrawer( - signedInUser: widget.signedInUser, - propicFile: widget.propicFile, + signedInUser: signedInUser, + propicFile: proPicUrl != "" ? NetworkImage(proPicUrl) : null, ); } - MihPackageTools getTools() { + MihPackageTools getTools(bool isBusinessUser) { Map temp = {}; temp[const Icon(Icons.person)] = () { setState(() { @@ -162,7 +188,7 @@ class _MihHomeState extends State { _personalSelected = true; }); }; - if (widget.isBusinessUser) { + if (isBusinessUser) { temp[const Icon(Icons.business_center)] = () { setState(() { _selcetedIndex = 1; @@ -176,27 +202,29 @@ class _MihHomeState extends State { ); } - List getToolBody() { + List getToolBody(HomeArguments profData) { List toolBodies = []; toolBodies.add( MihPersonalHome( - signedInUser: widget.signedInUser, + signedInUser: profData.signedInUser, personalSelected: _personalSelected, - business: widget.business, - businessUser: widget.businessUser, - propicFile: widget.propicFile, - isUserNew: widget.isUserNew, - isDevActive: widget.isDevActive, + business: profData.business, + businessUser: profData.businessUser, + propicFile: profData.profilePicUrl != "" + ? NetworkImage(profData.profilePicUrl) + : null, + isDevActive: AppEnviroment.getEnv() == "Dev", + isUserNew: profData.signedInUser.username == "", ), ); - if (widget.isBusinessUser) { + if (profData.signedInUser.type != "personal") { toolBodies.add( MihBusinessHome( - signedInUser: widget.signedInUser, + signedInUser: profData.signedInUser, personalSelected: _personalSelected, - businessUser: widget.businessUser, - business: widget.business, - isBusinessUserNew: widget.isBusinessUserNew, + businessUser: profData.businessUser, + business: profData.business, + isBusinessUserNew: profData.businessUser == null, ), ); } diff --git a/Frontend/lib/mih_packages/mih_home/mih_home_error.dart b/Frontend/lib/mih_packages/mih_home/mih_home_error.dart new file mode 100644 index 00000000..e1a293a7 --- /dev/null +++ b/Frontend/lib/mih_packages/mih_home/mih_home_error.dart @@ -0,0 +1,150 @@ +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_button.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_tool_body.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_tools.dart'; +import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart'; + +class MihHomeError extends StatefulWidget { + final String errorMessage; + const MihHomeError({ + super.key, + required this.errorMessage, + }); + + @override + State createState() => _MihHomeErrorState(); +} + +class _MihHomeErrorState extends State { + int _selcetedIndex = 0; + + @override + Widget build(BuildContext context) { + return MihPackage( + appActionButton: getErrorAction(), + appTools: getErrorTools(), + appBody: getErrorToolBody(widget.errorMessage), + selectedbodyIndex: _selcetedIndex, + onIndexChange: (newValue) { + setState(() { + _selcetedIndex = newValue; + }); + //print("Index: $_selcetedIndex"); + }, + ); + } + + MihPackageAction getErrorAction() { + return MihPackageAction( + icon: const Icon(Icons.refresh), + iconSize: 35, + onTap: () { + context.goNamed( + 'mihHome', + extra: true, + ); + }, + ); + } + + MihPackageTools getErrorTools() { + Map temp = {}; + temp[const Icon(Icons.power_off_outlined)] = () { + setState(() { + _selcetedIndex = 0; + }); + }; + return MihPackageTools( + tools: temp, + selcetedIndex: _selcetedIndex, + ); + } + + List getErrorToolBody(String error) { + List toolBodies = [ + MihPackageToolBody( + borderOn: true, + bodyItem: Column( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Text( + "Connection Error", + textAlign: TextAlign.center, + style: TextStyle( + color: MihColors.getSecondaryColor( + MzansiInnovationHub.of(context)!.theme.mode == "Dark"), + fontSize: 35, + fontWeight: FontWeight.bold, + ), + ), + Icon( + Icons.power_off_outlined, + size: 150, + color: MihColors.getSecondaryColor( + MzansiInnovationHub.of(context)!.theme.mode == "Dark"), + ), + SizedBox( + width: 500, + child: Text( + "Looks like we ran into an issue getting your data.\nPlease check you internet connection and try again.", + textAlign: TextAlign.center, + style: TextStyle( + color: MihColors.getSecondaryColor( + MzansiInnovationHub.of(context)!.theme.mode == "Dark"), + fontSize: 20, + fontWeight: FontWeight.bold, + ), + ), + ), + const SizedBox(height: 15), + MihButton( + onPressed: () { + context.goNamed( + 'mihHome', + extra: true, + ); + }, + buttonColor: MihColors.getGreenColor( + MzansiInnovationHub.of(context)!.theme.mode == "Dark"), + width: 300, + child: Text( + "Refresh", + style: TextStyle( + color: MihColors.getPrimaryColor( + MzansiInnovationHub.of(context)!.theme.mode == "Dark"), + fontSize: 20, + fontWeight: FontWeight.bold, + ), + ), + ), + const SizedBox(height: 15), + Padding( + padding: const EdgeInsets.all(10.0), + child: SizedBox( + width: 500, + child: SelectionArea( + child: Text( + "Error: $error", + textAlign: TextAlign.left, + style: TextStyle( + color: MihColors.getRedColor( + MzansiInnovationHub.of(context)!.theme.mode == + "Dark"), + fontSize: 15, + fontWeight: FontWeight.bold, + ), + ), + ), + ), + ), + ], + ), + ) + ]; + return toolBodies; + } +} diff --git a/Frontend/lib/mih_packages/mih_home/mih_profile_getter.dart b/Frontend/lib/mih_packages/mih_home/mih_profile_getter.dart index eedb5a2d..e07ee97f 100644 --- a/Frontend/lib/mih_packages/mih_home/mih_profile_getter.dart +++ b/Frontend/lib/mih_packages/mih_home/mih_profile_getter.dart @@ -75,7 +75,6 @@ class _MIHProfileGetterState extends State { _selcetedIndex = 0; }); }; - return MihPackageTools( tools: temp, selcetedIndex: _selcetedIndex, @@ -244,18 +243,18 @@ class _MIHProfileGetterState extends State { if (snapshot.connectionState == ConnectionState.done) { if (snapshot.hasData) { return MihHome( - signedInUser: snapshot.requireData.signedInUser, - businessUser: snapshot.data!.businessUser, - business: snapshot.data!.business, - patient: snapshot.data!.patient, - notifications: snapshot.data!.notifi, - propicFile: snapshot.data!.profilePicUrl != "" - ? NetworkImage(snapshot.data!.profilePicUrl) - : null, - isUserNew: isUserNew(snapshot.requireData.signedInUser), - isBusinessUser: isBusinessUser(snapshot.requireData.signedInUser), - isBusinessUserNew: isBusinessUserNew(snapshot.data!.businessUser), - isDevActive: isDevActive(), + // signedInUser: snapshot.requireData.signedInUser, + // businessUser: snapshot.data!.businessUser, + // business: snapshot.data!.business, + // patient: snapshot.data!.patient, + // notifications: snapshot.data!.notifi, + // propicFile: snapshot.data!.profilePicUrl != "" + // ? NetworkImage(snapshot.data!.profilePicUrl) + // : null, + // isUserNew: isUserNew(snapshot.requireData.signedInUser), + // isBusinessUser: isBusinessUser(snapshot.requireData.signedInUser), + // isBusinessUserNew: isBusinessUserNew(snapshot.data!.businessUser), + // isDevActive: isDevActive(), personalSelected: widget.personalSelected, ); // return MIHHomeLegacy( diff --git a/Frontend/lib/mih_packages/mih_home/package_tools/mih_business_home.dart b/Frontend/lib/mih_packages/mih_home/package_tools/mih_business_home.dart index 738ad4b1..34a1864a 100644 --- a/Frontend/lib/mih_packages/mih_home/package_tools/mih_business_home.dart +++ b/Frontend/lib/mih_packages/mih_home/package_tools/mih_business_home.dart @@ -1,3 +1,4 @@ +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_single_child_scroll.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_icons.dart'; @@ -244,15 +245,24 @@ class _MihBusinessHomeState extends State hintColor: MihColors.getPrimaryColor( MzansiInnovationHub.of(context)!.theme.mode == "Dark"), onPrefixIconTap: () { - Navigator.of(context).pushNamed( - '/mzansi-ai', - arguments: MzansiAiArguments( + context.goNamed( + "mzansiAi", + extra: MzansiAiArguments( widget.signedInUser, searchController.text.isEmpty ? null : searchController.text, ), ); + // Navigator.of(context).pushNamed( + // '/mzansi-ai', + // arguments: MzansiAiArguments( + // widget.signedInUser, + // searchController.text.isEmpty + // ? null + // : searchController.text, + // ), + // ); searchController.clear(); }, searchFocusNode: _searchFocusNode, 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 def04d9f..7e07e9dc 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 @@ -1,8 +1,9 @@ +import 'package:go_router/go_router.dart'; import 'package:mzansi_innovation_hub/main.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_package_components/Example/package_tiles/test_package_tile.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_icons.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_tile.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_search_bar.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_objects/app_user.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_objects/arguments.dart'; @@ -159,27 +160,10 @@ class _MihPersonalHomeState extends State //=============== Dev =============== if (widget.isDevActive) { temp.add({ - "test": MihPackageTile( - onTap: () { - Navigator.of(context).pushNamed( - '/package-dev', - arguments: TestArguments( - widget.signedInUser, - widget.business, - ), - ); - }, - appName: "Test", - appIcon: Icon( - Icons.warning_amber_rounded, - color: MihColors.getSecondaryColor( - MzansiInnovationHub.of(context)!.theme.mode == "Dark"), - ), - iconSize: packageSize, - primaryColor: MihColors.getSecondaryColor( - MzansiInnovationHub.of(context)!.theme.mode == "Dark"), - secondaryColor: MihColors.getPrimaryColor( - MzansiInnovationHub.of(context)!.theme.mode == "Dark"), + "test": TestPackageTile( + signedInUser: widget.signedInUser, + business: widget.business, + packageSize: packageSize, ) }); } @@ -219,9 +203,9 @@ class _MihPersonalHomeState extends State void autoNavToProfile() { WidgetsBinding.instance.addPostFrameCallback((_) { - Navigator.of(context).pushNamed( - '/mzansi-profile', - arguments: AppProfileUpdateArguments( + context.goNamed( + 'mzansiProfileManage', + extra: AppProfileUpdateArguments( widget.signedInUser, widget.propicFile, ), @@ -299,15 +283,24 @@ class _MihPersonalHomeState extends State hintColor: MihColors.getPrimaryColor( MzansiInnovationHub.of(context)!.theme.mode == "Dark"), onPrefixIconTap: () { - Navigator.of(context).pushNamed( - '/mzansi-ai', - arguments: MzansiAiArguments( + context.goNamed( + "mzansiAi", + extra: MzansiAiArguments( widget.signedInUser, searchController.text.isEmpty ? null : searchController.text, ), ); + // Navigator.of(context).pushNamed( + // '/mzansi-ai', + // arguments: MzansiAiArguments( + // widget.signedInUser, + // searchController.text.isEmpty + // ? null + // : searchController.text, + // ), + // ); searchController.clear(); }, searchFocusNode: _searchFocusNode, diff --git a/Frontend/lib/mih_packages/mzansi_ai/mzansi_ai.dart b/Frontend/lib/mih_packages/mzansi_ai/mzansi_ai.dart index 4d7c2ca9..0cc11ad6 100644 --- a/Frontend/lib/mih_packages/mzansi_ai/mzansi_ai.dart +++ b/Frontend/lib/mih_packages/mzansi_ai/mzansi_ai.dart @@ -1,3 +1,4 @@ +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'; @@ -28,7 +29,10 @@ class _MzansiAiState extends State { icon: const Icon(Icons.arrow_back), iconSize: 35, onTap: () { - Navigator.of(context).pop(); + context.goNamed( + 'mihHome', + extra: true, + ); FocusScope.of(context).unfocus(); }, ); diff --git a/Frontend/lib/mih_packages/mzansi_ai/package_tiles/mzansi_ai_tile.dart b/Frontend/lib/mih_packages/mzansi_ai/package_tiles/mzansi_ai_tile.dart index af830803..5361524e 100644 --- a/Frontend/lib/mih_packages/mzansi_ai/package_tiles/mzansi_ai_tile.dart +++ b/Frontend/lib/mih_packages/mzansi_ai/package_tiles/mzansi_ai_tile.dart @@ -1,3 +1,4 @@ +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_tile.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_icons.dart'; @@ -25,13 +26,20 @@ class _MzansiAiTileState extends State { Widget build(BuildContext context) { return MihPackageTile( onTap: () { - Navigator.of(context).pushNamed( - '/mzansi-ai', - arguments: MzansiAiArguments( + context.goNamed( + 'mzansiAi', + extra: MzansiAiArguments( widget.signedInUser, "", ), ); + // Navigator.of(context).pushNamed( + // '/mzansi-ai', + // arguments: MzansiAiArguments( + // widget.signedInUser, + // "", + // ), + // ); }, appName: "Mzansi AI", appIcon: Icon( diff --git a/Frontend/lib/mih_packages/mzansi_ai/package_tools/ai_chat.dart b/Frontend/lib/mih_packages/mzansi_ai/package_tools/ai_chat.dart index 6f136666..43d69089 100644 --- a/Frontend/lib/mih_packages/mzansi_ai/package_tools/ai_chat.dart +++ b/Frontend/lib/mih_packages/mzansi_ai/package_tools/ai_chat.dart @@ -1,6 +1,7 @@ import 'dart:async'; import 'dart:convert'; import 'package:flutter_speed_dial/flutter_speed_dial.dart'; +import 'package:gpt_markdown/gpt_markdown.dart'; import 'package:mzansi_innovation_hub/main.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_icons.dart'; import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart'; @@ -222,7 +223,7 @@ class _AiChatState extends State { child: Column( mainAxisSize: MainAxisSize.max, children: [ - Text( + GptMarkdown( snapshot.requireData, textAlign: TextAlign.left, style: TextStyle( @@ -569,7 +570,6 @@ class _AiChatState extends State { @override void dispose() { - // TODO: implement dispose super.dispose(); _modelController.dispose(); _fontSizeController.dispose(); @@ -630,7 +630,6 @@ class _AiChatState extends State { content: systemPromt, ), ); - _loadMessages(); initTTS(); _ttsVoiceController.addListener(voiceSelected); if (widget.startUpQuestion != null && widget.startUpQuestion!.isNotEmpty) { diff --git a/Frontend/lib/mih_packages/mzansi_directory/builders/build_business_search_resultsList.dart b/Frontend/lib/mih_packages/mzansi_directory/builders/build_business_search_resultsList.dart index f52381ce..9740c534 100644 --- a/Frontend/lib/mih_packages/mzansi_directory/builders/build_business_search_resultsList.dart +++ b/Frontend/lib/mih_packages/mzansi_directory/builders/build_business_search_resultsList.dart @@ -1,4 +1,5 @@ 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_objects/arguments.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_objects/business.dart'; @@ -41,13 +42,20 @@ class _BuildBusinessSearchResultsListState MzansiInnovationHub.of(context)!.theme.mode == "Dark"), child: InkWell( onTap: () { - Navigator.of(context).pushNamed( - '/business-profile/view', - arguments: BusinessViewArguments( + context.goNamed( + 'businessProfileView', + extra: BusinessViewArguments( widget.businessList[index], widget.businessList[index].Name, ), ); + // // Navigator.of(context).pushNamed( + // // '/business-profile/view', + // // arguments: BusinessViewArguments( + // // widget.businessList[index], + // // widget.businessList[index].Name, + // // ), + // ); }, splashColor: MihColors.getSecondaryColor( MzansiInnovationHub.of(context)!.theme.mode == "Dark") diff --git a/Frontend/lib/mih_packages/mzansi_directory/builders/build_favourite_businesses_list.dart b/Frontend/lib/mih_packages/mzansi_directory/builders/build_favourite_businesses_list.dart index 9b754421..1c2509fa 100644 --- a/Frontend/lib/mih_packages/mzansi_directory/builders/build_favourite_businesses_list.dart +++ b/Frontend/lib/mih_packages/mzansi_directory/builders/build_favourite_businesses_list.dart @@ -1,4 +1,5 @@ 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_objects/arguments.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_objects/business.dart'; @@ -44,13 +45,20 @@ class _BuildFavouriteBusinessesListState MzansiInnovationHub.of(context)!.theme.mode == "Dark"), child: InkWell( onTap: () { - Navigator.of(context).pushNamed( - '/business-profile/view', - arguments: BusinessViewArguments( - business, - business.Name, + context.goNamed( + 'businessProfileView', + extra: BusinessViewArguments( + widget.favouriteBusinesses[index]!, + widget.favouriteBusinesses[index]!.Name, ), ); + // Navigator.of(context).pushNamed( + // '/business-profile/view', + // arguments: BusinessViewArguments( + // business, + // business.Name, + // ), + // ); }, splashColor: MihColors.getSecondaryColor( MzansiInnovationHub.of(context)!.theme.mode == "Dark") diff --git a/Frontend/lib/mih_packages/mzansi_directory/builders/build_user_search_results_list.dart b/Frontend/lib/mih_packages/mzansi_directory/builders/build_user_search_results_list.dart index 9e0f940d..8135ce94 100644 --- a/Frontend/lib/mih_packages/mzansi_directory/builders/build_user_search_results_list.dart +++ b/Frontend/lib/mih_packages/mzansi_directory/builders/build_user_search_results_list.dart @@ -1,4 +1,5 @@ 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_objects/app_user.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_personal_profile_preview.dart'; @@ -36,10 +37,14 @@ class _BuildUserSearchResultsListState MzansiInnovationHub.of(context)!.theme.mode == "Dark"), child: InkWell( onTap: () { - Navigator.of(context).pushNamed( - '/mzansi-profile/view', - arguments: widget.userList[index], + context.goNamed( + 'mzansiProfileView', + extra: widget.userList[index], ); + // Navigator.of(context).pushNamed( + // '/mzansi-profile/view', + // arguments: widget.userList[index], + // ); }, splashColor: MihColors.getSecondaryColor( MzansiInnovationHub.of(context)!.theme.mode == "Dark") diff --git a/Frontend/lib/mih_packages/mzansi_directory/mzansi_directory.dart b/Frontend/lib/mih_packages/mzansi_directory/mzansi_directory.dart index 8b48989b..5719cbe5 100644 --- a/Frontend/lib/mih_packages/mzansi_directory/mzansi_directory.dart +++ b/Frontend/lib/mih_packages/mzansi_directory/mzansi_directory.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; import 'package:geolocator/geolocator.dart'; +import 'package:go_router/go_router.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_objects/arguments.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'; @@ -97,7 +98,10 @@ class _MzansiDirectoryState extends State { icon: const Icon(Icons.arrow_back), iconSize: 35, onTap: () { - Navigator.of(context).pop(); + context.goNamed( + 'mihHome', + extra: true, + ); FocusScope.of(context).unfocus(); }, ); diff --git a/Frontend/lib/mih_packages/mzansi_directory/package_tiles/mzansi_directory_tile.dart b/Frontend/lib/mih_packages/mzansi_directory/package_tiles/mzansi_directory_tile.dart index 1f534131..9185b8d2 100644 --- a/Frontend/lib/mih_packages/mzansi_directory/package_tiles/mzansi_directory_tile.dart +++ b/Frontend/lib/mih_packages/mzansi_directory/package_tiles/mzansi_directory_tile.dart @@ -1,4 +1,5 @@ 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_objects/arguments.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_icons.dart'; @@ -21,13 +22,20 @@ class _MzansiDirectoryTileState extends State { Widget build(BuildContext context) { return MihPackageTile( onTap: () { - Navigator.of(context).pushNamed( - '/mzansi-directory', - arguments: MzansiDirectoryArguments( + context.goNamed( + "mzansiDirectory", + extra: MzansiDirectoryArguments( personalSearch: true, startSearchText: null, ), ); + // Navigator.of(context).pushNamed( + // '/mzansi-directory', + // arguments: MzansiDirectoryArguments( + // personalSearch: true, + // startSearchText: null, + // ), + // ); }, appName: "Mzansi Directory", appIcon: Icon( 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 faabea5b..edc2b570 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 @@ -1,7 +1,9 @@ import 'dart:convert'; 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_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'; @@ -13,7 +15,6 @@ import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_ import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_delete_message.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'; 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'; @@ -64,20 +65,20 @@ class _BuildEmployeeListState extends State { }), ); if (response.statusCode == 200) { - Navigator.of(context).pop(); - Navigator.of(context).pop(); - Navigator.of(context).pop(); - //setState(() {}); - Navigator.of(context).pushNamed( - '/business-profile/manage', - arguments: BusinessArguments( - widget.arguments.signedInUser, - widget.arguments.businessUser, - widget.arguments.business, - ), - ); + // Navigator.of(context).pop(); + // Navigator.of(context).pop(); + // Navigator.of(context).pop(); + // //setState(() {}); + // Navigator.of(context).pushNamed( + // '/business-profile/manage', + // arguments: BusinessArguments( + // widget.arguments.signedInUser, + // widget.arguments.businessUser, + // widget.arguments.business, + // ), + // ); String message = "Your employees details have been updated."; - successPopUp(message); + successPopUp(message, false); } else { internetConnectionPopUp(); } @@ -97,25 +98,86 @@ class _BuildEmployeeListState extends State { //print("Here4"); //print(response.statusCode); if (response.statusCode == 200) { - Navigator.of(context).pop(); - Navigator.of(context).pop(); - Navigator.of(context).pop(); - Navigator.of(context).pushNamed( - '/business-profile/manage', - arguments: BusinessArguments( - widget.arguments.signedInUser, - widget.arguments.businessUser, - widget.arguments.business, - ), - ); + // Navigator.of(context).pop(); + // Navigator.of(context).pop(); + // Navigator.of(context).pop(); + // Navigator.of(context).pushNamed( + // '/business-profile/manage', + // arguments: BusinessArguments( + // widget.arguments.signedInUser, + // widget.arguments.businessUser, + // widget.arguments.business, + // ), + // ); String message = "The employee has been deleted successfully. This means they will no longer have access to your business profile"; - successPopUp(message); + successPopUp(message, false); } else { internetConnectionPopUp(); } } + 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.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, + // ); + }, + ); + } + void internetConnectionPopUp() { showDialog( context: context, @@ -125,18 +187,6 @@ class _BuildEmployeeListState extends State { ); } - void successPopUp(String message) { - showDialog( - context: context, - builder: (context) { - return MIHSuccessMessage( - successType: "Success", - successMessage: message, - ); - }, - ); - } - bool isRequiredFieldsCaptured() { if (accessController.text.isEmpty || typeController.text.isEmpty) { return false; @@ -216,18 +266,29 @@ class _BuildEmployeeListState extends State { readOnly: true, hintText: "Surname", ), - const SizedBox(height: 15.0), - MihDropdownField( + 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: typeController, - hintText: "Title", - dropdownOptions: const ["Doctor", "Assistant", "Other"], - editable: true, - enableSearch: true, - validator: (value) { - return MihValidationServices().isEmpty(value); - }, + multiLineInput: false, requiredText: true, + readOnly: true, + hintText: "Title", ), + // MihDropdownField( + // controller: typeController, + // hintText: "Title", + // dropdownOptions: const ["Doctor", "Assistant", "Other"], + // editable: true, + // enableSearch: true, + // validator: (value) { + // return MihValidationServices().isEmpty(value); + // }, + // requiredText: true, + // ), const SizedBox(height: 10.0), MihDropdownField( controller: accessController, diff --git a/Frontend/lib/mih_packages/mzansi_profile/business_profile/builders/build_user_list.dart b/Frontend/lib/mih_packages/mzansi_profile/business_profile/builders/build_user_list.dart index 80f27543..c1c6e870 100644 --- a/Frontend/lib/mih_packages/mzansi_profile/business_profile/builders/build_user_list.dart +++ b/Frontend/lib/mih_packages/mzansi_profile/business_profile/builders/build_user_list.dart @@ -1,6 +1,8 @@ import 'dart:convert'; +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_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'; @@ -11,7 +13,6 @@ 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_components/mih_pop_up_messages/mih_loading_circle.dart'; -import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_success_message.dart'; import 'package:mzansi_innovation_hub/mih_config/mih_env.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_objects/app_user.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_objects/arguments.dart'; @@ -58,32 +59,93 @@ class _BuildUserListState extends State { "app_id": widget.users[index].app_id, "signature": "", "sig_path": "", - "title": typeController.text, + "title": "", "access": accessController.text, }), ); if (response.statusCode == 201) { - Navigator.of(context).pop(); - Navigator.of(context).pop(); - Navigator.of(context).pop(); - Navigator.of(context).pushNamed( - '/business-profile/manage', - arguments: BusinessArguments( - widget.arguments.signedInUser, - widget.arguments.businessUser, - widget.arguments.business, - ), - ); + // Navigator.of(context).pop(); + // Navigator.of(context).pop(); + // Navigator.of(context).pop(); + // Navigator.of(context).pushNamed( + // '/business-profile/manage', + // arguments: BusinessArguments( + // widget.arguments.signedInUser, + // widget.arguments.businessUser, + // widget.arguments.business, + // ), + // ); String message = "${widget.users[index].username} is now apart of your team with ${accessController.text} access to ${widget.arguments.business!.Name}"; - successPopUp(message); + successPopUp(message, false); } else { internetConnectionPopUp(); } } + 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.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, + // ); + }, + ); + } + bool isRequiredFieldsCaptured() { - if (accessController.text.isEmpty || typeController.text.isEmpty) { + if (accessController.text.isEmpty) { return false; } else { return true; @@ -99,18 +161,6 @@ class _BuildUserListState extends State { ); } - void successPopUp(String message) { - showDialog( - context: context, - builder: (context) { - return MIHSuccessMessage( - successType: "Success", - successMessage: message, - ); - }, - ); - } - String hideEmail(String email) { var firstLetter = email[0]; var end = email.split("@")[1]; @@ -169,19 +219,32 @@ class _BuildUserListState extends State { readOnly: true, hintText: "Email", ), - const SizedBox(height: 15.0), - MihDropdownField( - controller: typeController, - hintText: "Title", - dropdownOptions: const ["Doctor", "Assistant", "Other"], - editable: true, - enableSearch: true, - validator: (value) { - return MihValidationServices().isEmpty(value); - }, - requiredText: true, - ), 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: typeController, + // multiLineInput: false, + // requiredText: true, + // readOnly: true, + // hintText: "Title", + // ), + // MihDropdownField( + // controller: typeController, + // hintText: "Title", + // dropdownOptions: const ["Doctor", "Assistant", "Other"], + // editable: true, + // enableSearch: true, + // validator: (value) { + // return MihValidationServices().isEmpty(value); + // }, + // requiredText: true, + // ), + // const SizedBox(height: 10.0), MihDropdownField( controller: accessController, hintText: "Access Type", diff --git a/Frontend/lib/mih_packages/mzansi_profile/business_profile/components/mih_add_bookmark_alert.dart b/Frontend/lib/mih_packages/mzansi_profile/business_profile/components/mih_add_bookmark_alert.dart index 4c55e1d8..6e70de6b 100644 --- a/Frontend/lib/mih_packages/mzansi_profile/business_profile/components/mih_add_bookmark_alert.dart +++ b/Frontend/lib/mih_packages/mzansi_profile/business_profile/components/mih_add_bookmark_alert.dart @@ -1,4 +1,5 @@ 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_objects/arguments.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_objects/business.dart'; @@ -33,23 +34,13 @@ class _MihAddBookmarkAlertState extends State { await MihMzansiDirectoryServices() .addBookmarkedBusiness(user_id, business_id) .then((statusCode) { + context.pop(); if (statusCode == 201) { - Navigator.of(context).pushNamedAndRemoveUntil( - '/mzansi-directory', - ModalRoute.withName('/'), - arguments: MzansiDirectoryArguments( - personalSearch: false, // personalSearch - packageIndex: 1, - startSearchText: widget.business.Name, - ), - ); - MihAlertServices().successAlert( + successPopUp( "Successfully Bookmarked Business!", "${widget.business.Name} has successfully been added to favourite businessess in the Mzansi Directory.", - context, ); } else { - Navigator.of(context).pop(); MihAlertServices().errorAlert( "Error Adding Bookmark", "An error occured while add ${widget.business.Name} to you Mzansi Directory, Please try again later.", @@ -59,6 +50,71 @@ class _MihAddBookmarkAlertState extends State { }); } + void successPopUp(String title, String message) { + 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: title, + 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( + "mzansiDirectory", + extra: MzansiDirectoryArguments( + personalSearch: false, + startSearchText: widget.business.Name, + packageIndex: 1, + ), + ); + }, + 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, + // ); + }, + ); + } + @override Widget build(BuildContext context) { return MihPackageAlert( diff --git a/Frontend/lib/mih_packages/mzansi_profile/business_profile/components/mih_business_info_card.dart b/Frontend/lib/mih_packages/mzansi_profile/business_profile/components/mih_business_info_card.dart index 1b75e44d..124bb903 100644 --- a/Frontend/lib/mih_packages/mzansi_profile/business_profile/components/mih_business_info_card.dart +++ b/Frontend/lib/mih_packages/mzansi_profile/business_profile/components/mih_business_info_card.dart @@ -1,8 +1,11 @@ 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_objects/bookmarked_business.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_objects/business.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_objects/business_review.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_icons.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_alert.dart'; import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart'; import 'package:mzansi_innovation_hub/mih_packages/mzansi_profile/business_profile/components/mih_add_bookmark_alert.dart'; @@ -31,6 +34,14 @@ class MihBusinessCard extends StatefulWidget { class _MihBusinessCardState extends State { Future? _businessReviewFuture; Future? _bookmarkedBusinessFuture; + bool _isUserSignedIn = false; + + Future _checkUserSession() async { + final doesSessionExist = await SuperTokens.doesSessionExist(); + setState(() { + _isUserSignedIn = doesSessionExist; + }); + } RedactedConfiguration getRedactedConfiguration() { return RedactedConfiguration( @@ -390,6 +401,7 @@ class _MihBusinessCardState extends State { @override void initState() { super.initState(); + _checkUserSession(); _businessReviewFuture = getUserReview(); _bookmarkedBusinessFuture = getUserBookmark(); } @@ -665,33 +677,103 @@ class _MihBusinessCardState extends State { Future businessReviewRatingWindow( BusinessReview? myReview, bool previouslyRated, double width) async { - showDialog( - context: context, - builder: (context) => MihReviewBusinessWindow( - business: widget.business, - businessReview: myReview, - screenWidth: width, - readOnly: false, - ), - ); + if (_isUserSignedIn) { + showDialog( + context: context, + builder: (context) => MihReviewBusinessWindow( + business: widget.business, + businessReview: myReview, + screenWidth: width, + readOnly: false, + ), + ); + } else { + showSignInRequiredAlert(); + } } void showAddBookmarkAlert() { - showDialog( - context: context, - builder: (context) => MihAddBookmarkAlert( - business: widget.business, - ), - ); + if (_isUserSignedIn) { + showDialog( + context: context, + builder: (context) => MihAddBookmarkAlert( + business: widget.business, + ), + ); + } else { + showSignInRequiredAlert(); + } } void showDeleteBookmarkAlert(BookmarkedBusiness? bookmarkBusiness) { + if (_isUserSignedIn) { + showDialog( + context: context, + builder: (context) => MihDeleteBookmarkAlert( + business: widget.business, + bookmarkBusiness: bookmarkBusiness, + startUpSearch: widget.startUpSearch, + )); + } else { + showSignInRequiredAlert(); + } + } + + void showSignInRequiredAlert() { showDialog( - context: context, - builder: (context) => MihDeleteBookmarkAlert( - business: widget.business, - bookmarkBusiness: bookmarkBusiness, - startUpSearch: widget.startUpSearch, - )); + context: context, + builder: (context) => MihPackageAlert( + alertIcon: Column( + children: [ + Icon( + MihIcons.mihLogo, + size: 125, + color: MihColors.getSecondaryColor( + MzansiInnovationHub.of(context)!.theme.mode == "Dark"), + ), + const SizedBox(height: 10), + ], + ), + alertTitle: "Let's Get Started", + alertBody: Column( + children: [ + Text( + "Ready to dive in to the world of MIH?\nSign in or create a free MIH account to unlock all the powerful features of the MIH app. It's quick and easy!", + style: TextStyle( + color: MihColors.getSecondaryColor( + MzansiInnovationHub.of(context)!.theme.mode == "Dark"), + fontSize: 15, + ), + ), + const SizedBox(height: 25), + Center( + child: MihButton( + onPressed: () { + context.goNamed( + 'mihHome', + extra: true, + ); + }, + buttonColor: MihColors.getGreenColor( + MzansiInnovationHub.of(context)!.theme.mode == "Dark"), + elevation: 10, + width: 300, + child: Text( + "Sign In/ Create Account", + style: TextStyle( + color: MihColors.getPrimaryColor( + MzansiInnovationHub.of(context)!.theme.mode == "Dark"), + fontSize: 20, + fontWeight: FontWeight.bold, + ), + ), + ), + ) + ], + ), + alertColour: MihColors.getSecondaryColor( + MzansiInnovationHub.of(context)!.theme.mode == "Dark"), + ), + ); } } diff --git a/Frontend/lib/mih_packages/mzansi_profile/business_profile/components/mih_delete_bookmark_alert.dart b/Frontend/lib/mih_packages/mzansi_profile/business_profile/components/mih_delete_bookmark_alert.dart index 2a935f9a..4d5dbae8 100644 --- a/Frontend/lib/mih_packages/mzansi_profile/business_profile/components/mih_delete_bookmark_alert.dart +++ b/Frontend/lib/mih_packages/mzansi_profile/business_profile/components/mih_delete_bookmark_alert.dart @@ -1,4 +1,5 @@ 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_objects/arguments.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_objects/bookmarked_business.dart'; @@ -36,35 +37,13 @@ class _MihDeleteBookmarkAlertState extends State { await MihMzansiDirectoryServices() .deleteBookmarkedBusiness(idbookmarked_businesses) .then((statusCode) { + context.pop(); if (statusCode == 200) { - // Navigator.of(context).pop(); //Remove loading circle - // Navigator.of(context).pop(); //Remove window - // Navigator.of(context).pop(); //Remove profile - // Navigator.of(context).pop(); //Remove directory - // Navigator.of(context).pushNamed( - // '/mzansi-directory', - // arguments: MzansiDirectoryArguments( - // startUpSearch: widget.startUpSearch, // startUpSearch - // personalSearch: false, // personalSearch - // ), - // ); - Navigator.of(context).pushNamedAndRemoveUntil( - '/mzansi-directory', - ModalRoute.withName('/'), - arguments: MzansiDirectoryArguments( - personalSearch: false, // personalSearch - packageIndex: 1, - startSearchText: widget.business.Name, - ), - ); - MihAlertServices().successAlert( + successPopUp( "Successfully Removed Bookmark!", "${widget.business.Name} has successfully been removed your favourite businessess in the Mzansi Directory.", - context, ); } else { - //error messagek - Navigator.of(context).pop(); MihAlertServices().errorAlert( "Error Adding Bookmark", "An error occured while add ${widget.business.Name} to you Mzansi Directory, Please try again later.", @@ -74,6 +53,71 @@ class _MihDeleteBookmarkAlertState extends State { }); } + void successPopUp(String title, String message) { + 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: title, + 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( + "mzansiDirectory", + extra: MzansiDirectoryArguments( + personalSearch: false, + startSearchText: widget.business.Name, + packageIndex: 1, + ), + ); + }, + 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, + // ); + }, + ); + } + @override Widget build(BuildContext context) { return MihPackageAlert( diff --git a/Frontend/lib/mih_packages/mzansi_profile/business_profile/components/mih_review_business_window.dart b/Frontend/lib/mih_packages/mzansi_profile/business_profile/components/mih_review_business_window.dart index 1d6e06dd..48de194b 100644 --- a/Frontend/lib/mih_packages/mzansi_profile/business_profile/components/mih_review_business_window.dart +++ b/Frontend/lib/mih_packages/mzansi_profile/business_profile/components/mih_review_business_window.dart @@ -1,6 +1,7 @@ import 'package:custom_rating_bar/custom_rating_bar.dart'; import 'package:flutter/material.dart'; 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_objects/arguments.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_objects/business.dart'; @@ -93,23 +94,13 @@ class _MihReviewBusinessWindowState extends State { widget.business.rating, ) .then((statusCode) { - Navigator.of(context).pop(); //Remove loading dialog - Navigator.of(context).pop(); //Remove delete dialog + context.pop(); //Remove loading dialog + context.pop(); //Remove delete dialog if (statusCode == 200) { - Navigator.of(context).pop(); //Remove window - Navigator.of(context).pop(); //Remove profile - Navigator.of(context).pop(); //Remove directory - Navigator.of(context).pushNamed( - '/mzansi-directory', - arguments: MzansiDirectoryArguments( - personalSearch: false, // personalSearch - startSearchText: widget.business.Name, - ), - ); - MihAlertServices().successAlert( + context.pop(); //Remove window + successPopUp( "Successfully Deleted Review!", "Your review has successfully been delete and will no longer appear under the business.", - context, ); } else { MihAlertServices().errorAlert( @@ -136,7 +127,7 @@ class _MihReviewBusinessWindowState extends State { MihButton( width: 300, onPressed: () { - Navigator.of(context).pop(); + context.pop(); }, buttonColor: MihColors.getGreenColor( MzansiInnovationHub.of(context)!.theme.mode == "Dark"), @@ -188,22 +179,12 @@ class _MihReviewBusinessWindowState extends State { widget.business.rating, ) .then((statusCode) { - Navigator.of(context).pop(); //Remove loading dialog + context.pop(); //Remove loading dialog if (statusCode == 200) { - Navigator.of(context).pop(); //pop window - Navigator.of(context).pop(); //pop business profile - Navigator.of(context).pop(); //pop directory - Navigator.of(context).pushNamed( - '/mzansi-directory', - arguments: MzansiDirectoryArguments( - personalSearch: false, // personalSearch - startSearchText: widget.business.Name, - ), - ); - MihAlertServices().successAlert( + context.pop(); + successPopUp( "Successfully Updated Review!", "Your review has successfully been updated and will now appear under the business.", - context, ); } else { MihAlertServices().errorAlert( @@ -224,22 +205,12 @@ class _MihReviewBusinessWindowState extends State { widget.business.rating.isEmpty ? "0.0" : widget.business.rating, ) .then((statusCode) { - Navigator.of(context).pop(); //Remove loading dialog + context.pop(); //Remove loading dialog if (statusCode == 201) { - Navigator.of(context).pop(); // pop window - Navigator.of(context).pop(); // pop business profile - Navigator.of(context).pop(); // pop directory - Navigator.of(context).pushNamed( - '/mzansi-directory', - arguments: MzansiDirectoryArguments( - personalSearch: false, // personalSearch - startSearchText: widget.business.Name, - ), - ); - MihAlertServices().successAlert( + context.pop(); + successPopUp( "Successfully Added Review!", "Your review has successfully been added and will now appear under the business.", - context, ); } else { MihAlertServices().errorAlert( @@ -252,6 +223,70 @@ class _MihReviewBusinessWindowState extends State { } } + void successPopUp(String title, String message) { + 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: title, + 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( + "mzansiDirectory", + extra: MzansiDirectoryArguments( + personalSearch: false, + startSearchText: widget.business.Name, + ), + ); + }, + 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, + // ); + }, + ); + } + String getWindowTitle() { if (widget.readOnly) { return "Review Details"; 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 7987eedf..f106ec95 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,3 +1,5 @@ +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_package_components/mih_package.dart'; @@ -66,7 +68,10 @@ class _MzansiBusinessProfileState extends State { icon: const Icon(Icons.arrow_back), iconSize: 35, onTap: () { - Navigator.of(context).pop(); + context.goNamed( + 'mihHome', + extra: false, + ); FocusScope.of(context).unfocus(); }, ); @@ -104,6 +109,11 @@ class _MzansiBusinessProfileState extends State { _selcetedIndex = 4; }); }; + temp[const Icon(Icons.qr_code_rounded)] = () { + setState(() { + _selcetedIndex = 5; + }); + }; return MihPackageTools( tools: temp, selcetedIndex: _selcetedIndex, @@ -156,6 +166,10 @@ class _MzansiBusinessProfileState extends State { MihMyBusinessTeam(arguments: widget.arguments), MihBusinessUserSearch(arguments: widget.arguments), MihBusinessReviews(business: widget.arguments.business!), + MihBusinessQrCode( + business: widget.arguments.business!, + startUpSearch: "", + ), ]; return toolBodies; } @@ -165,8 +179,9 @@ class _MzansiBusinessProfileState extends State { "Profile", "User", "Team", - "Add Member", + "Add", "Reviews", + "Share", ]; return toolTitles; } diff --git a/Frontend/lib/mih_packages/mzansi_profile/business_profile/mzansi_business_profile_view.dart b/Frontend/lib/mih_packages/mzansi_profile/business_profile/mzansi_business_profile_view.dart index fdba7344..2e625382 100644 --- a/Frontend/lib/mih_packages/mzansi_profile/business_profile/mzansi_business_profile_view.dart +++ b/Frontend/lib/mih_packages/mzansi_profile/business_profile/mzansi_business_profile_view.dart @@ -1,16 +1,24 @@ +import 'package:go_router/go_router.dart'; +import 'package:ken_logger/ken_logger.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_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:flutter/material.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_loading_circle.dart'; import 'package:mzansi_innovation_hub/mih_packages/mzansi_profile/business_profile/package_tools/mih_business_details_view.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_business_details_services.dart'; class MzansiBusinessProfileView extends StatefulWidget { - final BusinessViewArguments arguments; + final BusinessViewArguments? arguments; + final String? businessId; const MzansiBusinessProfileView({ super.key, required this.arguments, + required this.businessId, }); @override @@ -20,21 +28,62 @@ class MzansiBusinessProfileView extends StatefulWidget { class _MzansiBusinessProfileViewState extends State { int _selcetedIndex = 0; + Business? business; + String startUpSearch = ""; + + Future _fetchBusinessDetails() async { + if (widget.arguments != null) { + setState(() { + business = widget.arguments!.business; + startUpSearch = widget.arguments!.startUpSearch ?? ""; + }); + } else if (widget.businessId != null) { + final biz = await MihBusinessDetailsServices() + .getBusinessDetailsByBusinessId(widget.businessId!); + if (biz == null) { + context.goNamed( + 'mihHome', + extra: true, + ); + } else { + KenLogger.success("Business found: ${biz.Name}"); + setState(() { + business = biz; + startUpSearch = ""; + }); + } + } + } + + @override + void initState() { + super.initState(); + _fetchBusinessDetails(); + } @override Widget build(BuildContext context) { - return MihPackage( - appActionButton: getAction(), - appTools: getTools(), - appBody: getToolBody(), - appToolTitles: getToolTitle(), - selectedbodyIndex: _selcetedIndex, - onIndexChange: (newValue) { - setState(() { - _selcetedIndex = newValue; - }); - }, - ); + if (business == null) { + KenLogger.warning("Business is null, showing loading indicator"); + return Scaffold( + body: const Center( + child: Mihloadingcircle(), + ), + ); + } else { + return MihPackage( + appActionButton: getAction(), + appTools: getTools(), + appBody: getToolBody(), + appToolTitles: getToolTitle(), + selectedbodyIndex: _selcetedIndex, + onIndexChange: (newValue) { + setState(() { + _selcetedIndex = newValue; + }); + }, + ); + } } MihPackageAction getAction() { @@ -42,7 +91,13 @@ class _MzansiBusinessProfileViewState extends State { icon: const Icon(Icons.arrow_back), iconSize: 35, onTap: () { - Navigator.of(context).pop(); + context.goNamed( + "mzansiDirectory", + extra: MzansiDirectoryArguments( + personalSearch: false, + startSearchText: business!.Name, + ), + ); FocusScope.of(context).unfocus(); }, ); @@ -60,6 +115,11 @@ class _MzansiBusinessProfileViewState extends State { _selcetedIndex = 1; }); }; + temp[const Icon(Icons.qr_code_rounded)] = () { + setState(() { + _selcetedIndex = 2; + }); + }; return MihPackageTools( tools: temp, selcetedIndex: _selcetedIndex, @@ -69,10 +129,14 @@ class _MzansiBusinessProfileViewState extends State { List getToolBody() { List toolBodies = [ MihBusinessDetailsView( - business: widget.arguments.business, - startUpSearch: widget.arguments.startUpSearch, + business: business!, + startUpSearch: startUpSearch, ), - MihBusinessReviews(business: widget.arguments.business), + MihBusinessReviews(business: business!), + MihBusinessQrCode( + business: business!, + startUpSearch: startUpSearch, + ) ]; return toolBodies; } @@ -81,6 +145,7 @@ class _MzansiBusinessProfileViewState extends State { List toolTitles = [ "Profile", "Reviews", + "Share Business", ]; return toolTitles; } diff --git a/Frontend/lib/mih_packages/mzansi_profile/business_profile/package_tiles/mzansi_business_profile_tile.dart b/Frontend/lib/mih_packages/mzansi_profile/business_profile/package_tiles/mzansi_business_profile_tile.dart index 829f797f..abd349c7 100644 --- a/Frontend/lib/mih_packages/mzansi_profile/business_profile/package_tiles/mzansi_business_profile_tile.dart +++ b/Frontend/lib/mih_packages/mzansi_profile/business_profile/package_tiles/mzansi_business_profile_tile.dart @@ -1,3 +1,4 @@ +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_tile.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_icons.dart'; @@ -24,10 +25,14 @@ class _MzansiBusinessProfileTileState extends State { Widget build(BuildContext context) { return MihPackageTile( onTap: () { - Navigator.of(context).pushNamed( - '/business-profile/manage', - arguments: widget.arguments, + context.goNamed( + "businessProfileManage", + extra: widget.arguments, ); + // Navigator.of(context).pushNamed( + // '/business-profile/manage', + // arguments: widget.arguments, + // ); }, appName: "Business Profile", appIcon: Icon( diff --git a/Frontend/lib/mih_packages/mzansi_profile/business_profile/package_tiles/mzansi_setup_business_profile_tile.dart b/Frontend/lib/mih_packages/mzansi_profile/business_profile/package_tiles/mzansi_setup_business_profile_tile.dart index 68ab758d..268cea2a 100644 --- a/Frontend/lib/mih_packages/mzansi_profile/business_profile/package_tiles/mzansi_setup_business_profile_tile.dart +++ b/Frontend/lib/mih_packages/mzansi_profile/business_profile/package_tiles/mzansi_setup_business_profile_tile.dart @@ -1,3 +1,4 @@ +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_tile.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_icons.dart'; @@ -25,10 +26,14 @@ class _MzansiSetupBusinessProfileTileState Widget build(BuildContext context) { return MihPackageTile( onTap: () { - Navigator.of(context).pushNamed( - '/business-profile/set-up', - arguments: widget.signedInUser, + context.goNamed( + 'businessProfileSetup', + extra: widget.signedInUser, ); + // Navigator.of(context).pushNamed( + // '/business-profile/set-up', + // arguments: widget.signedInUser, + // ); }, appName: "Set Up Business", appIcon: Icon( 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 1e5afb6f..00c22f00 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,6 +1,7 @@ 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'; @@ -19,7 +20,6 @@ import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_ 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_components/mih_pop_up_messages/mih_success_message.dart'; import 'package:mzansi_innovation_hub/mih_config/mih_env.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_objects/arguments.dart'; @@ -55,6 +55,67 @@ class _MihBusinessDetailsState extends State { final ValueNotifier _counter = ValueNotifier(0); late String env; + 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.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, + // ); + }, + ); + } + Future submitForm() async { if (isFormFilled()) { int statusCode = 0; @@ -78,25 +139,10 @@ class _MihBusinessDetailsState extends State { 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, - ), - ); + //You left of here + String message = "Your information has been updated successfully!"; + successPopUp(message, false); // File uploaded successfully - showDialog( - context: context, - builder: (context) { - return const MIHSuccessMessage( - successType: "Success", - successMessage: "Business details updated successfully", - ); - }, - ); } else { // File upload failed showDialog( @@ -234,7 +280,7 @@ class _MihBusinessDetailsState extends State { fullscreen: false, windowTitle: 'Edit Profile', onWindowTapClose: () { - Navigator.of(context).pop(); + context.pop(); resetControllers(); }, windowBody: MihSingleChildScroll( diff --git a/Frontend/lib/mih_packages/mzansi_profile/business_profile/package_tools/mih_business_qr_code.dart b/Frontend/lib/mih_packages/mzansi_profile/business_profile/package_tools/mih_business_qr_code.dart new file mode 100644 index 00000000..1d31a2c4 --- /dev/null +++ b/Frontend/lib/mih_packages/mzansi_profile/business_profile/package_tools/mih_business_qr_code.dart @@ -0,0 +1,344 @@ +import 'package:cached_network_image/cached_network_image.dart'; +import 'package:file_picker/file_picker.dart'; +import 'package:flutter/material.dart'; +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_objects/business.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_floating_menu.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_icons.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_single_child_scroll.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_loading_circle.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_file_services.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_circle_avatar.dart'; +import 'package:supertokens_flutter/supertokens.dart'; +import 'package:url_launcher/url_launcher.dart'; + +class MihBusinessQrCode extends StatefulWidget { + final Business business; + final String? startUpSearch; + const MihBusinessQrCode({ + super.key, + required this.business, + required this.startUpSearch, + }); + + @override + State createState() => _MihBusinessQrCodeState(); +} + +class _MihBusinessQrCodeState extends State { + late Future futureImageUrl; + PlatformFile? file; + late String qrCodedata; + int qrSize = 500; + bool _isUserSignedIn = false; + + Future _checkUserSession() async { + final doesSessionExist = await SuperTokens.doesSessionExist(); + setState(() { + _isUserSignedIn = doesSessionExist; + }); + } + + String getQrCodeData(int qrSize) { + String color = MihColors.getPrimaryColor( + MzansiInnovationHub.of(context)!.theme.mode == "Dark") + .toARGB32() + .toRadixString(16) + .substring(2, 8); + // KenLogger.warning(color); + String bgColor = MihColors.getSecondaryColor( + MzansiInnovationHub.of(context)!.theme.mode == "Dark") + .toARGB32() + .toRadixString(16) + .substring(2, 8); + // KenLogger.warning(bgColor); + String encodedData = + Uri.encodeComponent("$qrCodedata${widget.business.business_id}"); + + return "https://api.qrserver.com/v1/create-qr-code/?data=$encodedData&size=${qrSize}x${qrSize}&bgcolor=$bgColor&color=$color"; + } + + Future downloadQrCode() async { + if (_isUserSignedIn) { + final Uri uri = Uri.parse(getQrCodeData(1024)); + if (!await launchUrl(uri)) { + throw 'Could not launch $uri'; + } + } else { + showSignInRequiredAlert(); + } + } + + void showSignInRequiredAlert() { + showDialog( + context: context, + builder: (context) => MihPackageAlert( + alertIcon: Column( + children: [ + Icon( + MihIcons.mihLogo, + size: 125, + color: MihColors.getSecondaryColor( + MzansiInnovationHub.of(context)!.theme.mode == "Dark"), + ), + const SizedBox(height: 10), + ], + ), + alertTitle: "Let's Get Started", + alertBody: Column( + children: [ + Text( + "Ready to dive in to the world of MIH?\nSign in or create a free MIH account to unlock all the powerful features of the MIH app. It's quick and easy!", + style: TextStyle( + color: MihColors.getSecondaryColor( + MzansiInnovationHub.of(context)!.theme.mode == "Dark"), + fontSize: 15, + ), + ), + const SizedBox(height: 25), + Center( + child: MihButton( + onPressed: () { + context.goNamed( + 'mihHome', + extra: true, + ); + }, + buttonColor: MihColors.getGreenColor( + MzansiInnovationHub.of(context)!.theme.mode == "Dark"), + elevation: 10, + width: 300, + child: Text( + "Sign In/ Create Account", + style: TextStyle( + color: MihColors.getPrimaryColor( + MzansiInnovationHub.of(context)!.theme.mode == "Dark"), + fontSize: 20, + fontWeight: FontWeight.bold, + ), + ), + ), + ) + ], + ), + alertColour: MihColors.getSecondaryColor( + MzansiInnovationHub.of(context)!.theme.mode == "Dark"), + ), + ); + } + + @override + void dispose() { + super.dispose(); + } + + @override + void initState() { + super.initState(); + _checkUserSession(); + futureImageUrl = + MihFileApi.getMinioFileUrl(widget.business.logo_path, context); + qrCodedata = + "${AppEnviroment.baseAppUrl}/business-profile/view?business_id="; + } + + @override + Widget build(BuildContext context) { + Size screenSize = MediaQuery.of(context).size; + return MihPackageToolBody( + borderOn: false, + innerHorizontalPadding: 10, + bodyItem: getBody(screenSize, context), + ); + } + + Widget getBody(Size screenSize, BuildContext context) { + double profilePictureWidth = 150; + return Stack( + alignment: Alignment.topCenter, + children: [ + MihSingleChildScroll( + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 15.0), + child: Padding( + padding: + MzansiInnovationHub.of(context)!.theme.screenType == "desktop" + ? EdgeInsets.symmetric(horizontal: screenSize.width * 0.2) + : EdgeInsets.symmetric( + horizontal: screenSize.width * 0), //.075), + child: Padding( + padding: const EdgeInsets.only(top: 10.0), + child: Material( + color: MihColors.getSecondaryColor( + MzansiInnovationHub.of(context)!.theme.mode == "Dark") + .withValues(alpha: 0.6), + borderRadius: BorderRadius.circular(25), + elevation: 10, + shadowColor: Colors.black, + child: Container( + decoration: BoxDecoration( + color: MihColors.getSecondaryColor( + MzansiInnovationHub.of(context)!.theme.mode == + "Dark"), + borderRadius: BorderRadius.circular(20), + ), + child: Padding( + padding: const EdgeInsets.all(20.0), + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + FutureBuilder( + future: futureImageUrl, + builder: (context, asyncSnapshot) { + if (asyncSnapshot.connectionState == + ConnectionState.done && + asyncSnapshot.hasData) { + if (asyncSnapshot.requireData != "") { + return MihCircleAvatar( + imageFile: NetworkImage( + asyncSnapshot.requireData), + width: profilePictureWidth, + editable: false, + fileNameController: + TextEditingController(), + userSelectedfile: file, + frameColor: MihColors.getPrimaryColor( + MzansiInnovationHub.of(context)! + .theme + .mode == + "Dark"), + backgroundColor: + MihColors.getSecondaryColor( + MzansiInnovationHub.of(context)! + .theme + .mode == + "Dark"), + onChange: () {}, + ); + } else { + return Icon( + MihIcons.iDontKnow, + size: profilePictureWidth, + color: MihColors.getSecondaryColor( + MzansiInnovationHub.of(context)! + .theme + .mode == + "Dark"), + ); + } + } else { + return Icon( + MihIcons.mihRing, + size: profilePictureWidth, + color: MihColors.getSecondaryColor( + MzansiInnovationHub.of(context)! + .theme + .mode == + "Dark"), + ); + } + }, + ), + FittedBox( + child: Text( + widget.business.Name, + style: TextStyle( + fontSize: 35, + fontWeight: FontWeight.bold, + color: MihColors.getPrimaryColor( + MzansiInnovationHub.of(context)! + .theme + .mode == + "Dark"), + ), + ), + ), + FittedBox( + child: Text( + widget.business.type, + style: TextStyle( + fontSize: 20, + fontWeight: FontWeight.w600, + color: MihColors.getPrimaryColor( + MzansiInnovationHub.of(context)! + .theme + .mode == + "Dark"), + ), + ), + ), + const SizedBox(height: 10), + SizedBox( + width: 300, + height: 300, + child: CachedNetworkImage( + imageUrl: getQrCodeData(qrSize.toInt()), + placeholder: (context, url) => + const Mihloadingcircle(), + errorWidget: (context, url, error) => + const Icon(Icons.error), + ), + ), + const SizedBox(height: 10), + FittedBox( + child: Text( + "Scan & Connect", + style: TextStyle( + fontSize: 30, + fontWeight: FontWeight.bold, + color: MihColors.getPrimaryColor( + MzansiInnovationHub.of(context)! + .theme + .mode == + "Dark"), + ), + ), + ), + ], + )), + ), + ), + ), + ), + ), + ), + Positioned( + right: 10, + bottom: 10, + child: MihFloatingMenu( + animatedIcon: AnimatedIcons.menu_close, + children: [ + SpeedDialChild( + child: Icon( + Icons.download_rounded, + color: MihColors.getPrimaryColor( + MzansiInnovationHub.of(context)!.theme.mode == "Dark"), + ), + label: "Download QR Code", + 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: () { + downloadQrCode(); + }, + ) + ]), + ) + ], + ); + } +} 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 084014a2..45e87a65 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,5 +1,6 @@ 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_config/mih_colors.dart'; import 'package:mzansi_innovation_hub/mih_services/mih_alert_services.dart'; @@ -15,7 +16,6 @@ import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_ import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_image_display.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_success_message.dart'; import 'package:mzansi_innovation_hub/mih_config/mih_env.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_objects/arguments.dart'; @@ -100,25 +100,27 @@ class _MihMyBusinessUserState extends State { 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, - ), - ); + // Navigator.of(context).pop(); + // Navigator.of(context).pop(); + // Navigator.of(context).pushNamed( + // '/', + // arguments: AuthArguments( + // false, + // false, + // ), + // ); // File uploaded successfully - showDialog( - context: context, - builder: (context) { - return const MIHSuccessMessage( - successType: "Success", - successMessage: "Business details updated successfully", - ); - }, - ); + 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( @@ -167,6 +169,67 @@ class _MihMyBusinessUserState extends State { } } + 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.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, + // ); + }, + ); + } + @override void dispose() { super.dispose(); diff --git a/Frontend/lib/mih_packages/mzansi_profile/business_profile/profile_business_add.dart b/Frontend/lib/mih_packages/mzansi_profile/business_profile/profile_business_add.dart index c8ad97fa..5362dde8 100644 --- a/Frontend/lib/mih_packages/mzansi_profile/business_profile/profile_business_add.dart +++ b/Frontend/lib/mih_packages/mzansi_profile/business_profile/profile_business_add.dart @@ -1,8 +1,10 @@ import 'dart:convert'; import 'package:country_code_picker/country_code_picker.dart'; +import 'package:go_router/go_router.dart'; import 'package:http/http.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_pop_up_messages/mih_loading_circle.dart'; import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart'; import 'package:mzansi_innovation_hub/mih_services/mih_alert_services.dart'; @@ -19,10 +21,8 @@ import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_ import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_form.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_success_message.dart'; import 'package:mzansi_innovation_hub/mih_config/mih_env.dart'; 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:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:file_picker/file_picker.dart'; @@ -103,14 +103,14 @@ class _ProfileBusinessAddState extends State { ); print("Status code: $statusCode"); if (statusCode == 201) { - Navigator.of(context).pop(); - Navigator.of(context).popAndPushNamed( - '/', - arguments: AuthArguments(false, false), - ); + // Navigator.of(context).pop(); + // Navigator.of(context).popAndPushNamed( + // '/', + // arguments: AuthArguments(false, false), + // ); String message = "Your business profile is now live! You can now start connecting with customers and growing your business."; - successPopUp(message); + successPopUp(message, false); } else { internetConnectionPopUp(); } @@ -166,14 +166,63 @@ class _ProfileBusinessAddState extends State { ); } - void successPopUp(String message) { + void successPopUp(String message, bool stayOnPersonalSide) { showDialog( context: context, builder: (context) { - return MIHSuccessMessage( - successType: "Success", - successMessage: message, + 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, + // ); }, ); } @@ -236,7 +285,11 @@ class _ProfileBusinessAddState extends State { icon: const Icon(Icons.arrow_back), iconSize: 35, onTap: () { - Navigator.of(context).pop(); + // Navigator.of(context).pop(); + context.goNamed( + 'mihHome', + extra: true, + ); }, ); } 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 c9c201f1..46dea907 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 @@ -1,3 +1,4 @@ +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'; @@ -41,7 +42,11 @@ class _MzansiProfileState extends State { icon: const Icon(Icons.arrow_back), iconSize: 35, onTap: () { - Navigator.of(context).pop(); + // Navigator.of(context).pop(); + context.goNamed( + 'mihHome', + extra: true, + ); FocusScope.of(context).unfocus(); }, ); diff --git a/Frontend/lib/mih_packages/mzansi_profile/personal_profile/mzansi_profile_view.dart b/Frontend/lib/mih_packages/mzansi_profile/personal_profile/mzansi_profile_view.dart index a1c47ae8..edea06c9 100644 --- a/Frontend/lib/mih_packages/mzansi_profile/personal_profile/mzansi_profile_view.dart +++ b/Frontend/lib/mih_packages/mzansi_profile/personal_profile/mzansi_profile_view.dart @@ -1,4 +1,6 @@ +import 'package:go_router/go_router.dart'; 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/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'; @@ -40,7 +42,13 @@ class _MzansiProfileViewState extends State { icon: const Icon(Icons.arrow_back), iconSize: 35, onTap: () { - Navigator.of(context).pop(); + context.goNamed( + "mzansiDirectory", + extra: MzansiDirectoryArguments( + personalSearch: true, + startSearchText: widget.user.username, + ), + ); FocusScope.of(context).unfocus(); }, ); diff --git a/Frontend/lib/mih_packages/mzansi_profile/personal_profile/package_tiles/mzansi_profile_tile.dart b/Frontend/lib/mih_packages/mzansi_profile/personal_profile/package_tiles/mzansi_profile_tile.dart index c3d5a754..730b1f0e 100644 --- a/Frontend/lib/mih_packages/mzansi_profile/personal_profile/package_tiles/mzansi_profile_tile.dart +++ b/Frontend/lib/mih_packages/mzansi_profile/personal_profile/package_tiles/mzansi_profile_tile.dart @@ -1,3 +1,4 @@ +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_tile.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_icons.dart'; @@ -28,9 +29,9 @@ class _MzansiProfileTileState extends State { // ImageProvider logo = MzansiInnovationHub.of(context)!.theme.logoImage(); return MihPackageTile( onTap: () { - Navigator.of(context).pushNamed( - '/mzansi-profile', - arguments: AppProfileUpdateArguments( + context.goNamed( + 'mzansiProfileManage', + extra: AppProfileUpdateArguments( widget.signedInUser, widget.propicFile, ), diff --git a/Frontend/lib/mih_packages/mzansi_profile/personal_profile/package_tiles/mzansi_setup_profile_tile.dart b/Frontend/lib/mih_packages/mzansi_profile/personal_profile/package_tiles/mzansi_setup_profile_tile.dart index 1744e842..37fff79c 100644 --- a/Frontend/lib/mih_packages/mzansi_profile/personal_profile/package_tiles/mzansi_setup_profile_tile.dart +++ b/Frontend/lib/mih_packages/mzansi_profile/personal_profile/package_tiles/mzansi_setup_profile_tile.dart @@ -1,3 +1,4 @@ +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_tile.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_icons.dart'; @@ -27,9 +28,9 @@ class _MzansiSetupProfileTileState extends State { Widget build(BuildContext context) { return MihPackageTile( onTap: () { - Navigator.of(context).pushNamed( - '/mzansi-profile', - arguments: AppProfileUpdateArguments( + context.goNamed( + 'mzansiProfileManage', + extra: AppProfileUpdateArguments( widget.signedInUser, widget.propicFile, ), 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 bdc49148..97f3900b 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,3 +1,4 @@ +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_config/mih_colors.dart'; @@ -14,7 +15,6 @@ 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_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_success_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'; @@ -131,19 +131,8 @@ class _MihPersonalProfileState extends State { if (originalProfileTypeIsBusiness == false && businessUser == true) { stayOnPersonalSide = false; } - Navigator.of(context).pop(); - Navigator.of(context).pop(); - Navigator.of(context).pop(); - Navigator.of(context).pushNamed( - '/', - arguments: AuthArguments( - stayOnPersonalSide, - // true, - false, - ), - ); String message = "Your information has been updated successfully!"; - successPopUp(message); + successPopUp(message, stayOnPersonalSide); } else { internetConnectionPopUp(); } @@ -164,14 +153,63 @@ class _MihPersonalProfileState extends State { } } - void successPopUp(String message) { + void successPopUp(String message, bool stayOnPersonalSide) { showDialog( context: context, builder: (context) { - return MIHSuccessMessage( - successType: "Success", - successMessage: message, + 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, + // ); }, ); } diff --git a/Frontend/lib/mih_packages/mzansi_wallet/builder/build_loyalty_card_list.dart b/Frontend/lib/mih_packages/mzansi_wallet/builder/build_loyalty_card_list.dart index da4ea1e3..688cfcc4 100644 --- a/Frontend/lib/mih_packages/mzansi_wallet/builder/build_loyalty_card_list.dart +++ b/Frontend/lib/mih_packages/mzansi_wallet/builder/build_loyalty_card_list.dart @@ -1,7 +1,12 @@ +import 'package:flutter/foundation.dart'; import 'package:flutter_speed_dial/flutter_speed_dial.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_objects/arguments.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_banner_ad.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_icons.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_error_message.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_mzansi_wallet_services.dart'; @@ -17,6 +22,7 @@ import 'package:mzansi_innovation_hub/mih_components/mih_objects/loyalty_card.da import 'package:mzansi_innovation_hub/mih_packages/mzansi_wallet/components/mih_card_display.dart'; import 'package:flutter/material.dart'; import 'package:barcode_widget/barcode_widget.dart'; +import 'package:screen_brightness/screen_brightness.dart'; class BuildLoyaltyCardList extends StatefulWidget { final AppUser signedInUser; @@ -46,12 +52,13 @@ class _BuildLoyaltyCardListState extends State { final TextEditingController _nicknameController = TextEditingController(); final TextEditingController _cardNumberController = TextEditingController(); late int _noFavourites; + double? _originalBrightness; final _formKey = GlobalKey(); void openscanner() async { - Navigator.of(context).pushNamed( - '/scanner', - arguments: _cardNumberController, + context.pushNamed( + "barcodeScanner", + extra: _cardNumberController, ); } @@ -136,18 +143,31 @@ class _BuildLoyaltyCardListState extends State { const SizedBox(height: 15), Center( child: MihButton( - onPressed: () { + onPressed: () async { if (_formKey.currentState!.validate()) { - MIHMzansiWalletApis.updateLoyaltyCardAPICall( + int statusCode = await MIHMzansiWalletApis + .updateLoyaltyCardAPICall( widget.signedInUser, widget.cardList[index].idloyalty_cards, widget.cardList[index].favourite, widget.cardList[index].priority_index, _nicknameController.text, _cardNumberController.text, - 0, ctxt, ); + if (statusCode == 200) { + context.pop(); + context.pop(); + context.goNamed( + "mzansiWallet", + extra: WalletArguments( + widget.signedInUser, + 0, + ), + ); + } else { + internetConnectionPopUp(); + } } else { MihAlertServices().formNotFilledCompletely(context); } @@ -184,13 +204,23 @@ class _BuildLoyaltyCardListState extends State { builder: (context) { return MIHDeleteMessage( deleteType: "Loyalty Card", - onTap: () { - MIHMzansiWalletApis.deleteLoyaltyCardAPICall( + onTap: () async { + int statusCode = + await MIHMzansiWalletApis.deleteLoyaltyCardAPICall( widget.signedInUser, widget.cardList[index].idloyalty_cards, - widget.navIndex, context, ); + if (statusCode == 200) { + setState(() { + widget.cardList.removeAt(index); + }); + context.pop(); + context.pop(); + } else { + context.pop(); + internetConnectionPopUp(); + } }); }, ); @@ -225,17 +255,30 @@ class _BuildLoyaltyCardListState extends State { height: 15, ), MihButton( - onPressed: () { - MIHMzansiWalletApis.updateLoyaltyCardAPICall( + onPressed: () async { + int statusCode = + await MIHMzansiWalletApis.updateLoyaltyCardAPICall( widget.signedInUser, widget.cardList[index].idloyalty_cards, "Yes", _noFavourites, widget.cardList[index].nickname, widget.cardList[index].card_number, - 1, ctxt, ); + if (statusCode == 200) { + context.pop(); + context.pop(); + context.goNamed( + "mzansiWallet", + extra: WalletArguments( + widget.signedInUser, + 1, + ), + ); + } else { + internetConnectionPopUp(); + } }, buttonColor: MihColors.getGreenColor( MzansiInnovationHub.of(context)!.theme.mode == "Dark"), @@ -257,6 +300,17 @@ class _BuildLoyaltyCardListState extends State { ); } + void internetConnectionPopUp() { + showDialog( + context: context, + builder: (context) { + return const MIHErrorMessage( + errorType: "Internet Connection", + ); + }, + ); + } + void removeFromFavCardWindow(BuildContext ctxt, int index) { showDialog( context: context, @@ -286,17 +340,30 @@ class _BuildLoyaltyCardListState extends State { height: 15, ), MihButton( - onPressed: () { - MIHMzansiWalletApis.updateLoyaltyCardAPICall( + onPressed: () async { + int statusCode = + await MIHMzansiWalletApis.updateLoyaltyCardAPICall( widget.signedInUser, widget.cardList[index].idloyalty_cards, "", 0, widget.cardList[index].nickname, widget.cardList[index].card_number, - 0, ctxt, ); + if (statusCode == 200) { + context.pop(); + context.pop(); + context.goNamed( + "mzansiWallet", + extra: WalletArguments( + widget.signedInUser, + 0, + ), + ); + } else { + internetConnectionPopUp(); + } }, buttonColor: MihColors.getRedColor( MzansiInnovationHub.of(context)!.theme.mode == "Dark"), @@ -411,10 +478,11 @@ class _BuildLoyaltyCardListState extends State { }, ), ], - onWindowTapClose: widget.onCardViewClose ?? - () { - Navigator.pop(context); - }, + onWindowTapClose: () { + widget.onCardViewClose; + resetScreenBrightness(); + context.pop(); + }, windowBody: Column( mainAxisSize: MainAxisSize.max, children: [ @@ -461,6 +529,7 @@ class _BuildLoyaltyCardListState extends State { // const SizedBox(height: 10), Text( formattedCardNumber, + textAlign: TextAlign.center, style: const TextStyle( color: Colors.black, fontSize: 25, @@ -498,6 +567,99 @@ class _BuildLoyaltyCardListState extends State { return count; } + Future setScreenBrightness(double newBrightness) async { + if (!kIsWeb) { + bool canChange = + await ScreenBrightness.instance.canChangeSystemBrightness; + + KenLogger.success("Can change system brightness: $canChange"); + if (canChange) { + // Permission is granted, you can now change the system brightness + ScreenBrightness.instance.system.then((brightness) { + setState(() { + _originalBrightness = brightness; + }); + KenLogger.success("Original brightness: $_originalBrightness"); + }); + await ScreenBrightness.instance + .setSystemScreenBrightness(newBrightness); + KenLogger.success("Brightness set to: $newBrightness"); + } else { + context.pop(); + showDialog( + context: context, + builder: (context) { + return MihPackageAlert( + alertIcon: Icon( + Icons.brightness_7_rounded, + size: 150, + color: MihColors.getSecondaryColor( + MzansiInnovationHub.of(context)!.theme.mode == "Dark"), + ), + alertTitle: "Permission Required", + alertBody: Column( + children: [ + Text( + "Sometimes it can be tough to scan your loyalty card if your phone screen is dim. To make sure your scan is successful every time, we need your permission to temporarily increase your screen brightness.\n\nWould you mind enabling this in your device settings?", + style: TextStyle( + color: MihColors.getSecondaryColor( + MzansiInnovationHub.of(context)!.theme.mode == + "Dark"), + fontSize: 15, + fontWeight: FontWeight.bold, + ), + ), + const SizedBox(height: 25), + MihButton( + onPressed: () async { + context.pop(); + await ScreenBrightness.instance + .setSystemScreenBrightness(newBrightness); + }, + buttonColor: MihColors.getGreenColor( + MzansiInnovationHub.of(context)!.theme.mode == "Dark"), + width: 300, + child: Text( + "Grant Permission", + style: TextStyle( + color: MihColors.getPrimaryColor( + MzansiInnovationHub.of(context)!.theme.mode == + "Dark"), + fontSize: 20, + fontWeight: FontWeight.bold, + ), + ), + ), + ], + ), + alertColour: MihColors.getSecondaryColor( + MzansiInnovationHub.of(context)!.theme.mode == "Dark"), + ); + }, + ); + } + } else { + KenLogger.warning( + "Screen brightness adjustment is not supported on Web."); + // _originalBrightness = 1.0; // Default brightness for web + // await ScreenBrightness.instance.setSystemScreenBrightness(1.0); + // KenLogger.success("Brightness set to default value: 1.0"); + } + } + + void resetScreenBrightness() async { + if (!kIsWeb) { + KenLogger.success( + "Resetting screen brightness to original value: $_originalBrightness"); + if (_originalBrightness != null) { + await ScreenBrightness.instance + .setSystemScreenBrightness(_originalBrightness!); + } + } else { + KenLogger.warning("Screen brightness reset is not supported on Web."); + } + } + @override void initState() { super.initState(); @@ -533,6 +695,7 @@ class _BuildLoyaltyCardListState extends State { height: 100, ), onTap: () { + setScreenBrightness(1.0); viewCardWindow(index, size.width); }, ); diff --git a/Frontend/lib/mih_packages/mzansi_wallet/components/mih_barcode_scanner.dart b/Frontend/lib/mih_packages/mzansi_wallet/components/mih_barcode_scanner.dart index 74c2040e..23eb53c5 100644 --- a/Frontend/lib/mih_packages/mzansi_wallet/components/mih_barcode_scanner.dart +++ b/Frontend/lib/mih_packages/mzansi_wallet/components/mih_barcode_scanner.dart @@ -1,5 +1,6 @@ import 'dart:async'; import 'package:flutter/material.dart'; +import 'package:go_router/go_router.dart'; import 'package:mobile_scanner/mobile_scanner.dart'; import 'package:mzansi_innovation_hub/main.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_button.dart'; @@ -36,7 +37,7 @@ class _MihBarcodeScannerState extends State }); print(bcode.barcodes.first.rawValue); _scannerController.stop(); - Navigator.of(context).pop(); + context.pop(); } } @@ -123,7 +124,7 @@ class _MihBarcodeScannerState extends State child: MihButton( onPressed: () { _scannerController.stop(); - Navigator.of(context).pop(); + context.pop(); }, buttonColor: MihColors.getRedColor( MzansiInnovationHub.of(context)!.theme.mode == diff --git a/Frontend/lib/mih_packages/mzansi_wallet/components/mih_card_display.dart b/Frontend/lib/mih_packages/mzansi_wallet/components/mih_card_display.dart index 1f086c9a..5f590c57 100644 --- a/Frontend/lib/mih_packages/mzansi_wallet/components/mih_card_display.dart +++ b/Frontend/lib/mih_packages/mzansi_wallet/components/mih_card_display.dart @@ -168,6 +168,7 @@ class _MihCardDisplayState extends State { FittedBox( child: Text( widget.nickname, + textAlign: TextAlign.center, style: const TextStyle( fontSize: 25, fontWeight: FontWeight.bold, diff --git a/Frontend/lib/mih_packages/mzansi_wallet/mih_wallet.dart b/Frontend/lib/mih_packages/mzansi_wallet/mih_wallet.dart index 24c85c74..bff4aa00 100644 --- a/Frontend/lib/mih_packages/mzansi_wallet/mih_wallet.dart +++ b/Frontend/lib/mih_packages/mzansi_wallet/mih_wallet.dart @@ -1,3 +1,4 @@ +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'; @@ -52,7 +53,10 @@ class _MihWalletState extends State { icon: const Icon(Icons.arrow_back), iconSize: 35, onTap: () { - Navigator.of(context).pop(); + context.goNamed( + 'mihHome', + extra: true, + ); FocusScope.of(context).unfocus(); }, ); diff --git a/Frontend/lib/mih_packages/mzansi_wallet/package_tiles/mih_wallet_tile.dart b/Frontend/lib/mih_packages/mzansi_wallet/package_tiles/mih_wallet_tile.dart index 83e483aa..ddb89401 100644 --- a/Frontend/lib/mih_packages/mzansi_wallet/package_tiles/mih_wallet_tile.dart +++ b/Frontend/lib/mih_packages/mzansi_wallet/package_tiles/mih_wallet_tile.dart @@ -1,3 +1,4 @@ +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_tile.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_icons.dart'; @@ -24,11 +25,16 @@ class _MihWalletTileState extends State { @override Widget build(BuildContext context) { return MihPackageTile( + // authenticateUser: true, onTap: () { - Navigator.of(context).pushNamed( - '/mzansi-wallet', - arguments: WalletArguments(widget.signedInUser, 0), + context.goNamed( + 'mzansiWallet', + extra: WalletArguments(widget.signedInUser, 0), ); + // Navigator.of(context).pushNamed( + // '/mzansi-wallet', + // arguments: WalletArguments(widget.signedInUser, 0), + // ); }, appName: "Mzansi Wallet", appIcon: Icon( diff --git a/Frontend/lib/mih_packages/mzansi_wallet/package_tools/mih_cards.dart b/Frontend/lib/mih_packages/mzansi_wallet/package_tools/mih_cards.dart index 0cd5b97a..fdd49288 100644 --- a/Frontend/lib/mih_packages/mzansi_wallet/package_tools/mih_cards.dart +++ b/Frontend/lib/mih_packages/mzansi_wallet/package_tools/mih_cards.dart @@ -1,6 +1,8 @@ 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_banner_ad.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_alert.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_mzansi_wallet_services.dart'; @@ -73,9 +75,9 @@ class _MihCardsState extends State { } void openscanner() async { - Navigator.of(context).pushNamed( - '/scanner', - arguments: cardNumberController, + context.pushNamed( + "barcodeScanner", + extra: cardNumberController, ); } @@ -87,6 +89,71 @@ class _MihCardsState extends State { } } + void successPopUp(String title, String message, int packageIndex) { + 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: title, + 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"), + ); + }, + ); + } + + void internetConnectionPopUp() { + showDialog( + context: context, + builder: (context) { + return const MIHErrorMessage( + errorType: "Internet Connection", + ); + }, + ); + } + void addCardWindow(BuildContext ctxt, double width) { showDialog( context: context, @@ -246,7 +313,7 @@ class _MihCardsState extends State { const SizedBox(height: 15), Center( child: MihButton( - onPressed: () { + onPressed: () async { if (_formKey.currentState!.validate()) { if (shopController.text == "") { showDialog( @@ -257,7 +324,8 @@ class _MihCardsState extends State { }, ); } else { - MIHMzansiWalletApis.addLoyaltyCardAPICall( + int statusCode = + await MIHMzansiWalletApis.addLoyaltyCardAPICall( widget.signedInUser, widget.signedInUser.app_id, shopController.text, @@ -265,9 +333,22 @@ class _MihCardsState extends State { "", 0, _nicknameController.text, - 0, context, ); + if (statusCode == 201) { + setState(() { + cardList = MIHMzansiWalletApis.getLoyaltyCards( + widget.signedInUser.app_id); + }); + context.pop(); + successPopUp( + "Successfully Added Card", + "The loyalty card has been added to your favourites.", + 0, + ); + } else { + internetConnectionPopUp(); + } } } else { MihAlertServices().formNotFilledCompletely(context); @@ -380,7 +461,7 @@ class _MihCardsState extends State { setState(() { _bannerAd = MihBannerAd(); }); - Navigator.pop(context); + // Navigator.pop(context); }, ); }, diff --git a/Frontend/lib/mih_packages/patient_profile/pat_manager/list_builders/build_mih_patient_search_list.dart b/Frontend/lib/mih_packages/patient_profile/pat_manager/list_builders/build_mih_patient_search_list.dart index 0772435e..68f98a06 100644 --- a/Frontend/lib/mih_packages/patient_profile/pat_manager/list_builders/build_mih_patient_search_list.dart +++ b/Frontend/lib/mih_packages/patient_profile/pat_manager/list_builders/build_mih_patient_search_list.dart @@ -1,4 +1,5 @@ import 'dart:convert'; +import 'package:go_router/go_router.dart'; import 'package:mzansi_innovation_hub/main.dart'; import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart'; import 'package:mzansi_innovation_hub/mih_services/mih_service_calls.dart'; @@ -363,15 +364,24 @@ class _BuildPatientsListState extends State { child: MihButton( onPressed: () { if (hasAccess) { - Navigator.of(context) - .pushNamed('/patient-manager/patient', - arguments: PatientViewArguments( - widget.signedInUser, - widget.patients[index], - widget.businessUser, - widget.business, - "business", - )); + context.pop(); + context.pushNamed('patientManagerPatient', + extra: PatientViewArguments( + widget.signedInUser, + widget.patients[index], + widget.businessUser, + widget.business, + "business", + )); + // Navigator.of(context) + // .pushNamed('/patient-manager/patient', + // arguments: PatientViewArguments( + // widget.signedInUser, + // widget.patients[index], + // widget.businessUser, + // widget.business, + // "business", + // )); } else { noAccessWarning(); } diff --git a/Frontend/lib/mih_packages/patient_profile/pat_manager/list_builders/build_my_patient_list_list.dart b/Frontend/lib/mih_packages/patient_profile/pat_manager/list_builders/build_my_patient_list_list.dart index aed37d40..d7e6059a 100644 --- a/Frontend/lib/mih_packages/patient_profile/pat_manager/list_builders/build_my_patient_list_list.dart +++ b/Frontend/lib/mih_packages/patient_profile/pat_manager/list_builders/build_my_patient_list_list.dart @@ -1,4 +1,6 @@ +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_config/mih_colors.dart'; import 'package:mzansi_innovation_hub/mih_services/mih_alert_services.dart'; import 'package:mzansi_innovation_hub/mih_services/mih_service_calls.dart'; @@ -49,14 +51,15 @@ class _BuildPatientsListState extends State { final baseAPI = AppEnviroment.baseApiUrl; - void submitApointment(int index) { + Future submitApointment(int index) async { //To-Do: Add the appointment to the database // print("To-Do: Add the appointment to the database"); String description = "Date: ${dateController.text}\nTime: ${timeController.text}\n"; description += "Medical Practice: ${widget.business!.Name}\n"; description += "Contact Number: ${widget.business!.contact_no}"; - MihMzansiCalendarApis.addPatientAppointment( + int statusCode; + statusCode = await MihMzansiCalendarApis.addPatientAppointment( widget.signedInUser, false, widget.patientAccesses[index].app_id, @@ -71,6 +74,86 @@ class _BuildPatientsListState extends State { timeController.text, context, ); + if (statusCode == 201) { + context.pop(); + successPopUp("Successfully Added Appointment", + "You appointment has been successfully added to your calendar."); + } else { + internetConnectionPopUp(); + } + } + + void internetConnectionPopUp() { + showDialog( + context: context, + builder: (context) { + return const MIHErrorMessage( + errorType: "Internet Connection", + ); + }, + ); + } + + void successPopUp(String title, String message) { + 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: title, + 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(); + context.pop(); + setState(() { + dateController.clear(); + timeController.clear(); + idController.clear(); + fnameController.clear(); + lnameController.clear(); + }); + }, + 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"), + ); + }, + ); } bool isAppointmentFieldsFilled() { @@ -341,15 +424,24 @@ class _BuildPatientsListState extends State { ), MihButton( onPressed: () { - Navigator.of(context) - .pushNamed('/patient-manager/patient', - arguments: PatientViewArguments( - widget.signedInUser, - patientProfile, - widget.businessUser, - widget.business, - "business", - )); + context.pop(); + context.pushNamed('patientManagerPatient', + extra: PatientViewArguments( + widget.signedInUser, + patientProfile, + widget.businessUser, + widget.business, + "business", + )); + // Navigator.of(context) + // .pushNamed('/patient-manager/patient', + // arguments: PatientViewArguments( + // widget.signedInUser, + // patientProfile, + // widget.businessUser, + // widget.business, + // "business", + // )); }, buttonColor: MihColors.getSecondaryColor( MzansiInnovationHub.of(context)!.theme.mode == diff --git a/Frontend/lib/mih_packages/patient_profile/pat_manager/package_tiles/pat_manager_tile.dart b/Frontend/lib/mih_packages/patient_profile/pat_manager/package_tiles/pat_manager_tile.dart index b17e794a..0d95b243 100644 --- a/Frontend/lib/mih_packages/patient_profile/pat_manager/package_tiles/pat_manager_tile.dart +++ b/Frontend/lib/mih_packages/patient_profile/pat_manager/package_tiles/pat_manager_tile.dart @@ -1,3 +1,4 @@ +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_tile.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_icons.dart'; @@ -22,11 +23,16 @@ class _PatManagerTileState extends State { @override Widget build(BuildContext context) { return MihPackageTile( + authenticateUser: true, onTap: () { - Navigator.of(context).pushNamed( - '/patient-manager', - arguments: widget.arguments, + context.goNamed( + 'patientManager', + extra: widget.arguments, ); + // Navigator.of(context).pushNamed( + // '/patient-manager', + // arguments: widget.arguments, + // ); }, appName: "Patient Manager", appIcon: Icon( diff --git a/Frontend/lib/mih_packages/patient_profile/pat_manager/package_tools/waiting_room.dart b/Frontend/lib/mih_packages/patient_profile/pat_manager/package_tools/waiting_room.dart index ac7dfb49..9dfe5cbf 100644 --- a/Frontend/lib/mih_packages/patient_profile/pat_manager/package_tools/waiting_room.dart +++ b/Frontend/lib/mih_packages/patient_profile/pat_manager/package_tools/waiting_room.dart @@ -1,6 +1,8 @@ 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_icons.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_alert.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_mzansi_calendar_services.dart'; @@ -269,7 +271,7 @@ class _WaitingRoomState extends State { fullscreen: false, windowTitle: "Appointment Type", onWindowTapClose: () { - Navigator.of(context).pop(); + context.pop(); }, windowBody: Column( children: [ @@ -285,7 +287,7 @@ class _WaitingRoomState extends State { MihButton( onPressed: () { widget.onIndexChange(1); - Navigator.of(context).pop(); + context.pop(); }, buttonColor: MihColors.getGreenColor( MzansiInnovationHub.of(context)!.theme.mode == "Dark"), @@ -304,7 +306,7 @@ class _WaitingRoomState extends State { MihButton( onPressed: () { widget.onIndexChange(2); - Navigator.of(context).pop(); + context.pop(); }, buttonColor: MihColors.getGreenColor( MzansiInnovationHub.of(context)!.theme.mode == "Dark"), @@ -354,7 +356,7 @@ class _WaitingRoomState extends State { fullscreen: false, windowTitle: "Add Appointment", onWindowTapClose: () { - Navigator.of(context).pop(); + context.pop(); _appointmentDateController.clear(); _appointmentTimeController.clear(); _appointmentTitleController.clear(); @@ -457,10 +459,11 @@ class _WaitingRoomState extends State { ); } - void addAppointmentCall() { + Future addAppointmentCall() async { if (isAppointmentInputValid()) { + int statusCode; if (widget.personalSelected == false) { - MihMzansiCalendarApis.addBusinessAppointment( + statusCode = await MihMzansiCalendarApis.addBusinessAppointment( widget.signedInUser, widget.business!, widget.businessUser!, @@ -472,7 +475,7 @@ class _WaitingRoomState extends State { context, ); } else { - MihMzansiCalendarApis.addPersonalAppointment( + statusCode = await MihMzansiCalendarApis.addPersonalAppointment( widget.signedInUser, _appointmentTitleController.text, _appointmentDescriptionIDController.text, @@ -481,6 +484,13 @@ class _WaitingRoomState extends State { context, ); } + if (statusCode == 201) { + context.pop(); + successPopUp("Successfully Added Appointment", + "You appointment has been successfully added to your calendar."); + } else { + internetConnectionPopUp(); + } } else { showDialog( context: context, @@ -492,6 +502,77 @@ class _WaitingRoomState extends State { checkforchange(); } + void internetConnectionPopUp() { + showDialog( + context: context, + builder: (context) { + return const MIHErrorMessage( + errorType: "Internet Connection", + ); + }, + ); + } + + void successPopUp(String title, String message) { + 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: title, + 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(); + setState(() { + _appointmentDateController.clear(); + _appointmentTimeController.clear(); + _appointmentTitleController.clear(); + _appointmentDescriptionIDController.clear(); + }); + }, + 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"), + ); + }, + ); + } + bool isAppointmentInputValid() { if (_appointmentDescriptionIDController.text.isEmpty || _appointmentDateController.text.isEmpty || diff --git a/Frontend/lib/mih_packages/patient_profile/pat_manager/pat_manager.dart b/Frontend/lib/mih_packages/patient_profile/pat_manager/pat_manager.dart index da284a2a..77003af1 100644 --- a/Frontend/lib/mih_packages/patient_profile/pat_manager/pat_manager.dart +++ b/Frontend/lib/mih_packages/patient_profile/pat_manager/pat_manager.dart @@ -1,3 +1,4 @@ +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'; @@ -48,7 +49,11 @@ class _PatManagerState extends State { icon: const Icon(Icons.arrow_back), iconSize: 35, onTap: () { - Navigator.of(context).pop(); + // Navigator.of(context).pop(); + context.goNamed( + 'mihHome', + extra: false, + ); FocusScope.of(context).unfocus(); }, ); diff --git a/Frontend/lib/mih_packages/patient_profile/pat_profile/add_or_view_patient.dart b/Frontend/lib/mih_packages/patient_profile/pat_profile/add_or_view_patient.dart index ee9e4a1a..c7a6455a 100644 --- a/Frontend/lib/mih_packages/patient_profile/pat_profile/add_or_view_patient.dart +++ b/Frontend/lib/mih_packages/patient_profile/pat_profile/add_or_view_patient.dart @@ -1,14 +1,12 @@ -import 'dart:convert'; import 'package:mzansi_innovation_hub/main.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_loading_circle.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/patients.dart'; import 'package:mzansi_innovation_hub/mih_packages/patient_profile/pat_profile/patient_add.dart'; import 'package:mzansi_innovation_hub/mih_packages/patient_profile/pat_profile/patient_profile.dart'; import 'package:flutter/material.dart'; -import 'package:supertokens_flutter/http.dart' as http; +import 'package:mzansi_innovation_hub/mih_services/mih_patient_services.dart'; class AddOrViewPatient extends StatefulWidget { //final AppUser signedInUser; @@ -28,39 +26,15 @@ class _AddOrViewPatientState extends State { late Widget loading; late Future patient; - Future fetchPatient() async { - //print("Patien manager page: $endpoint"); - final response = await http.get(Uri.parse( - "${AppEnviroment.baseApiUrl}/patients/${widget.arguments.signedInUser.app_id}")); - // print("Here"); - // print("Body: ${response.body}"); - // print("Code: ${response.statusCode}"); - // var errorCode = response.statusCode.toString(); - // var errorBody = response.body; - - if (response.statusCode == 200) { - // print("Here1"); - var decodedData = jsonDecode(response.body); - // print("Here2"); - Patient patients = Patient.fromJson(decodedData as Map); - // print("Here3"); - // print(patients); - return patients; - } - return null; - } - - @override - void dispose() { - // TODO: implement dispose - super.dispose(); + Future fetchPatientData() async { + return await MihPatientServices() + .getPatientDetails(widget.arguments.signedInUser.app_id); } @override void initState() { - // TODO: implement initState super.initState(); - patient = fetchPatient(); + patient = fetchPatientData(); } @override diff --git a/Frontend/lib/mih_packages/patient_profile/pat_profile/list_builders/build_claim_statement_files_list.dart b/Frontend/lib/mih_packages/patient_profile/pat_profile/list_builders/build_claim_statement_files_list.dart index 43a747c3..469018c5 100644 --- a/Frontend/lib/mih_packages/patient_profile/pat_profile/list_builders/build_claim_statement_files_list.dart +++ b/Frontend/lib/mih_packages/patient_profile/pat_profile/list_builders/build_claim_statement_files_list.dart @@ -2,6 +2,7 @@ import 'dart:async'; import 'package:fl_downloader/fl_downloader.dart'; 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_icons.dart'; import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart'; @@ -125,13 +126,21 @@ class _BuildClaimStatementFileListState void printDocument(String link, String path) async { http2.Response response = await http.get(Uri.parse(link)); var pdfData = response.bodyBytes; - Navigator.of(context).pushNamed( - '/file-veiwer/print-preview', - arguments: PrintPreviewArguments( + context.pop(); + context.pushNamed( + 'printPreview', + extra: PrintPreviewArguments( pdfData, getFileName(path), ), ); + // Navigator.of(context).pushNamed( + // '/file-veiwer/print-preview', + // arguments: PrintPreviewArguments( + // pdfData, + // getFileName(path), + // ), + // ); } void nativeFileDownload(String fileLink) async { @@ -222,7 +231,15 @@ class _BuildClaimStatementFileListState backgroundColor: MihColors.getGreenColor( MzansiInnovationHub.of(context)!.theme.mode == "Dark"), onTap: () { - printDocument(url, filePath); + context.pop(); + context.pushNamed( + 'fileViewer', + extra: FileViewArguments( + url, + filePath, + ), + ); + // printDocument(url, filePath); }, ), ); @@ -368,8 +385,9 @@ class _BuildClaimStatementFileListState return Padding( padding: const EdgeInsets.symmetric(horizontal: 10.0), child: Column( - // mainAxisAlignment: MainAxisAlignment.center, - // crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisSize: MainAxisSize.max, children: [ const SizedBox(height: 50), Stack( @@ -390,16 +408,23 @@ class _BuildClaimStatementFileListState ], ), const SizedBox(height: 10), - Text( - "No Claims or Statements have been added to this profile.", - textAlign: TextAlign.center, - overflow: TextOverflow.visible, - style: TextStyle( - fontSize: 25, - fontWeight: FontWeight.bold, - color: MihColors.getSecondaryColor( - MzansiInnovationHub.of(context)!.theme.mode == "Dark"), - ), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Expanded( + child: Text( + "No Claims or Statements have been added to this profile.", + textAlign: TextAlign.center, + style: TextStyle( + fontSize: 25, + fontWeight: FontWeight.bold, + color: MihColors.getSecondaryColor( + MzansiInnovationHub.of(context)!.theme.mode == + "Dark"), + ), + ), + ), + ], ), const SizedBox(height: 25), Visibility( diff --git a/Frontend/lib/mih_packages/patient_profile/pat_profile/list_builders/build_files_list.dart b/Frontend/lib/mih_packages/patient_profile/pat_profile/list_builders/build_files_list.dart index 7a42a458..3a302712 100644 --- a/Frontend/lib/mih_packages/patient_profile/pat_profile/list_builders/build_files_list.dart +++ b/Frontend/lib/mih_packages/patient_profile/pat_profile/list_builders/build_files_list.dart @@ -3,6 +3,7 @@ import 'dart:convert'; import 'package:fl_downloader/fl_downloader.dart'; 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_icons.dart'; import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart'; @@ -103,22 +104,22 @@ class _BuildFilesListState extends State { }), ); if (response2.statusCode == 200) { - Navigator.of(context).pop(); //Remove Loading Dialog - Navigator.of(context).pop(); //Remove Delete Dialog - Navigator.of(context).pop(); //Remove File View Dialog - Navigator.of(context).pop(); //Remove File List Dialog + context.pop(); //Remove Loading Dialog + context.pop(); //Remove Delete Dialog + context.pop(); //Remove File View Dialog + context.pop(); //Remove File List Dialog //print(widget.business); if (widget.business == null) { - Navigator.of(context).pushNamed('/patient-manager/patient', - arguments: PatientViewArguments( + context.pushNamed('patientManagerPatient', + extra: PatientViewArguments( widget.signedInUser, widget.selectedPatient, widget.businessUser, widget.business, "personal")); } else { - Navigator.of(context).pushNamed('/patient-manager/patient', - arguments: PatientViewArguments( + context.pushNamed('patientManagerPatient', + extra: PatientViewArguments( widget.signedInUser, widget.selectedPatient, widget.businessUser, @@ -175,9 +176,10 @@ class _BuildFilesListState extends State { void printDocument(String link, String path) async { http2.Response response = await http.get(Uri.parse(link)); var pdfData = response.bodyBytes; - Navigator.of(context).pushNamed( - '/file-veiwer/print-preview', - arguments: PrintPreviewArguments( + context.pop(); + context.pushNamed( + 'printPreview', + extra: PrintPreviewArguments( pdfData, getFileName(path), ), @@ -274,9 +276,10 @@ class _BuildFilesListState extends State { backgroundColor: MihColors.getGreenColor( MzansiInnovationHub.of(context)!.theme.mode == "Dark"), onTap: () { - Navigator.of(context).pushNamed( - '/file-veiwer', - arguments: FileViewArguments( + context.pop(); + context.pushNamed( + 'fileViewer', + extra: FileViewArguments( url, filePath, ), diff --git a/Frontend/lib/mih_packages/patient_profile/pat_profile/list_builders/build_notes_list.dart b/Frontend/lib/mih_packages/patient_profile/pat_profile/list_builders/build_notes_list.dart index d1649368..e3bb088a 100644 --- a/Frontend/lib/mih_packages/patient_profile/pat_profile/list_builders/build_notes_list.dart +++ b/Frontend/lib/mih_packages/patient_profile/pat_profile/list_builders/build_notes_list.dart @@ -294,8 +294,9 @@ class _BuildNotesListState extends State { return Padding( padding: const EdgeInsets.symmetric(horizontal: 10.0), child: Column( - // mainAxisAlignment: MainAxisAlignment.center, - // crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisSize: MainAxisSize.max, children: [ const SizedBox(height: 50), Stack( @@ -316,16 +317,24 @@ class _BuildNotesListState extends State { ], ), const SizedBox(height: 10), - Text( - "No Notes have been added to this profile.", - textAlign: TextAlign.center, - overflow: TextOverflow.visible, - style: TextStyle( - fontSize: 25, - fontWeight: FontWeight.bold, - color: MihColors.getSecondaryColor( - MzansiInnovationHub.of(context)!.theme.mode == "Dark"), - ), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Expanded( + child: Text( + "No Notes have been added to this profile.", + textAlign: TextAlign.center, + overflow: TextOverflow.visible, + style: TextStyle( + fontSize: 25, + fontWeight: FontWeight.bold, + color: MihColors.getSecondaryColor( + MzansiInnovationHub.of(context)!.theme.mode == + "Dark"), + ), + ), + ), + ], ), const SizedBox(height: 25), Visibility( diff --git a/Frontend/lib/mih_packages/patient_profile/pat_profile/package_tiles/patient_profile_tile.dart b/Frontend/lib/mih_packages/patient_profile/pat_profile/package_tiles/patient_profile_tile.dart index 2afadc0b..e6a82763 100644 --- a/Frontend/lib/mih_packages/patient_profile/pat_profile/package_tiles/patient_profile_tile.dart +++ b/Frontend/lib/mih_packages/patient_profile/pat_profile/package_tiles/patient_profile_tile.dart @@ -1,3 +1,4 @@ +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_tile.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_icons.dart'; @@ -23,11 +24,16 @@ class _PatientProfileTileState extends State { @override Widget build(BuildContext context) { return MihPackageTile( + authenticateUser: true, onTap: () { - Navigator.of(context).pushNamed( - '/patient-profile', - arguments: widget.arguments, + context.goNamed( + 'patientProfile', + extra: widget.arguments, ); + // Navigator.of(context).pushNamed( + // '/patient-profile', + // arguments: widget.arguments, + // ); }, appName: "Patient Profile", appIcon: Icon( diff --git a/Frontend/lib/mih_packages/patient_profile/pat_profile/package_tools/patient_info.dart b/Frontend/lib/mih_packages/patient_profile/pat_profile/package_tools/patient_info.dart index b86ea5b8..2f59f61e 100644 --- a/Frontend/lib/mih_packages/patient_profile/pat_profile/package_tools/patient_info.dart +++ b/Frontend/lib/mih_packages/patient_profile/pat_profile/package_tools/patient_info.dart @@ -1,4 +1,5 @@ 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_single_child_scroll.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_form.dart'; @@ -442,9 +443,13 @@ class _PatientInfoState extends State { backgroundColor: MihColors.getGreenColor( MzansiInnovationHub.of(context)!.theme.mode == "Dark"), onTap: () { - Navigator.of(context).pushNamed('/patient-profile/edit', - arguments: PatientEditArguments( - widget.signedInUser, widget.selectedPatient)); + context.goNamed( + 'patientProfileEdit', + extra: PatientEditArguments( + widget.signedInUser, + widget.selectedPatient, + ), + ); }, ) ], diff --git a/Frontend/lib/mih_packages/patient_profile/pat_profile/patient_add.dart b/Frontend/lib/mih_packages/patient_profile/pat_profile/patient_add.dart index 0c8b87c1..3863c927 100644 --- a/Frontend/lib/mih_packages/patient_profile/pat_profile/patient_add.dart +++ b/Frontend/lib/mih_packages/patient_profile/pat_profile/patient_add.dart @@ -1,8 +1,9 @@ -import 'dart:convert'; - +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_config/mih_colors.dart'; import 'package:mzansi_innovation_hub/mih_services/mih_alert_services.dart'; +import 'package:mzansi_innovation_hub/mih_services/mih_patient_services.dart'; import 'package:mzansi_innovation_hub/mih_services/mih_validation_services.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_layout/mih_action.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_layout/mih_body.dart'; @@ -13,13 +14,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_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_success_message.dart'; import 'package:mzansi_innovation_hub/mih_config/mih_env.dart'; 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:flutter/material.dart'; import 'package:flutter/services.dart'; -import 'package:supertokens_flutter/http.dart' as http; class AddPatient extends StatefulWidget { final AppUser signedInUser; @@ -89,40 +88,95 @@ class _AddPatientState extends State { } } - Future addPatientAPICall() async { - var response = await http.post( - Uri.parse("$baseAPI/patients/insert/"), - headers: { - "Content-Type": "application/json; charset=UTF-8" - }, - body: jsonEncode({ - "id_no": idController.text, - "first_name": fnameController.text, - "last_name": lnameController.text, - "email": emailController.text, - "cell_no": cellController.text, - "medical_aid": medAidController.text, - "medical_aid_main_member": medMainMemController.text, - "medical_aid_no": medNoController.text, - "medical_aid_code": medAidCodeController.text, - "medical_aid_name": medNameController.text, - "medical_aid_scheme": medSchemeController.text, - "address": addressController.text, - "app_id": widget.signedInUser.app_id, - }), + Future addPatientService() async { + int statusCode = await MihPatientServices().addPatientService( + idController.text, + fnameController.text, + lnameController.text, + emailController.text, + cellController.text, + medAidController.text, + medMainMemController.text, + medNoController.text, + medAidCodeController.text, + medNameController.text, + medSchemeController.text, + addressController.text, + widget.signedInUser, ); - if (response.statusCode == 201) { - Navigator.of(context).popAndPushNamed('/patient-profile', - arguments: PatientViewArguments( - widget.signedInUser, null, null, null, "personal")); + if (statusCode == 201) { String message = "${fnameController.text} ${lnameController.text} patient profile has been successfully added!\n"; - successPopUp(message); + successPopUp("Successfully created Patient Profile", message); } else { internetConnectionPopUp(); } } + void successPopUp(String title, String message) { + 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: title, + 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(); + context.goNamed( + 'patientProfile', + extra: PatientViewArguments( + widget.signedInUser, + null, + null, + null, + "personal", + ), + ); + }, + 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"), + ); + }, + ); + } + void internetConnectionPopUp() { showDialog( context: context, @@ -143,18 +197,6 @@ class _AddPatientState extends State { ); } - void successPopUp(String message) { - showDialog( - context: context, - builder: (context) { - return MIHSuccessMessage( - successType: "Success", - successMessage: message, - ); - }, - ); - } - void isRequired() { //print("listerner triggered"); if (medAidController.text == "Yes") { @@ -217,6 +259,7 @@ class _AddPatientState extends State { controller: fnameController, multiLineInput: false, requiredText: true, + readOnly: true, hintText: "First Name", validator: (value) { return MihValidationServices().isEmpty(value); @@ -231,6 +274,7 @@ class _AddPatientState extends State { controller: lnameController, multiLineInput: false, requiredText: true, + readOnly: true, hintText: "Surname", validator: (value) { return MihValidationServices().isEmpty(value); @@ -471,7 +515,7 @@ class _AddPatientState extends State { } void submitForm() { - addPatientAPICall(); + addPatientService(); } MIHAction getActionButton() { @@ -479,7 +523,11 @@ class _AddPatientState extends State { icon: const Icon(Icons.arrow_back), iconSize: 35, onTap: () { - Navigator.of(context).pop(); + context.goNamed( + 'mihHome', + extra: true, + ); + FocusScope.of(context).unfocus(); }, ); } diff --git a/Frontend/lib/mih_packages/patient_profile/pat_profile/patient_edit.dart b/Frontend/lib/mih_packages/patient_profile/pat_profile/patient_edit.dart index dc63a53d..1de1d5e4 100644 --- a/Frontend/lib/mih_packages/patient_profile/pat_profile/patient_edit.dart +++ b/Frontend/lib/mih_packages/patient_profile/pat_profile/patient_edit.dart @@ -1,8 +1,11 @@ import 'dart:convert'; +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_config/mih_colors.dart'; import 'package:mzansi_innovation_hub/mih_services/mih_alert_services.dart'; +import 'package:mzansi_innovation_hub/mih_services/mih_patient_services.dart'; import 'package:mzansi_innovation_hub/mih_services/mih_validation_services.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_layout/mih_action.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_layout/mih_body.dart'; @@ -13,7 +16,6 @@ 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_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_success_message.dart'; import 'package:mzansi_innovation_hub/mih_config/mih_env.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_objects/app_user.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_objects/arguments.dart'; @@ -84,49 +86,135 @@ class _EditPatientState extends State { // } Future updatePatientApiCall() async { - //print("Here1"); - //userEmail = getLoginUserEmail() as String; - //print(userEmail); - //print("Here2"); - //await getOfficeIdByUser(docOfficeIdApiUrl + userEmail); - //print(futureDocOfficeId.toString()); - //print("Here3"); - var response = await http.put( - Uri.parse(apiUrlEdit), - headers: { - "Content-Type": "application/json; charset=UTF-8" - }, - body: jsonEncode({ - "id_no": idController.text, - "first_name": fnameController.text, - "last_name": lnameController.text, - "email": emailController.text, - "cell_no": cellController.text, - "medical_aid": medAidController.text, - "medical_aid_main_member": medMainMemController.text, - "medical_aid_no": medNoController.text, - "medical_aid_code": medAidCodeController.text, - "medical_aid_name": medNameController.text, - "medical_aid_scheme": medSchemeController.text, - "address": addressController.text, - "app_id": widget.selectedPatient.app_id, - }), + var statusCode = await MihPatientServices().updatePatientService( + widget.selectedPatient.app_id, + idController.text, + fnameController.text, + lnameController.text, + emailController.text, + cellController.text, + medAidController.text, + medMainMemController.text, + medNoController.text, + medAidCodeController.text, + medNameController.text, + medSchemeController.text, + addressController.text, ); - // print("Here4"); - // print(response.statusCode); - if (response.statusCode == 200) { - Navigator.of(context).pop(); - Navigator.of(context).pop(); - Navigator.of(context).pushNamed('/patient-profile', - arguments: PatientViewArguments( - widget.signedInUser, null, null, null, "personal")); - //Navigator.of(context).pushNamed('/'); - String message = - "${fnameController.text} ${lnameController.text}'s information has been updated successfully! Their medical records and details are now current."; - successPopUp(message); + if (statusCode == 200) { + successPopUp( + "Successfully Updated Profile!", + "${fnameController.text} ${lnameController.text}'s information has been updated successfully! Their medical records and details are now current.", + ); } else { - internetConnectionPopUp(); + MihAlertServices().errorAlert( + "Error Updating Profile", + "There was an error updating your profile. Please try again later.", + context, + ); } + // var response = await http.put( + // Uri.parse(apiUrlEdit), + // headers: { + // "Content-Type": "application/json; charset=UTF-8" + // }, + // body: jsonEncode({ + // "id_no": idController.text, + // "first_name": fnameController.text, + // "last_name": lnameController.text, + // "email": emailController.text, + // "cell_no": cellController.text, + // "medical_aid": medAidController.text, + // "medical_aid_main_member": medMainMemController.text, + // "medical_aid_no": medNoController.text, + // "medical_aid_code": medAidCodeController.text, + // "medical_aid_name": medNameController.text, + // "medical_aid_scheme": medSchemeController.text, + // "address": addressController.text, + // "app_id": widget.selectedPatient.app_id, + // }), + // ); + // print(response.statusCode); + // if (response.statusCode == 200) { + // Navigator.of(context).pop(); + // Navigator.of(context).pop(); + // Navigator.of(context).pushNamed('/patient-profile', + // arguments: PatientViewArguments( + // widget.signedInUser, null, null, null, "personal")); + // //Navigator.of(context).pushNamed('/'); + // String message = + // "${fnameController.text} ${lnameController.text}'s information has been updated successfully! Their medical records and details are now current."; + // successPopUp(message); + // } else { + // internetConnectionPopUp(); + // } + } + + void successPopUp(String title, String message) { + 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: title, + 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( + "patientProfile", + extra: PatientViewArguments( + widget.signedInUser, + widget.selectedPatient, + null, + null, + "personal", + ), + ); + }, + 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 deletePatientApiCall() async { @@ -156,7 +244,7 @@ class _EditPatientState extends State { widget.signedInUser, null, null, null, "personal")); String message = "${fnameController.text} ${lnameController.text}'s record has been deleted successfully. This means it will no longer be visible in patient manager and cannot be used for future appointments."; - successPopUp(message); + successPopUp("Error", message); } else { internetConnectionPopUp(); } @@ -324,18 +412,6 @@ class _EditPatientState extends State { ); } - void successPopUp(String message) { - showDialog( - context: context, - builder: (context) { - return MIHSuccessMessage( - successType: "Success", - successMessage: message, - ); - }, - ); - } - bool isFieldsFilled() { if (medRequired.value) { if (idController.text.isEmpty || @@ -433,6 +509,7 @@ class _EditPatientState extends State { controller: fnameController, multiLineInput: false, requiredText: true, + readOnly: true, hintText: "First Name", validator: (value) { return MihValidationServices().isEmpty(value); @@ -447,6 +524,7 @@ class _EditPatientState extends State { controller: lnameController, multiLineInput: false, requiredText: true, + readOnly: true, hintText: "Surname", validator: (value) { return MihValidationServices().isEmpty(value); @@ -695,7 +773,17 @@ class _EditPatientState extends State { icon: const Icon(Icons.arrow_back), iconSize: 35, onTap: () { - Navigator.of(context).pop(); + context.goNamed( + 'patientProfile', + extra: PatientViewArguments( + widget.signedInUser, + null, + null, + null, + "personal", + ), + ); + // Navigator.of(context).pop(); }, ); } diff --git a/Frontend/lib/mih_packages/patient_profile/pat_profile/patient_profile.dart b/Frontend/lib/mih_packages/patient_profile/pat_profile/patient_profile.dart index 53d38d7e..01f3d6b6 100644 --- a/Frontend/lib/mih_packages/patient_profile/pat_profile/patient_profile.dart +++ b/Frontend/lib/mih_packages/patient_profile/pat_profile/patient_profile.dart @@ -1,3 +1,4 @@ +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'; @@ -42,7 +43,14 @@ class _PatientProfileState extends State { icon: const Icon(Icons.arrow_back), iconSize: 35, onTap: () { - Navigator.of(context).pop(); + if (widget.arguments.type == "business") { + context.pop(); + } else { + context.goNamed( + 'mihHome', + extra: true, + ); + } FocusScope.of(context).unfocus(); }, ); diff --git a/Frontend/lib/mih_services/mih_access_controls_services.dart b/Frontend/lib/mih_services/mih_access_controls_services.dart new file mode 100644 index 00000000..931c4899 --- /dev/null +++ b/Frontend/lib/mih_services/mih_access_controls_services.dart @@ -0,0 +1,81 @@ +import 'dart:convert'; +import 'package:flutter/material.dart'; +import 'package:go_router/go_router.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_objects/app_user.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:supertokens_flutter/http.dart' as http; + +class MihAccessControlsServices { + /// This function is used to UPDATE access the business has. + /// + /// Patameters:- + /// String business_id, + /// String business_name, + /// String app_id, + /// String status, + /// String approved_by, + /// AppUser signedInUser, + /// BuildContext context, + /// + /// Returns void (on success 200 navigate to /mih-access ). + Future updatePatientAccessAPICall( + String business_id, + String business_name, + String app_id, + String status, + String approved_by, + AppUser signedInUser, + BuildContext context, + ) async { + loadingPopUp(context); + var response = await http.put( + Uri.parse( + "${AppEnviroment.baseApiUrl}/access-requests/update/permission/"), + headers: { + "Content-Type": "application/json; charset=UTF-8" + }, + // business_id: str + // app_id: str + // status: str + // approved_by: str + body: jsonEncode({ + "business_id": business_id, + "app_id": app_id, + "status": status, + "approved_by": approved_by, + }), + ); + context.pop(); + return response.statusCode; + // if (response.statusCode == 200) { + // //Navigator.of(context).pushNamed('/home'); + // Navigator.of(context).pop(); + // Navigator.of(context).pop(); + // Navigator.of(context).pushNamed( + // '/mih-access', + // arguments: signedInUser, + // ); + // String message = ""; + // if (status == "approved") { + // message = + // "You've successfully approved the access request! $business_name now has access to your profile forever."; + // } else { + // message = + // "You've declined the access request. $business_name will not have access to your profile."; + // } + // successPopUp(message, context); + // } else { + // internetConnectionPopUp(context); + // } + } + + static void loadingPopUp(BuildContext context) { + showDialog( + context: context, + builder: (context) { + return const Mihloadingcircle(); + }, + ); + } +} diff --git a/Frontend/lib/mih_services/mih_authentication_services.dart b/Frontend/lib/mih_services/mih_authentication_services.dart index acee93a2..50c747aa 100644 --- a/Frontend/lib/mih_services/mih_authentication_services.dart +++ b/Frontend/lib/mih_services/mih_authentication_services.dart @@ -1,6 +1,7 @@ import 'dart:convert'; import 'package:flutter/material.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_config/mih_env.dart'; @@ -102,10 +103,58 @@ class MihAuthenticationServices { if (response.statusCode == 200) { var userSignedin = jsonDecode(response.body); if (userSignedin["status"] == "OK") { - Navigator.of(context).pop(); + context.pop(); + return true; + } else { + context.pop(); + return false; + } + } else { + return false; + } + } + + Future forgotPassword( + String email, + ) async { + var response = await http.post( + Uri.parse("$baseAPI/auth/user/password/reset/token"), + body: '{"formFields": [{"id": "email","value": "$email"}]}', + headers: { + 'Content-type': 'application/json', + 'Accept': 'application/json', + }, + ); + if (response.statusCode == 200) { + var userSignedin = jsonDecode(response.body); + if (userSignedin["status"] == "OK") { + return true; + } else { + return false; + } + } else { + return false; + } + } + + Future resetPassword( + String token, + String password, + ) async { + var response = await http.post( + Uri.parse("$baseAPI/auth/user/password/reset"), + body: + '{"method": "token","formFields": [{"id": "password","value": "$password"}],"token": "$token"}', + headers: { + 'Content-type': 'application/json', + 'Accept': 'application/json', + }, + ); + if (response.statusCode == 200) { + var userSignedin = jsonDecode(response.body); + if (userSignedin["status"] == "OK") { return true; } else { - Navigator.of(context).pop(); return false; } } else { diff --git a/Frontend/lib/mih_services/mih_claim_statement_generation_services.dart b/Frontend/lib/mih_services/mih_claim_statement_generation_services.dart index 46d06e89..b26edd99 100644 --- a/Frontend/lib/mih_services/mih_claim_statement_generation_services.dart +++ b/Frontend/lib/mih_services/mih_claim_statement_generation_services.dart @@ -1,5 +1,6 @@ import 'dart:convert'; +import 'package:go_router/go_router.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_components/mih_objects/claim_statement_file.dart'; @@ -89,12 +90,13 @@ class MIHClaimStatementGenerationApi { }), ); if (response2.statusCode == 201) { - // end loading circle - Navigator.of(context).pop(); - Navigator.of(context).pop(); - Navigator.of(context).pop(); - Navigator.of(context) - .pushNamed('/patient-manager/patient', arguments: args); + context.pop(); // end loading circle + context.pop(); + + context.pushNamed( + 'patientManagerPatient', + extra: args, + ); String message = "The ${data.document_type}: $fileName has been successfully generated and added to ${data.patient_full_name}'s record. You can now access and download it for their use."; successPopUp(message, context); @@ -215,14 +217,13 @@ class MIHClaimStatementGenerationApi { {"idclaim_statement_file": fileID, "env": env}), ); if (response2.statusCode == 200) { - Navigator.of(context).pop(); - Navigator.of(context).pop(); - Navigator.of(context).pop(); - Navigator.of(context).pop(); + context.pop(); + context.pop(); + context.pop(); + context.pop(); //print(widget.business); - Navigator.of(context) - .pushNamed('/patient-manager/patient', arguments: args); + context.pushNamed('patientManagerPatient', extra: args); // Navigator.of(context) // .pushNamed('/patient-profile', arguments: widget.signedInUser); diff --git a/Frontend/lib/mih_services/mih_mzansi_calendar_services.dart b/Frontend/lib/mih_services/mih_mzansi_calendar_services.dart index 2a4639b2..d01785aa 100644 --- a/Frontend/lib/mih_services/mih_mzansi_calendar_services.dart +++ b/Frontend/lib/mih_services/mih_mzansi_calendar_services.dart @@ -1,6 +1,6 @@ import 'dart:convert'; -import 'package:mzansi_innovation_hub/mih_services/mih_notification_services.dart'; +import 'package:go_router/go_router.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/app_user.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_objects/appointment.dart'; @@ -8,19 +8,7 @@ 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:flutter/material.dart'; -// import '../mih_components/mih_pop_up_messages/mih_error_message.dart'; -// import '../mih_components/mih_pop_up_messages/mih_success_message.dart'; -// import '../mih_env/mih_env.dart'; -// import '../mih_objects/app_user.dart'; -// import '../mih_objects/arguments.dart'; -// import '../mih_objects/business.dart'; -// import '../mih_objects/business_user.dart'; -// import '../mih_objects/notification.dart'; -// import '../mih_objects/patient_access.dart'; -// import '../mih_objects/patient_queue.dart'; -// import '../mih_objects/patients.dart'; import 'package:supertokens_flutter/http.dart' as http; - import '../mih_components/mih_pop_up_messages/mih_error_message.dart'; import '../mih_components/mih_pop_up_messages/mih_success_message.dart'; import '../mih_config/mih_env.dart'; @@ -39,23 +27,12 @@ class MihMzansiCalendarApis { String app_id, String date, ) async { - //print("Patien manager page: $endpoint"); final response = await http.get(Uri.parse( "${AppEnviroment.baseApiUrl}/appointments/personal/$app_id?date=$date")); - // print("Here"); - // print("Body: ${response.body}"); - // print("Code: ${response.statusCode}"); - // errorCode = response.statusCode.toString(); - // errorBody = response.body; - if (response.statusCode == 200) { - //print("Here1"); Iterable l = jsonDecode(response.body); - //print("Here2"); List personalAppointments = List.from(l.map((model) => Appointment.fromJson(model))); - //print("Here3"); - //print(patientQueue); return personalAppointments; } else { throw Exception('failed to fatch personal appointments'); @@ -114,7 +91,7 @@ class MihMzansiCalendarApis { /// BuildContext context, /// /// Returns VOID (TRIGGERS NOTIGICATIOPN ON SUCCESS) - static Future deleteAppointmentAPICall( + static Future deleteAppointmentAPICall( AppUser signedInUser, bool personalSelected, Business? business, @@ -123,6 +100,7 @@ class MihMzansiCalendarApis { int idappointments, BuildContext context, ) async { + loadingPopUp(context); var response = await http.delete( Uri.parse("${AppEnviroment.baseApiUrl}/appointment/delete/"), headers: { @@ -130,39 +108,41 @@ class MihMzansiCalendarApis { }, body: jsonEncode({"idappointments": idappointments}), ); + context.pop(); + return response.statusCode; //print("Here4"); //print(response.statusCode); - if (response.statusCode == 200) { - Navigator.of(context).pop(); - Navigator.of(context).pop(); - Navigator.of(context).pop(); - if (inWaitingRoom == true && personalSelected == false) { - Navigator.of(context).pushNamed( - '/patient-manager', - arguments: PatManagerArguments( - signedInUser, - false, - business, - businessUser, - ), - ); - } else { - Navigator.of(context).pushNamed( - '/calendar', - arguments: CalendarArguments( - signedInUser, - personalSelected, - business, - businessUser, - ), - ); - } - String message = - "The appointment has been deleted successfully. This means it will no longer be visible in your Calendar."; - successPopUp(message, context); - } else { - internetConnectionPopUp(context); - } + // if (response.statusCode == 200) { + // Navigator.of(context).pop(); + // Navigator.of(context).pop(); + // Navigator.of(context).pop(); + // if (inWaitingRoom == true && personalSelected == false) { + // Navigator.of(context).pushNamed( + // '/patient-manager', + // arguments: PatManagerArguments( + // signedInUser, + // false, + // business, + // businessUser, + // ), + // ); + // } else { + // Navigator.of(context).pushNamed( + // '/calendar', + // arguments: CalendarArguments( + // signedInUser, + // personalSelected, + // business, + // businessUser, + // ), + // ); + // } + // String message = + // "The appointment has been deleted successfully. This means it will no longer be visible in your Calendar."; + // successPopUp(message, context); + // } else { + // internetConnectionPopUp(context); + // } } /// This function is used to add an appointment to users mzansi Calendar. @@ -177,7 +157,7 @@ class MihMzansiCalendarApis { /// BuildContext context, /// /// Returns VOID (TRIGGERS SUCCESS pop up) - static Future addPersonalAppointment( + static Future addPersonalAppointment( AppUser signedInUser, String title, String description, @@ -200,28 +180,30 @@ class MihMzansiCalendarApis { "time": time, }), ); - if (response.statusCode == 201) { - Navigator.pop(context); - Navigator.pop(context); - Navigator.pop(context); - String message = - "Your appointment \"$title\" for the $date $title has been deleted."; + context.pop(); + return response.statusCode; + // if (response.statusCode == 201) { + // Navigator.pop(context); + // Navigator.pop(context); + // Navigator.pop(context); + // String message = + // "Your appointment \"$title\" for the $date $title has been deleted."; - // Navigator.pop(context); - Navigator.of(context).pushNamed( - '/calendar', - arguments: CalendarArguments( - signedInUser, - true, - null, - null, - ), - ); - successPopUp(message, context); - } else { - Navigator.pop(context); - internetConnectionPopUp(context); - } + // // Navigator.pop(context); + // Navigator.of(context).pushNamed( + // '/calendar', + // arguments: CalendarArguments( + // signedInUser, + // true, + // null, + // null, + // ), + // ); + // successPopUp(message, context); + // } else { + // Navigator.pop(context); + // internetConnectionPopUp(context); + // } } /// This function is used to add an appointment to users mzansi Calendar. @@ -236,7 +218,7 @@ class MihMzansiCalendarApis { /// BuildContext context, /// /// Returns VOID (TRIGGERS SUCCESS pop up) - static Future addBusinessAppointment( + static Future addBusinessAppointment( AppUser signedInUser, Business business, BusinessUser businessUser, @@ -262,42 +244,44 @@ class MihMzansiCalendarApis { "time": time, }), ); - if (response.statusCode == 201) { - // Navigator.pop(context); - Navigator.pop(context); - Navigator.pop(context); - Navigator.pop(context); - String message = - "Your appointment \"$title\" for the $date $title has been deleted."; + context.pop(); + return response.statusCode; + // if (response.statusCode == 201) { + // // Navigator.pop(context); + // Navigator.pop(context); + // Navigator.pop(context); + // Navigator.pop(context); + // String message = + // "Your appointment \"$title\" for the $date $title has been deleted."; - // Navigator.pop(context); - if (inWaitingRoom) { - Navigator.of(context).pushNamed( - '/patient-manager', - arguments: PatManagerArguments( - signedInUser, - false, - business, - businessUser, - ), - ); - } else { - Navigator.of(context).pushNamed( - '/calendar', - arguments: CalendarArguments( - signedInUser, - false, - business, - businessUser, - ), - ); - } + // // Navigator.pop(context); + // if (inWaitingRoom) { + // Navigator.of(context).pushNamed( + // '/patient-manager', + // arguments: PatManagerArguments( + // signedInUser, + // false, + // business, + // businessUser, + // ), + // ); + // } else { + // Navigator.of(context).pushNamed( + // '/calendar', + // arguments: CalendarArguments( + // signedInUser, + // false, + // business, + // businessUser, + // ), + // ); + // } - successPopUp(message, context); - } else { - Navigator.pop(context); - internetConnectionPopUp(context); - } + // successPopUp(message, context); + // } else { + // Navigator.pop(context); + // internetConnectionPopUp(context); + // } } /// This function is used to add an appointment to users mzansi Calendar. @@ -312,7 +296,7 @@ class MihMzansiCalendarApis { /// BuildContext context, /// /// Returns VOID (TRIGGERS SUCCESS pop up) - static Future addPatientAppointment( + static Future addPatientAppointment( AppUser signedInUser, bool personalSelected, String patientAppId, @@ -338,20 +322,22 @@ class MihMzansiCalendarApis { "time": time, }), ); - if (response.statusCode == 201) { - MihNotificationApis.addNewAppointmentNotificationAPICall( - patientAppId, - personalSelected, - date, - time, - businessArgs, - context, - ); - // Navigator.pop(context); - } else { - Navigator.pop(context); - internetConnectionPopUp(context); - } + context.pop(); + return response.statusCode; + // if (response.statusCode == 201) { + // MihNotificationApis.addNewAppointmentNotificationAPICall( + // patientAppId, + // personalSelected, + // date, + // time, + // businessArgs, + // context, + // ); + // // Navigator.pop(context); + // } else { + // Navigator.pop(context); + // internetConnectionPopUp(context); + // } } /// This function is used to update an appointment to users mzansi Calendar. @@ -367,7 +353,7 @@ class MihMzansiCalendarApis { /// BuildContext context, /// /// Returns VOID (TRIGGERS SUCCESS pop up) - static Future updatePersonalAppointment( + static Future updatePersonalAppointment( AppUser signedInUser, Business? business, BusinessUser? businessUser, @@ -392,28 +378,30 @@ class MihMzansiCalendarApis { "time": time, }), ); - if (response.statusCode == 200) { - Navigator.pop(context); - Navigator.pop(context); - Navigator.pop(context); - String message = - "Your appointment \"$title\" has been updates to the $date $title."; + context.pop(); + return response.statusCode; + // if (response.statusCode == 200) { + // Navigator.pop(context); + // Navigator.pop(context); + // Navigator.pop(context); + // String message = + // "Your appointment \"$title\" has been updates to the $date $title."; - Navigator.pop(context); - Navigator.of(context).pushNamed( - '/calendar', - arguments: CalendarArguments( - signedInUser, - true, - business, - businessUser, - ), - ); - successPopUp(message, context); - } else { - Navigator.pop(context); - internetConnectionPopUp(context); - } + // Navigator.pop(context); + // Navigator.of(context).pushNamed( + // '/calendar', + // arguments: CalendarArguments( + // signedInUser, + // true, + // business, + // businessUser, + // ), + // ); + // successPopUp(message, context); + // } else { + // Navigator.pop(context); + // internetConnectionPopUp(context); + // } } /// This function is used to update an appointment to users mzansi Calendar. @@ -429,7 +417,7 @@ class MihMzansiCalendarApis { /// BuildContext context, /// /// Returns VOID (TRIGGERS SUCCESS pop up) - static Future updateBusinessAppointment( + static Future updateBusinessAppointment( AppUser signedInUser, Business? business, BusinessUser? businessUser, @@ -454,28 +442,30 @@ class MihMzansiCalendarApis { "time": time, }), ); - if (response.statusCode == 200) { - Navigator.pop(context); - Navigator.pop(context); - Navigator.pop(context); - String message = - "Your appointment \"$title\" has been updates to the $date $title."; + context.pop(); + return response.statusCode; + // if (response.statusCode == 200) { + // Navigator.pop(context); + // Navigator.pop(context); + // Navigator.pop(context); + // String message = + // "Your appointment \"$title\" has been updates to the $date $title."; - Navigator.pop(context); - Navigator.of(context).pushNamed( - '/calendar', - arguments: CalendarArguments( - signedInUser, - false, - business, - businessUser, - ), - ); - successPopUp(message, context); - } else { - Navigator.pop(context); - internetConnectionPopUp(context); - } + // Navigator.pop(context); + // Navigator.of(context).pushNamed( + // '/calendar', + // arguments: CalendarArguments( + // signedInUser, + // false, + // business, + // businessUser, + // ), + // ); + // successPopUp(message, context); + // } else { + // Navigator.pop(context); + // internetConnectionPopUp(context); + // } } /// This function is used to update an appointment to users mzansi Calendar. @@ -491,7 +481,7 @@ class MihMzansiCalendarApis { /// BuildContext context, /// /// Returns VOID (TRIGGERS SUCCESS pop up) - static Future updatePatientAppointment( + static Future updatePatientAppointment( AppUser signedInUser, Business? business, BusinessUser? businessUser, @@ -516,29 +506,31 @@ class MihMzansiCalendarApis { "time": time, }), ); - if (response.statusCode == 200) { - Navigator.pop(context); - Navigator.pop(context); - Navigator.pop(context); - Navigator.pop(context); - String message = - "Your appointment \"$title\" has been updates to the $date $title."; + context.pop(); + return response.statusCode; + // if (response.statusCode == 200) { + // Navigator.pop(context); + // Navigator.pop(context); + // Navigator.pop(context); + // Navigator.pop(context); + // String message = + // "Your appointment \"$title\" has been updates to the $date $title."; - // Navigator.pop(context); - Navigator.of(context).pushNamed( - '/patient-manager', - arguments: PatManagerArguments( - signedInUser, - false, - business, - businessUser, - ), - ); - successPopUp(message, context); - } else { - Navigator.pop(context); - internetConnectionPopUp(context); - } + // // Navigator.pop(context); + // Navigator.of(context).pushNamed( + // '/patient-manager', + // arguments: PatManagerArguments( + // signedInUser, + // false, + // business, + // businessUser, + // ), + // ); + // successPopUp(message, context); + // } else { + // Navigator.pop(context); + // internetConnectionPopUp(context); + // } } //================== POP UPS ========================================================================== diff --git a/Frontend/lib/mih_services/mih_mzansi_wallet_services.dart b/Frontend/lib/mih_services/mih_mzansi_wallet_services.dart index acbdf2a1..01254196 100644 --- a/Frontend/lib/mih_services/mih_mzansi_wallet_services.dart +++ b/Frontend/lib/mih_services/mih_mzansi_wallet_services.dart @@ -1,7 +1,7 @@ import 'dart:convert'; +import 'package:go_router/go_router.dart'; 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_objects/loyalty_card.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_loading_circle.dart'; import 'package:flutter/material.dart'; @@ -22,22 +22,12 @@ class MIHMzansiWalletApis { static Future> getLoyaltyCards( String app_id, ) async { - //print("Patien manager page: $endpoint"); final response = await http.get(Uri.parse( "${AppEnviroment.baseApiUrl}/mzasni-wallet/loyalty-cards/$app_id")); - // print("Here"); - // print("Body: ${response.body}"); - // print("Code: ${response.statusCode}"); - // 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) => MIHLoyaltyCard.fromJson(model))); - //print("Here3"); - //print(patientQueue); return patientQueue; } else { throw Exception('failed to fatch loyalty cards'); @@ -55,19 +45,10 @@ class MIHMzansiWalletApis { //print("Patien manager page: $endpoint"); final response = await http.get(Uri.parse( "${AppEnviroment.baseApiUrl}/mzasni-wallet/loyalty-cards/favourites/$app_id")); - // print("Here"); - // print("Body: ${response.body}"); - // print("Code: ${response.statusCode}"); - // 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) => MIHLoyaltyCard.fromJson(model))); - //print("Here3"); - //print(patientQueue); return patientQueue; } else { throw Exception('failed to fatch loyalty cards'); @@ -82,10 +63,9 @@ class MIHMzansiWalletApis { /// BuildContext context, /// /// Returns VOID (TRIGGERS NOTIGICATIOPN ON SUCCESS) - static Future deleteLoyaltyCardAPICall( + static Future deleteLoyaltyCardAPICall( AppUser signedInUser, int idloyalty_cards, - int navIndex, BuildContext context, ) async { loadingPopUp(context); @@ -99,22 +79,24 @@ class MIHMzansiWalletApis { ); //print("Here4"); //print(response.statusCode); - if (response.statusCode == 200) { - Navigator.of(context).pop(); - Navigator.of(context).pop(); - Navigator.of(context).pop(); - Navigator.of(context).pop(); - Navigator.of(context).pushNamed( - '/mzansi-wallet', - arguments: WalletArguments(signedInUser, navIndex), - ); - String message = - "The loyalty card has been deleted successfully. This means it will no longer be visible in your Mzansi Wallet."; - successPopUp(message, context); - } else { - Navigator.pop(context); - internetConnectionPopUp(context); - } + context.pop(); + return response.statusCode; + // if (response.statusCode == 200) { + // Navigator.of(context).pop(); + // Navigator.of(context).pop(); + // Navigator.of(context).pop(); + // Navigator.of(context).pop(); + // Navigator.of(context).pushNamed( + // '/mzansi-wallet', + // arguments: WalletArguments(signedInUser, navIndex), + // ); + // String message = + // "The loyalty card has been deleted successfully. This means it will no longer be visible in your Mzansi Wallet."; + // successPopUp(message, context); + // } else { + // Navigator.pop(context); + // internetConnectionPopUp(context); + // } } /// This function is used to add a lopyalty card to users mzansi wallet. @@ -127,7 +109,7 @@ class MIHMzansiWalletApis { /// BuildContext context, /// /// Returns VOID (TRIGGERS SUCCESS pop up) - static Future addLoyaltyCardAPICall( + static Future addLoyaltyCardAPICall( AppUser signedInUser, String app_id, String shop_name, @@ -135,7 +117,6 @@ class MIHMzansiWalletApis { String favourite, int priority_index, String nickname, - int navIndex, BuildContext context, ) async { loadingPopUp(context); @@ -154,21 +135,23 @@ class MIHMzansiWalletApis { "nickname": nickname, }), ); - if (response.statusCode == 201) { - Navigator.pop(context); - String message = - "Your $shop_name Loyalty Card was successfully added to your Mzansi Wallet."; - Navigator.pop(context); - Navigator.pop(context); - Navigator.of(context).pushNamed( - '/mzansi-wallet', - arguments: WalletArguments(signedInUser, navIndex), - ); - successPopUp(message, context); - } else { - Navigator.pop(context); - internetConnectionPopUp(context); - } + context.pop(); + return response.statusCode; + // if (response.statusCode == 201) { + // // Navigator.pop(context); + // // String message = + // // "Your $shop_name Loyalty Card was successfully added to your Mzansi Wallet."; + // // Navigator.pop(context); + // // Navigator.pop(context); + // // Navigator.of(context).pushNamed( + // // '/mzansi-wallet', + // // arguments: WalletArguments(signedInUser, navIndex), + // // ); + // // successPopUp(message, context); + // } else { + // // Navigator.pop(context); + // // internetConnectionPopUp(context); + // } } /// This function is used to Update loyalty card from users mzansi wallet. @@ -179,14 +162,13 @@ class MIHMzansiWalletApis { /// BuildContext context, /// /// Returns VOID (TRIGGERS NOTIGICATIOPN ON SUCCESS) - static Future updateLoyaltyCardAPICall( + static Future updateLoyaltyCardAPICall( AppUser signedInUser, int idloyalty_cards, String favourite, int priority_index, String nickname, String card_number, - int navIndex, BuildContext context, ) async { loadingPopUp(context); @@ -204,23 +186,8 @@ class MIHMzansiWalletApis { "card_number": card_number, }), ); - //print("Here4"); - //print(response.statusCode); - if (response.statusCode == 200) { - Navigator.of(context).pop(); - Navigator.of(context).pop(); - Navigator.of(context).pop(); - Navigator.of(context).pop(); - Navigator.of(context).pushNamed( - '/mzansi-wallet', - arguments: WalletArguments(signedInUser, navIndex), - ); - String message = "The loyalty card has been added to your favourites."; - successPopUp(message, context); - } else { - Navigator.pop(context); - internetConnectionPopUp(context); - } + context.pop(); + return response.statusCode; } //================== POP UPS ========================================================================== diff --git a/Frontend/lib/mih_services/mih_notification_services.dart b/Frontend/lib/mih_services/mih_notification_services.dart index c58bca6f..0b45bbd4 100644 --- a/Frontend/lib/mih_services/mih_notification_services.dart +++ b/Frontend/lib/mih_services/mih_notification_services.dart @@ -1,5 +1,6 @@ import 'dart:convert'; +import 'package:go_router/go_router.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_objects/arguments.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_objects/notification.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_error_message.dart'; @@ -61,10 +62,9 @@ class MihNotificationApis { String message = "A request has been sent to the patient advising that you have requested access to their profile. Only once access has been granted will you be able to book an appointment."; Navigator.of(context).pop(); - Navigator.of(context).pop(); - Navigator.of(context).pushNamed( - '/patient-manager', - arguments: PatManagerArguments( + context.goNamed( + 'patientManager', + extra: PatManagerArguments( args.signedInUser, personalSelected, args.business, @@ -108,16 +108,25 @@ class MihNotificationApis { String message = "A request has been sent to the patient advising that you have re-applied for access to their profile. Only once access has been granted will you be able to book an appointment."; Navigator.of(context).pop(); - Navigator.of(context).pop(); - Navigator.of(context).pushNamed( - '/patient-manager', - arguments: PatManagerArguments( + context.goNamed( + 'patientManager', + extra: PatManagerArguments( args.signedInUser, personalSelected, args.business, args.businessUser, ), ); + // Navigator.of(context).pop(); + // Navigator.of(context).pushNamed( + // '/patient-manager', + // arguments: PatManagerArguments( + // args.signedInUser, + // personalSelected, + // args.business, + // args.businessUser, + // ), + // ); successPopUp(message, context); } else { internetConnectionPopUp(context); diff --git a/Frontend/lib/mih_services/mih_patient_services.dart b/Frontend/lib/mih_services/mih_patient_services.dart index b57e89f2..57420896 100644 --- a/Frontend/lib/mih_services/mih_patient_services.dart +++ b/Frontend/lib/mih_services/mih_patient_services.dart @@ -1,5 +1,6 @@ import 'dart:convert'; +import 'package:mzansi_innovation_hub/mih_components/mih_objects/app_user.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_objects/patients.dart'; import 'package:mzansi_innovation_hub/mih_config/mih_env.dart'; import 'package:supertokens_flutter/http.dart' as http; @@ -11,7 +12,7 @@ class MihPatientServices { String appId, ) async { var response = await http.get( - Uri.parse("${AppEnviroment.baseApiUrl}/patient/app_id/$appId"), + Uri.parse("${AppEnviroment.baseApiUrl}/patients/$appId"), headers: { "Content-Type": "application/json; charset=UTF-8" }, @@ -24,4 +25,82 @@ class MihPatientServices { return null; } } + + Future addPatientService( + String id_no, + String fname, + String lname, + String email, + String cell, + String medAid, + String medMainMem, + String medNo, + String medAidCode, + String medName, + String medScheme, + String address, + AppUser signedInUser, + ) async { + var response = await http.post( + Uri.parse("$baseAPI/patients/insert/"), + headers: { + "Content-Type": "application/json; charset=UTF-8" + }, + body: jsonEncode({ + "id_no": id_no, + "first_name": fname, + "last_name": lname, + "email": email, + "cell_no": cell, + "medical_aid": medAid, + "medical_aid_main_member": medMainMem, + "medical_aid_no": medNo, + "medical_aid_code": medAidCode, + "medical_aid_name": medName, + "medical_aid_scheme": medScheme, + "address": address, + "app_id": signedInUser.app_id, + }), + ); + return response.statusCode; + } + + Future updatePatientService( + String app_id, + String id_no, + String fname, + String lname, + String email, + String cell, + String medAid, + String medMainMem, + String medNo, + String medAidCode, + String medName, + String medScheme, + String address, + ) async { + var response = await http.put( + Uri.parse("$baseAPI/patients/update/"), + headers: { + "Content-Type": "application/json; charset=UTF-8" + }, + body: jsonEncode({ + "id_no": id_no, + "first_name": fname, + "last_name": lname, + "email": email, + "cell_no": cell, + "medical_aid": medAid, + "medical_aid_main_member": medMainMem, + "medical_aid_no": medNo, + "medical_aid_code": medAidCode, + "medical_aid_name": medName, + "medical_aid_scheme": medScheme, + "address": address, + "app_id": app_id, + }), + ); + return response.statusCode; + } } diff --git a/Frontend/lib/mih_services/mih_user_services.dart b/Frontend/lib/mih_services/mih_user_services.dart index 01d1ebb4..4b267345 100644 --- a/Frontend/lib/mih_services/mih_user_services.dart +++ b/Frontend/lib/mih_services/mih_user_services.dart @@ -1,10 +1,13 @@ import 'dart:convert'; +import 'package:go_router/go_router.dart'; +import 'package:mzansi_innovation_hub/main.dart'; 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/mih_button.dart'; +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_pop_up_messages/mih_success_message.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:supertokens_flutter/http.dart' as http; @@ -46,18 +49,10 @@ class MihUserServices { }), ); if (response.statusCode == 201) { - Navigator.of(context).pushNamedAndRemoveUntil( - '/', - (route) => false, - arguments: AuthArguments( - true, - true, - ), + context.goNamed( + 'mihHome', + extra: true, ); - // signUpSuccess(); - // setState(() { - // successfulSignUp = true; - // }); } else { internetConnectionPopUp(context); } @@ -202,15 +197,16 @@ 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 + // 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. } @@ -233,14 +229,63 @@ class MihUserServices { ); } - static void successPopUp(String message, BuildContext context) { + static void successPopUp(String title, String message, BuildContext context) { showDialog( context: context, builder: (context) { - return MIHSuccessMessage( - successType: "Success", - successMessage: message, + return MihPackageAlert( + alertIcon: Icon( + Icons.check_circle_outline_rounded, + size: 150, + color: MihColors.getGreenColor( + MzansiInnovationHub.of(context)!.theme.mode == "Dark"), + ), + alertTitle: title, + 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: true, + ); + }, + 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, + // ); }, ); } diff --git a/Frontend/macos/Flutter/GeneratedPluginRegistrant.swift b/Frontend/macos/Flutter/GeneratedPluginRegistrant.swift index 66bdd02e..6abc3575 100644 --- a/Frontend/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/Frontend/macos/Flutter/GeneratedPluginRegistrant.swift @@ -14,8 +14,10 @@ import local_auth_darwin import mobile_scanner import path_provider_foundation import printing +import screen_brightness_macos import share_plus import shared_preferences_foundation +import sqflite_darwin import syncfusion_pdfviewer_macos import url_launcher_macos import webview_flutter_wkwebview @@ -30,8 +32,10 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { MobileScannerPlugin.register(with: registry.registrar(forPlugin: "MobileScannerPlugin")) PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) PrintingPlugin.register(with: registry.registrar(forPlugin: "PrintingPlugin")) + ScreenBrightnessMacosPlugin.register(with: registry.registrar(forPlugin: "ScreenBrightnessMacosPlugin")) SharePlusMacosPlugin.register(with: registry.registrar(forPlugin: "SharePlusMacosPlugin")) SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin")) + SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin")) SyncfusionFlutterPdfViewerPlugin.register(with: registry.registrar(forPlugin: "SyncfusionFlutterPdfViewerPlugin")) UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin")) WebViewFlutterPlugin.register(with: registry.registrar(forPlugin: "WebViewFlutterPlugin")) diff --git a/Frontend/pubspec.lock b/Frontend/pubspec.lock index ef6cb694..cc62b381 100644 --- a/Frontend/pubspec.lock +++ b/Frontend/pubspec.lock @@ -177,6 +177,30 @@ packages: url: "https://pub.dev" source: hosted version: "8.10.1" + cached_network_image: + dependency: "direct main" + description: + name: cached_network_image + sha256: "7c1183e361e5c8b0a0f21a28401eecdbde252441106a9816400dd4c2b2424916" + url: "https://pub.dev" + source: hosted + version: "3.4.1" + cached_network_image_platform_interface: + dependency: transitive + description: + name: cached_network_image_platform_interface + sha256: "35814b016e37fbdc91f7ae18c8caf49ba5c88501813f73ce8a07027a395e2829" + url: "https://pub.dev" + source: hosted + version: "4.1.1" + cached_network_image_web: + dependency: transitive + description: + name: cached_network_image_web + sha256: "980842f4e8e2535b8dbd3d5ca0b1f0ba66bf61d14cc3a17a9b4788a3685ba062" + url: "https://pub.dev" + source: hosted + version: "1.3.1" characters: dependency: transitive description: @@ -414,6 +438,14 @@ packages: description: flutter source: sdk version: "0.0.0" + flutter_cache_manager: + dependency: transitive + description: + name: flutter_cache_manager + sha256: "400b6592f16a4409a7f2bb929a9a7e38c72cceb8ffb99ee57bbf2cb2cecf8386" + url: "https://pub.dev" + source: hosted + version: "3.4.1" flutter_chat_types: dependency: "direct main" description: @@ -462,14 +494,22 @@ packages: url: "https://pub.dev" source: hosted version: "6.0.0" + flutter_math_fork: + dependency: transitive + description: + name: flutter_math_fork + sha256: "6d5f2f1aa57ae539ffb0a04bb39d2da67af74601d685a161aff7ce5bda5fa407" + url: "https://pub.dev" + source: hosted + version: "0.7.4" flutter_native_splash: dependency: "direct main" description: name: flutter_native_splash - sha256: aa06fec78de2190f3db4319dd60fdc8d12b2626e93ef9828633928c2dcaea840 + sha256: "8321a6d11a8d13977fa780c89de8d257cce3d841eecfb7a4cadffcc4f12d82dc" url: "https://pub.dev" source: hosted - version: "2.4.1" + version: "2.4.6" flutter_parsed_text: dependency: transitive description: @@ -608,6 +648,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.3" + go_router: + dependency: "direct main" + description: + name: go_router + sha256: "8b1f37dfaf6e958c6b872322db06f946509433bec3de753c3491a42ae9ec2b48" + url: "https://pub.dev" + source: hosted + version: "16.1.0" google_mobile_ads: dependency: "direct main" description: @@ -616,6 +664,14 @@ packages: url: "https://pub.dev" source: hosted version: "6.0.0" + gpt_markdown: + dependency: "direct main" + description: + name: gpt_markdown + sha256: "68d5337c8a00fc03a37dbddf84a6fd90401c30e99b6baf497ef9522a81fc34ee" + url: "https://pub.dev" + source: hosted + version: "1.1.2" graphs: dependency: transitive description: @@ -856,6 +912,22 @@ packages: url: "https://pub.dev" source: hosted version: "3.1.0" + nested: + dependency: transitive + description: + name: nested + sha256: "03bac4c528c64c95c722ec99280375a6f2fc708eec17c7b3f07253b626cd2a20" + url: "https://pub.dev" + source: hosted + version: "1.0.0" + octo_image: + dependency: transitive + description: + name: octo_image + sha256: "34faa6639a78c7e3cbe79be6f9f96535867e879748ade7d17c9b1ae7536293bd" + url: "https://pub.dev" + source: hosted + version: "2.1.0" ollama_dart: dependency: "direct main" description: @@ -1016,6 +1088,14 @@ packages: url: "https://pub.dev" source: hosted version: "4.1.0" + provider: + dependency: transitive + description: + name: provider + sha256: "4e82183fa20e5ca25703ead7e05de9e4cceed1fbd1eadc1ac3cb6f565a09f272" + url: "https://pub.dev" + source: hosted + version: "6.1.5+1" pub_semver: dependency: transitive description: @@ -1056,6 +1136,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.13" + rxdart: + dependency: transitive + description: + name: rxdart + sha256: "5c3004a4a8dbb94bd4bf5412a4def4acdaa12e12f269737a5751369e12d1a962" + url: "https://pub.dev" + source: hosted + version: "0.28.0" scratch_space: dependency: transitive description: @@ -1064,6 +1152,62 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.2" + screen_brightness: + dependency: "direct main" + description: + name: screen_brightness + sha256: b6cb9381b83fef7be74187ea043d54598b9a265b4ef6e40b69345ae28699b13e + url: "https://pub.dev" + source: hosted + version: "2.1.6" + screen_brightness_android: + dependency: transitive + description: + name: screen_brightness_android + sha256: fb5fa43cb89d0c9b8534556c427db1e97e46594ac5d66ebdcf16063b773d54ed + url: "https://pub.dev" + source: hosted + version: "2.1.2" + screen_brightness_ios: + dependency: transitive + description: + name: screen_brightness_ios + sha256: "2493953340ecfe8f4f13f61db50ce72533a55b0bbd58ba1402893feecf3727f5" + url: "https://pub.dev" + source: hosted + version: "2.1.2" + screen_brightness_macos: + dependency: transitive + description: + name: screen_brightness_macos + sha256: "4edf330ad21078686d8bfaf89413325fbaf571dcebe1e89254d675a3f288b5b9" + url: "https://pub.dev" + source: hosted + version: "2.1.1" + screen_brightness_ohos: + dependency: transitive + description: + name: screen_brightness_ohos + sha256: af2680660f7df785bcd2b1bef9b9f3c172191166dd27098f2dfe020c50c3dea4 + url: "https://pub.dev" + source: hosted + version: "2.1.1" + screen_brightness_platform_interface: + dependency: transitive + description: + name: screen_brightness_platform_interface + sha256: "737bd47b57746bc4291cab1b8a5843ee881af499514881b0247ec77447ee769c" + url: "https://pub.dev" + source: hosted + version: "2.1.0" + screen_brightness_windows: + dependency: transitive + description: + name: screen_brightness_windows + sha256: d3518bf0f5d7a884cee2c14449ae0b36803802866de09f7ef74077874b6b2448 + url: "https://pub.dev" + source: hosted + version: "2.1.0" scroll_to_index: dependency: transitive description: @@ -1197,6 +1341,46 @@ packages: url: "https://pub.dev" source: hosted version: "7.0.0" + sqflite: + dependency: transitive + description: + name: sqflite + sha256: e2297b1da52f127bc7a3da11439985d9b536f75070f3325e62ada69a5c585d03 + url: "https://pub.dev" + source: hosted + version: "2.4.2" + sqflite_android: + dependency: transitive + description: + name: sqflite_android + sha256: "2b3070c5fa881839f8b402ee4a39c1b4d561704d4ebbbcfb808a119bc2a1701b" + url: "https://pub.dev" + source: hosted + version: "2.4.1" + sqflite_common: + dependency: transitive + description: + name: sqflite_common + sha256: "6ef422a4525ecc601db6c0a2233ff448c731307906e92cabc9ba292afaae16a6" + url: "https://pub.dev" + source: hosted + version: "2.5.6" + sqflite_darwin: + dependency: transitive + description: + name: sqflite_darwin + sha256: "279832e5cde3fe99e8571879498c9211f3ca6391b0d818df4e17d9fff5c6ccb3" + url: "https://pub.dev" + source: hosted + version: "2.4.2" + sqflite_platform_interface: + dependency: transitive + description: + name: sqflite_platform_interface + sha256: "8dd4515c7bdcae0a785b0062859336de775e8c65db81ae33dd5445f35be61920" + url: "https://pub.dev" + source: hosted + version: "2.4.0" stack_trace: dependency: transitive description: @@ -1301,6 +1485,14 @@ packages: url: "https://pub.dev" source: hosted version: "29.2.10" + synchronized: + dependency: transitive + description: + name: synchronized + sha256: c254ade258ec8282947a0acbbc90b9575b4f19673533ee46f2f6e9b3aeefd7c0 + url: "https://pub.dev" + source: hosted + version: "3.4.0" table_calendar: dependency: "direct main" description: @@ -1333,6 +1525,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.2" + tuple: + dependency: transitive + description: + name: tuple + sha256: a97ce2013f240b2f3807bcbaf218765b6f301c3eff91092bcfa23a039e7dd151 + url: "https://pub.dev" + source: hosted + version: "2.0.2" typed_data: dependency: transitive description: diff --git a/Frontend/pubspec.yaml b/Frontend/pubspec.yaml index e06cca41..86c7242e 100644 --- a/Frontend/pubspec.yaml +++ b/Frontend/pubspec.yaml @@ -1,7 +1,7 @@ name: mzansi_innovation_hub description: "" publish_to: 'none' # Remove this line if you wish to publish to pub.dev -version: 1.1.16+93 +version: 1.2.0+94 environment: sdk: '>=3.5.3 <4.0.0' @@ -22,7 +22,7 @@ dependencies: args: ^2.7.0 gif_view: ^1.0.3 intl: ^0.20.2 - flutter_native_splash: ^2.4.1 + flutter_native_splash: ^2.4.6 printing: ^5.13.3 geolocator: ^14.0.1 table_calendar: ^3.1.2 @@ -48,6 +48,10 @@ dependencies: custom_rating_bar: ^3.0.0 country_code_picker: ^3.3.0 ken_logger: ^0.0.3 + go_router: ^16.1.0 + screen_brightness: ^2.1.6 + cached_network_image: ^3.4.1 + gpt_markdown: ^1.1.2 dev_dependencies: flutter_test: @@ -72,13 +76,16 @@ flutter: - family: MihIcons fonts: - asset: lib/mih_components/mih_package_components/assets/fonts/Mih_Icons.ttf + flutter_native_splash: color: "#3A4454" - image: lib/mih_components/mih_package_components/assets/images/logo_light.png - branding: lib/mih_components/mih_package_components/assets/images/branding_text.png + image: lib/mih_components/mih_package_components/assets/images/splash_screen/mih_image_splash.png + branding: lib/mih_components/mih_package_components/assets/images/splash_screen/mih_branding_splash.png + image_web: lib/mih_components/mih_package_components/assets/images/splash_screen/mih_image_splash_temp.gif + branding_web: lib/mih_components/mih_package_components/assets/images/splash_screen/mih_branding_splash_temp.gif branding_mode: bottom branding_bottom_padding: 24 android_12: - image: lib/mih_components/mih_package_components/assets/images/splash_screen/splash_screen_icon.png color: "#3A4454" - branding: lib/mih_components/mih_package_components/assets/images/branding_text.png \ No newline at end of file + image: lib/mih_components/mih_package_components/assets/images/splash_screen/mih_image_splash.png + branding: lib/mih_components/mih_package_components/assets/images/splash_screen/mih_branding_splash.png \ No newline at end of file diff --git a/Frontend/web/.well-known/apple-app-site-association b/Frontend/web/.well-known/apple-app-site-association new file mode 100644 index 00000000..2fa7acc2 --- /dev/null +++ b/Frontend/web/.well-known/apple-app-site-association @@ -0,0 +1,25 @@ +{ + "applinks": { + "apps": [], + "details": [ + { + "appIDs": [ + "B88N73P46W.za.co.mzansiinnovationhub.mih" + ], + "paths": [ + "*" + ], + "components": [ + { + "/": "/*" + } + ] + } + ] + }, + "webcredentials": { + "apps": [ + "B88N73P46W.za.co.mzansiinnovationhub.mih" + ] + } +} \ No newline at end of file diff --git a/Frontend/web/.well-known/assetlinks.json b/Frontend/web/.well-known/assetlinks.json new file mode 100644 index 00000000..a960aa85 --- /dev/null +++ b/Frontend/web/.well-known/assetlinks.json @@ -0,0 +1,14 @@ +[ + { + "relation": [ + "delegate_permission/common.handle_all_urls" + ], + "target": { + "namespace": "android_app", + "package_name": "za.co.mzansiinnovationhub.mih", + "sha256_cert_fingerprints": [ + "51:4C:93:E3:11:85:C5:7A:46:A9:C4:88:B7:E4:96:7F:41:11:80:4C:A4:2D:2D:55:30:C2:0B:A6:20:25:1E:98" + ] + } + } +] \ No newline at end of file diff --git a/Frontend/web/index.html b/Frontend/web/index.html index 972a48a0..724333da 100644 --- a/Frontend/web/index.html +++ b/Frontend/web/index.html @@ -1,14 +1,10 @@ - - - - + - + @@ -20,15 +16,14 @@ - MIH App: Mzansi Innovation Hub - All-in-One Super App for Business & Personal Life + MIH App: Mzansi Innovation Hub - All-in-One Super App for Business & Personal Life - - + @@ -70,74 +65,8 @@ var dartPdfJsBaseUrl = "https://cdnjs.cloudflare.com/ajax/libs/pdf.js/3.2.146/"; --> - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +