73 Commits

Author SHA1 Message Date
763c4cdb54 QOL: Build number update to 103 2025-11-05 10:04:30 +02:00
b37f0f71db BUG: Get patient data from tile 2025-11-05 09:59:58 +02:00
8ceb443964 QOL: Update Mzansi AI System PRompt 2025-11-05 09:44:54 +02:00
a87e52d22c NFC deep linking 2025-11-04 12:29:55 +02:00
46c281d288 QOL: Update build to 101 2025-11-04 12:07:47 +02:00
5289cf8511 favourite business fix 2025-11-04 12:07:00 +02:00
22ae804c2d IOS encryption compliance 2025-11-04 12:06:49 +02:00
1a7293fc12 deeplinking fix 2025-11-04 11:43:47 +02:00
e318e03805 QOL: Update build to 100 2025-11-04 11:36:04 +02:00
11b6ec9edb BUG: Update Appointment & Clear Coltrollers 2025-11-04 11:34:28 +02:00
2a7e3e17ce BUG: Bookmarked businesses data load 2025-11-04 11:00:29 +02:00
9cbdc849b1 BUG: back Nav from favourite business selection 2025-11-04 10:17:38 +02:00
0cabe11ab7 BUG: Business Profile Tool Transitions 2025-11-04 10:15:34 +02:00
a561f4fa5f BUG: Set up patient flow 2025-11-03 19:28:52 +02:00
429e91b638 QOL: update guide 2025-11-03 13:12:16 +02:00
c0d152002c QOL: Change reset game to start new game 2025-11-03 11:30:46 +02:00
1329c8aba4 BUG: MIH Ad Display Strategy 2025-11-03 11:27:44 +02:00
52f9eb7ba6 BUG: Add card refresh list 2025-11-03 10:18:29 +02:00
bcff545dd7 BUG: Menue showing in claims in personal mode 2025-11-03 09:25:16 +02:00
6a5b4f7f4b QOL: Location compliance update for app store 2025-11-03 09:20:14 +02:00
yaso-meth
b2b9d8f046 Merge pull request #260 from yaso-meth/V.1.2.2
V.1.2.2
2025-10-31 13:16:34 +02:00
yaso-meth
4c39e9163b Merge branch 'main' into V.1.2.2 2025-10-31 13:15:41 +02:00
yaso-meth
6541ac883f Merge pull request #259 from yaso-meth/V.1.2.1
Add Meta Add Mediation & Build Update
2025-10-31 13:14:47 +02:00
ffe9f6e9fb NEW: Version Update 2025-10-31 12:53:37 +02:00
8e6f3d7d45 Android Config Changes 2025-10-31 12:52:58 +02:00
abd56d5a14 Clean up 2025-10-31 12:18:13 +02:00
cb25b932ba NEW: Patient Manager Provider Setup pt4 2025-10-31 11:55:49 +02:00
771d809ce2 NEW: MIH MineSweeper Package pt4 2025-10-31 11:55:31 +02:00
d6f1629485 NEW: MIH MineSweeper Package Pt 3 2025-10-30 11:58:46 +02:00
39a42048c2 NEW: Patient Manager Provider Setup pt3 2025-10-29 15:43:05 +02:00
99d0fa4aa8 NEW: Patient Manager Provider Setup pt2 2025-10-29 13:59:09 +02:00
79ed959b42 BUG: Dropdown search text disabled 2025-10-29 13:17:05 +02:00
23c3cf4173 NEW: MIH MineSweeper Package pt2 2025-10-29 13:06:55 +02:00
f548db7d82 NEW: Patient Manager Provider Setup pt1 2025-10-27 18:46:20 +02:00
fd2f3a2138 BUG: Fix MIH Logo press on app drawer 2025-10-24 13:11:42 +02:00
1fe817919f QOL: Fix New User Setup flow 2025-10-24 13:00:19 +02:00
656e1cd3d7 QOL: reset providers on signout and signin 2025-10-24 12:59:11 +02:00
a9ea3594b9 QOL: Add reset function to providers 2025-10-24 12:58:29 +02:00
7de2cb7b36 QOL: Update Alert title size 2025-10-24 12:57:49 +02:00
ac22e50eca Change patient profile folder to patient manager 2025-10-23 11:01:39 +02:00
9bd039ca25 NEW: Mzansi Directory Provider Setup 2025-10-22 14:43:01 +02:00
b0d38b4b11 NEW: MIH Access Controlls Provider Setup 2025-10-21 15:42:38 +02:00
926b749fa8 NEW: MIH Calendar Provider Setup 2025-10-21 13:00:52 +02:00
b2ed1e0b51 NEW: About MIH Provider Setup pt2 2025-10-21 10:46:50 +02:00
3dc9ce30e6 NEW: MIH Calc Provider Setup pt2 2025-10-21 10:45:15 +02:00
91241aa399 NEW: Mzansi AI Provider Setup 2025-10-21 10:40:40 +02:00
c79904d132 NEW: complete provider mzansi wallet 2025-10-21 10:22:20 +02:00
15106d0a00 NEW: fix home nav 2025-10-21 09:53:37 +02:00
2e69e1dd92 NEW: MIH Home & Mzansi Profile Provider Setup pt 2 done 2025-10-20 16:41:24 +02:00
c89932755f BUG: Tab movement on password fields 2025-10-20 11:18:06 +02:00
540e13dfe0 mine sweeper pt2 2025-10-17 08:24:23 +02:00
d51603ff5d NEW: MIH Home & Mzansi Profile Provider Setup pt 1 2025-10-16 10:16:18 +02:00
553d22dd6b BUG: Package Auth Loop 2025-10-16 09:59:52 +02:00
5f5107ee99 QOL: Add Long Press to mih button 2025-10-16 09:46:02 +02:00
6ecce1e9ff NEW: MIH MineSweeper Package pt1 2025-10-16 09:45:17 +02:00
22d8c64994 QOL: Change Users to People in About MIH 2025-10-16 09:03:02 +02:00
ebd78eb72b NEW: MIH Authentication Provider Setup 2025-10-13 11:14:11 +02:00
f828ba1786 NEW: About MIH Provider Setup 2025-10-13 10:45:30 +02:00
bbadc58ab8 NEW: MIH Calculator Provider Setup 2025-10-08 15:06:04 +02:00
a1b7a3ef28 NEW: MIH Banner Ads Provider Set Up 2025-10-08 14:43:03 +02:00
7373a1b8cb NEW: Mzansi Wallet Provider Setup 2025-10-08 13:35:47 +02:00
0edbfadc90 NEW: Import & Set Up Provider 2025-10-08 12:53:09 +02:00
ef479b633d NEW: Add Test Device to main dev 2025-10-08 12:51:52 +02:00
081e7d5533 BUG: Special Chars in Business Type 2025-10-08 09:40:34 +02:00
18e8217ce1 NEW: Engen Card Added to Mzansi Wallet 2025-10-07 11:45:37 +02:00
cadd51535e Add Meta Ads SDK 2025-10-07 10:38:26 +02:00
ba394e7fea BUG: Business QR Code Picture Display 2025-10-07 10:38:04 +02:00
04c92804b8 BUG: Fix blank screen on load 2025-10-07 09:49:18 +02:00
yaso-meth
a2d1bebca1 Merge pull request #258 from yaso-meth/V.1.2.1
app sign pt2
2025-10-03 09:49:37 +02:00
yaso-meth
1a448572ea Merge pull request #257 from yaso-meth/V.1.2.1
app signing
2025-10-02 15:35:25 +02:00
yaso-meth
04b247aa99 Merge pull request #256 from yaso-meth/V.1.2.1
BUG: Mzansi Wallet Card Scanner
2025-10-02 13:55:34 +02:00
yaso-meth
aa0d756979 Merge pull request #255 from yaso-meth/V.1.2.1
fix docker compose alignment
2025-10-01 09:27:13 +02:00
yaso-meth
16f50f826b Merge pull request #254 from yaso-meth/V.1.2.1
V.1.2.1 First Push
2025-10-01 09:22:45 +02:00
179 changed files with 15343 additions and 11662 deletions

BIN
.DS_Store vendored

Binary file not shown.

View File

@@ -55,6 +55,11 @@ android {
// TODO: Add your own signing config for the release build. // TODO: Add your own signing config for the release build.
// Signing with the debug keys for now, so `flutter run --release` works. // Signing with the debug keys for now, so `flutter run --release` works.
signingConfig = signingConfigs.getByName("release") signingConfig = signingConfigs.getByName("release")
isMinifyEnabled = true
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
} }
} }
} }

View File

@@ -0,0 +1,5 @@
# R8/ProGuard rules to prevent removal of necessary Facebook Infer annotations
-keep class com.facebook.infer.annotation.** { *; }
-keep interface com.facebook.infer.annotation.** { *; }
-dontwarn com.facebook.infer.annotation.Nullsafe$Mode
-dontwarn com.facebook.infer.annotation.Nullsafe

View File

@@ -19,7 +19,8 @@
<application <application
android:label="MIH" android:label="MIH"
android:name="${applicationName}" android:name="${applicationName}"
android:icon="@mipmap/launcher_icon"> android:icon="@mipmap/launcher_icon"
android:enableOnBackInvokedCallback="true">
<activity <activity
android:name=".MainActivity" android:name=".MainActivity"
android:exported="true" android:exported="true"

View File

@@ -1,5 +1,5 @@
package za.co.mzansiinnovationhub.mih package za.co.mzansiinnovationhub.mih
import io.flutter.embedding.android.FlutterActivity import io.flutter.embedding.android.FlutterFragmentActivity
class MainActivity : FlutterActivity() class MainActivity : FlutterFragmentActivity()

View File

@@ -34,6 +34,7 @@ PODS:
- DKPhotoGallery/Resource (0.0.19): - DKPhotoGallery/Resource (0.0.19):
- SDWebImage - SDWebImage
- SwiftyGif - SwiftyGif
- FBAudienceNetwork (6.20.1)
- file_picker (0.0.1): - file_picker (0.0.1):
- DKImagePickerController/PhotoGallery - DKImagePickerController/PhotoGallery
- Flutter - Flutter
@@ -49,12 +50,18 @@ PODS:
- geolocator_apple (1.2.0): - geolocator_apple (1.2.0):
- Flutter - Flutter
- FlutterMacOS - FlutterMacOS
- gma_mediation_meta (1.4.1):
- Flutter
- GoogleMobileAdsMediationFacebook (~> 6.20.1.0)
- Google-Mobile-Ads-SDK (12.2.0): - Google-Mobile-Ads-SDK (12.2.0):
- GoogleUserMessagingPlatform (>= 1.1) - GoogleUserMessagingPlatform (>= 1.1)
- google_mobile_ads (6.0.0): - google_mobile_ads (6.0.0):
- Flutter - Flutter
- Google-Mobile-Ads-SDK (~> 12.2.0) - Google-Mobile-Ads-SDK (~> 12.2.0)
- webview_flutter_wkwebview - webview_flutter_wkwebview
- GoogleMobileAdsMediationFacebook (6.20.1.0):
- FBAudienceNetwork (= 6.20.1)
- Google-Mobile-Ads-SDK (~> 12.0)
- GoogleUserMessagingPlatform (3.0.0) - GoogleUserMessagingPlatform (3.0.0)
- local_auth_darwin (0.0.1): - local_auth_darwin (0.0.1):
- Flutter - Flutter
@@ -101,6 +108,7 @@ DEPENDENCIES:
- flutter_native_splash (from `.symlinks/plugins/flutter_native_splash/ios`) - flutter_native_splash (from `.symlinks/plugins/flutter_native_splash/ios`)
- flutter_tts (from `.symlinks/plugins/flutter_tts/ios`) - flutter_tts (from `.symlinks/plugins/flutter_tts/ios`)
- geolocator_apple (from `.symlinks/plugins/geolocator_apple/darwin`) - geolocator_apple (from `.symlinks/plugins/geolocator_apple/darwin`)
- gma_mediation_meta (from `.symlinks/plugins/gma_mediation_meta/ios`)
- google_mobile_ads (from `.symlinks/plugins/google_mobile_ads/ios`) - google_mobile_ads (from `.symlinks/plugins/google_mobile_ads/ios`)
- local_auth_darwin (from `.symlinks/plugins/local_auth_darwin/darwin`) - local_auth_darwin (from `.symlinks/plugins/local_auth_darwin/darwin`)
- mobile_scanner (from `.symlinks/plugins/mobile_scanner/darwin`) - mobile_scanner (from `.symlinks/plugins/mobile_scanner/darwin`)
@@ -119,7 +127,9 @@ SPEC REPOS:
trunk: trunk:
- DKImagePickerController - DKImagePickerController
- DKPhotoGallery - DKPhotoGallery
- FBAudienceNetwork
- Google-Mobile-Ads-SDK - Google-Mobile-Ads-SDK
- GoogleMobileAdsMediationFacebook
- GoogleUserMessagingPlatform - GoogleUserMessagingPlatform
- SDWebImage - SDWebImage
- SwiftyGif - SwiftyGif
@@ -143,6 +153,8 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/flutter_tts/ios" :path: ".symlinks/plugins/flutter_tts/ios"
geolocator_apple: geolocator_apple:
:path: ".symlinks/plugins/geolocator_apple/darwin" :path: ".symlinks/plugins/geolocator_apple/darwin"
gma_mediation_meta:
:path: ".symlinks/plugins/gma_mediation_meta/ios"
google_mobile_ads: google_mobile_ads:
:path: ".symlinks/plugins/google_mobile_ads/ios" :path: ".symlinks/plugins/google_mobile_ads/ios"
local_auth_darwin: local_auth_darwin:
@@ -175,6 +187,7 @@ SPEC CHECKSUMS:
device_info_plus: 21fcca2080fbcd348be798aa36c3e5ed849eefbe device_info_plus: 21fcca2080fbcd348be798aa36c3e5ed849eefbe
DKImagePickerController: 946cec48c7873164274ecc4624d19e3da4c1ef3c DKImagePickerController: 946cec48c7873164274ecc4624d19e3da4c1ef3c
DKPhotoGallery: b3834fecb755ee09a593d7c9e389d8b5d6deed60 DKPhotoGallery: b3834fecb755ee09a593d7c9e389d8b5d6deed60
FBAudienceNetwork: 08e86d63a05b3a5a59414af12e4af8d756943c80
file_picker: a0560bc09d61de87f12d246fc47d2119e6ef37be file_picker: a0560bc09d61de87f12d246fc47d2119e6ef37be
file_saver: 6cdbcddd690cb02b0c1a0c225b37cd805c2bf8b6 file_saver: 6cdbcddd690cb02b0c1a0c225b37cd805c2bf8b6
fl_downloader: dc99aa8dd303f862cccb830087f37acc9b0156ee fl_downloader: dc99aa8dd303f862cccb830087f37acc9b0156ee
@@ -182,8 +195,10 @@ SPEC CHECKSUMS:
flutter_native_splash: c32d145d68aeda5502d5f543ee38c192065986cf flutter_native_splash: c32d145d68aeda5502d5f543ee38c192065986cf
flutter_tts: b88dbc8655d3dc961bc4a796e4e16a4cc1795833 flutter_tts: b88dbc8655d3dc961bc4a796e4e16a4cc1795833
geolocator_apple: ab36aa0e8b7d7a2d7639b3b4e48308394e8cef5e geolocator_apple: ab36aa0e8b7d7a2d7639b3b4e48308394e8cef5e
gma_mediation_meta: 44defcf3b61414cdca65c0f897360e31b9332a09
Google-Mobile-Ads-SDK: 1dfb0c3cb46c7e2b00b0f4de74a1e06d9ea25d67 Google-Mobile-Ads-SDK: 1dfb0c3cb46c7e2b00b0f4de74a1e06d9ea25d67
google_mobile_ads: 535223588a6791b7a3cc3513a1bc7b89d12f3e62 google_mobile_ads: 535223588a6791b7a3cc3513a1bc7b89d12f3e62
GoogleMobileAdsMediationFacebook: b11a92ae3bfdae19853b882252b7e62791c18162
GoogleUserMessagingPlatform: f8d0cdad3ca835406755d0a69aa634f00e76d576 GoogleUserMessagingPlatform: f8d0cdad3ca835406755d0a69aa634f00e76d576
local_auth_darwin: 553ce4f9b16d3fdfeafce9cf042e7c9f77c1c391 local_auth_darwin: 553ce4f9b16d3fdfeafce9cf042e7c9f77c1c391
mobile_scanner: 9157936403f5a0644ca3779a38ff8404c5434a93 mobile_scanner: 9157936403f5a0644ca3779a38ff8404c5434a93

View File

@@ -2,6 +2,19 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0"> <plist version="1.0">
<dict> <dict>
<key>ITSAppUsesNonExemptEncryption</key>
<false/>
<key>SKAdNetworkItems</key>
<array>
<dict>
<key>SKAdNetworkIdentifier</key>
<string>v9wttpbfk9.skadnetwork</string>
</dict>
<dict>
<key>SKAdNetworkIdentifier</key>
<string>n38lu8286q.skadnetwork</string>
</dict>
</array>
<key>GADApplicationIdentifier</key> <key>GADApplicationIdentifier</key>
<string>ca-app-pub-4781880856775334~6935644635</string> <string>ca-app-pub-4781880856775334~6935644635</string>
<key>CADisableMinimumFrameDurationOnPhone</key> <key>CADisableMinimumFrameDurationOnPhone</key>
@@ -41,6 +54,8 @@
<string>Why is my app authenticating using face id?</string> <string>Why is my app authenticating using face id?</string>
<key>NSLocationWhenInUseUsageDescription</key> <key>NSLocationWhenInUseUsageDescription</key>
<string>This app needs access to location when open.</string> <string>This app needs access to location when open.</string>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>This app needs access to your location at all times to provide [Explain your specific, complete reason here, e.g., real-time tracking, background updates, etc.].</string>
<key>NSPhotoLibraryUsageDescription</key> <key>NSPhotoLibraryUsageDescription</key>
<string>This app needs to access your photo library to select images.</string> <string>This app needs to access your photo library to select images.</string>
<key>NSDownloadsFolderUsageDescription</key> <key>NSDownloadsFolderUsageDescription</key>

View File

@@ -1,6 +1,19 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart'; import 'package:go_router/go_router.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_providers/about_mih_provider.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_providers/mih_access_controlls_provider.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_providers/mih_authentication_provider.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_providers/mih_banner_ad_provider.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_providers/mih_calculator_provider.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_providers/mih_calendar_provider.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_providers/mih_mine_sweeper_provider.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_providers/mzansi_ai_provider.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_providers/mzansi_directory_provider.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_providers/mzansi_profile_provider.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_providers/mzansi_wallet_provider.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_providers/patient_manager_provider.dart';
import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart'; import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart';
import 'package:provider/provider.dart';
import 'package:upgrader/upgrader.dart'; import 'package:upgrader/upgrader.dart';
import 'mih_config/mih_env.dart'; import 'mih_config/mih_env.dart';
import 'mih_config/mih_theme.dart'; import 'mih_config/mih_theme.dart';
@@ -66,7 +79,46 @@ class _MzansiInnovationHubState extends State<MzansiInnovationHub> {
double width = MediaQuery.sizeOf(context).width; double width = MediaQuery.sizeOf(context).width;
theme.setScreenType(width); theme.setScreenType(width);
precacheImage(theme.loadingImage(), context); precacheImage(theme.loadingImage(), context);
return MaterialApp.router( return MultiProvider(
providers: [
ChangeNotifierProvider(
create: (context) => MihAuthenticationProvider(),
),
ChangeNotifierProvider(
create: (context) => MzansiProfileProvider(),
),
ChangeNotifierProvider(
create: (context) => MzansiWalletProvider(),
),
ChangeNotifierProvider(
create: (context) => MzansiAiProvider(),
),
ChangeNotifierProvider(
create: (context) => MzansiDirectoryProvider(),
),
ChangeNotifierProvider(
create: (context) => MihBannerAdProvider(),
),
ChangeNotifierProvider(
create: (context) => MihCalculatorProvider(),
),
ChangeNotifierProvider(
create: (context) => MihAccessControllsProvider(),
),
ChangeNotifierProvider(
create: (context) => MihCalendarProvider(),
),
ChangeNotifierProvider(
create: (context) => AboutMihProvider(),
),
ChangeNotifierProvider(
create: (context) => MihMineSweeperProvider(),
),
ChangeNotifierProvider(
create: (context) => PatientManagerProvider(),
),
],
child: MaterialApp.router(
title: getTitle(), title: getTitle(),
themeMode: ThemeMode.dark, themeMode: ThemeMode.dark,
theme: theme.getThemeData(), theme: theme.getThemeData(),
@@ -74,11 +126,19 @@ class _MzansiInnovationHubState extends State<MzansiInnovationHub> {
debugShowCheckedModeBanner: false, debugShowCheckedModeBanner: false,
routerConfig: widget.router, routerConfig: widget.router,
builder: (context, child) { builder: (context, child) {
if (child == null) {
return const Scaffold(
body: Center(
child: CircularProgressIndicator(),
),
);
}
return UpgradeAlert( return UpgradeAlert(
navigatorKey: widget.router.routerDelegate.navigatorKey, navigatorKey: widget.router.routerDelegate.navigatorKey,
child: child ?? const Text('Upgrade Alert'), child: child,
); );
}, },
),
); );
} }
} }

View File

@@ -20,6 +20,12 @@ void main() async {
apiBasePath: "/auth", apiBasePath: "/auth",
); );
if (!kIsWeb) { if (!kIsWeb) {
const List<String> testDeviceIds = ['733d4c68-9b54-453a-9622-2df407310f40'];
MobileAds.instance.updateRequestConfiguration(
RequestConfiguration(
testDeviceIds: testDeviceIds,
),
);
MobileAds.instance.initialize(); MobileAds.instance.initialize();
} else { } else {
usePathUrlStrategy(); usePathUrlStrategy();
@@ -29,5 +35,7 @@ void main() async {
}); });
final GoRouter appRouter = MihGoRouter().mihRouter; final GoRouter appRouter = MihGoRouter().mihRouter;
FlutterNativeSplash.remove(); FlutterNativeSplash.remove();
runApp(MzansiInnovationHub(router: appRouter,)); runApp(MzansiInnovationHub(
router: appRouter,
));
} }

View File

@@ -0,0 +1,42 @@
class MinesweeperPlayerScore {
String app_id;
String username;
String proPicUrl;
String difficulty;
String game_time;
double game_score;
DateTime played_date;
MinesweeperPlayerScore({
required this.app_id,
required this.username,
required this.proPicUrl,
required this.difficulty,
required this.game_time,
required this.game_score,
required this.played_date,
});
factory MinesweeperPlayerScore.fromJson(Map<String, dynamic> json) {
return MinesweeperPlayerScore(
app_id: json['app_id'],
username: json['username'],
proPicUrl: json['proPicUrl'],
difficulty: json['difficulty'],
game_time: json['game_time'],
game_score: json['game_score'],
played_date: DateTime.parse(json['played_date']),
);
}
Map<String, dynamic> toJson() {
return {
'app_id': app_id,
'username': username,
'proPicUrl': proPicUrl,
'difficulty': difficulty,
'game_time': game_score,
'played_date': played_date.toIso8601String(),
};
}
}

View File

@@ -396,7 +396,6 @@ class _PackageToolOneState extends State<PackageToolOne> {
return widget.business != null return widget.business != null
? MihBusinessProfilePreview( ? MihBusinessProfilePreview(
business: widget.business!, business: widget.business!,
myLocation: myLocation,
) )
: Text("NoBusiness Data"); : Text("NoBusiness Data");
} }
@@ -424,7 +423,7 @@ class _PackageToolOneState extends State<PackageToolOne> {
"rating", "rating",
"mission_vision", "mission_vision",
), ),
startUpSearch: '', // startUpSearch: '',
width: 300, width: 300,
).redacted( ).redacted(
context: context, context: context,

View File

@@ -1,10 +1,10 @@
@font-face { @font-face {
font-family: 'Mih_Icons'; font-family: 'icomoon';
src: url('fonts/Mih_Icons.eot?blbuxz'); src: url('fonts/icomoon.eot?8flwgj');
src: url('fonts/Mih_Icons.eot?blbuxz#iefix') format('embedded-opentype'), src: url('fonts/icomoon.eot?8flwgj#iefix') format('embedded-opentype'),
url('fonts/Mih_Icons.ttf?blbuxz') format('truetype'), url('fonts/icomoon.ttf?8flwgj') format('truetype'),
url('fonts/Mih_Icons.woff?blbuxz') format('woff'), url('fonts/icomoon.woff?8flwgj') format('woff'),
url('fonts/Mih_Icons.svg?blbuxz#Mih_Icons') format('svg'); url('fonts/icomoon.svg?8flwgj#icomoon') format('svg');
font-weight: normal; font-weight: normal;
font-style: normal; font-style: normal;
font-display: block; font-display: block;
@@ -13,7 +13,7 @@
[class^="icon-"], [class^="icon-"],
[class*=" icon-"] { [class*=" icon-"] {
/* use !important to prevent issues with browser extensions that change fonts */ /* use !important to prevent issues with browser extensions that change fonts */
font-family: 'Mih_Icons' !important; font-family: 'icomoon' !important;
/* speak: never; */ /* speak: never; */
font-style: normal; font-style: normal;
font-weight: normal; font-weight: normal;
@@ -26,70 +26,74 @@
-moz-osx-font-smoothing: grayscale; -moz-osx-font-smoothing: grayscale;
} }
.icon-mzansi_directory:before { .icon-mine_sweeper:before {
content: "\e900"; content: "\e900";
} }
.icon-personal_profile:before { .icon-mzansi_directory:before {
content: "\e901"; content: "\e901";
} }
.icon-about_mih:before { .icon-personal_profile:before {
content: "\e902"; content: "\e902";
} }
.icon-access_control:before { .icon-about_mih:before {
content: "\e903"; content: "\e903";
} }
.icon-business_profile:before { .icon-access_control:before {
content: "\e904"; content: "\e904";
} }
.icon-business_setup:before { .icon-business_profile:before {
content: "\e905"; content: "\e905";
} }
.icon-i_dont_know:before { .icon-business_setup:before {
content: "\e906"; content: "\e906";
} }
.icon-mih_logo:before { .icon-calculator:before {
content: "\e907"; content: "\e907";
} }
.icon-mih_ring:before { .icon-calendar:before {
content: "\e908"; content: "\e908";
} }
.icon-mzansi_ai:before { .icon-i_dont_know:before {
content: "\e909"; content: "\e909";
} }
.icon-mzansi_wallet:before { .icon-mih_logo:before {
content: "\e90a"; content: "\e90a";
} }
.icon-notifications:before { .icon-mih_ring:before {
content: "\e90b"; content: "\e90b";
} }
.icon-patient_manager:before { .icon-mzansi_ai:before {
content: "\e90c"; content: "\e90c";
} }
.icon-patient_profile:before { .icon-mzansi_wallet:before {
content: "\e90d"; content: "\e90d";
} }
.icon-profile_setup:before { .icon-notifications:before {
content: "\e90e"; content: "\e90e";
} }
.icon-calculator:before { .icon-patient_manager:before {
content: "\e940"; content: "\e90f";
} }
.icon-calendar:before { .icon-patient_profile:before {
content: "\e953"; content: "\e910";
}
.icon-profile_setup:before {
content: "\e911";
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

View File

@@ -1,6 +1,8 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:google_mobile_ads/google_mobile_ads.dart'; import 'package:google_mobile_ads/google_mobile_ads.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_providers/mih_banner_ad_provider.dart';
import 'package:mzansi_innovation_hub/mih_config/mih_env.dart'; import 'package:mzansi_innovation_hub/mih_config/mih_env.dart';
import 'package:provider/provider.dart';
class MihBannerAd extends StatefulWidget { class MihBannerAd extends StatefulWidget {
const MihBannerAd({super.key}); const MihBannerAd({super.key});
@@ -10,66 +12,44 @@ class MihBannerAd extends StatefulWidget {
} }
class _MihBannerAdState extends State<MihBannerAd> { class _MihBannerAdState extends State<MihBannerAd> {
BannerAd? _bannerAd;
bool _isBannerAdLoaded = false;
final adUnitId = AppEnviroment.bannerAdUnitId;
String errorMessage = '';
void _loadBannerAd() {
_bannerAd = BannerAd(
adUnitId: adUnitId,
request: const AdRequest(),
size: AdSize.banner,
listener: BannerAdListener(
onAdLoaded: (ad) {
debugPrint('$ad loaded.');
setState(() {
_isBannerAdLoaded = true;
});
},
onAdFailedToLoad: (ad, err) {
debugPrint('BannerAd failed to load: $err');
setState(() {
errorMessage =
'Failed to load ad- Message: ${err.message} Code :${err.code}';
});
ad.dispose(); // Dispose the ad to free resources
},
onAdOpened: (Ad ad) => debugPrint('$ad opened.'),
onAdClosed: (Ad ad) => debugPrint('$ad closed.'),
onAdImpression: (Ad ad) => debugPrint('$ad impression.'),
),
);
_bannerAd!.load();
}
@override @override
void dispose() { void dispose() {
_bannerAd?.dispose(); // Dispose the ad when the widget is removed
super.dispose(); super.dispose();
} }
@override @override
void initState() { void initState() {
super.initState(); super.initState();
_loadBannerAd(); MihBannerAdProvider adProvider = context.read<MihBannerAdProvider>();
WidgetsBinding.instance.addPostFrameCallback((_) {
adProvider.reset();
adProvider.loadBannerAd();
});
} }
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Consumer<MihBannerAdProvider>(
builder: (context, bannerAdProvider, child) {
if (!bannerAdProvider.isBannerAdLoaded) {
return SizedBox();
}
return Column( return Column(
children: [ children: [
_bannerAd != null && _isBannerAdLoaded bannerAdProvider.bannerAd != null &&
bannerAdProvider.isBannerAdLoaded
? SizedBox( ? SizedBox(
width: _bannerAd!.size.width.toDouble(), width: bannerAdProvider.bannerAd!.size.width.toDouble(),
height: _bannerAd!.size.height.toDouble(), height: bannerAdProvider.bannerAd!.size.height.toDouble(),
child: AdWidget(ad: _bannerAd!)) child: AdWidget(ad: bannerAdProvider.bannerAd!))
: SizedBox( : SizedBox(
child: child: Text(AppEnviroment.getEnv() == "Dev"
Text(AppEnviroment.getEnv() == "Dev" ? errorMessage : ""), ? bannerAdProvider.errorMessage
: ""),
), ),
], ],
); );
},
);
} }
} }

View File

@@ -4,17 +4,17 @@ 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_objects/business.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_circle_avatar.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_circle_avatar.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_icons.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_providers/mzansi_directory_provider.dart';
import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart'; import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_file_services.dart'; import 'package:mzansi_innovation_hub/mih_services/mih_file_services.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_location_services.dart'; import 'package:mzansi_innovation_hub/mih_services/mih_location_services.dart';
import 'package:provider/provider.dart';
class MihBusinessProfilePreview extends StatefulWidget { class MihBusinessProfilePreview extends StatefulWidget {
final Business business; final Business business;
final String? myLocation;
const MihBusinessProfilePreview({ const MihBusinessProfilePreview({
super.key, super.key,
required this.business, required this.business,
required this.myLocation,
}); });
@override @override
@@ -26,10 +26,10 @@ class _MihBusinessProfilePreviewState extends State<MihBusinessProfilePreview> {
late Future<String> futureImageUrl; late Future<String> futureImageUrl;
PlatformFile? file; PlatformFile? file;
String calculateDistance() { String calculateDistance(MzansiDirectoryProvider directoryProvider) {
try { try {
double distanceInKm = MIHLocationAPI().getDistanceInMeaters( double distanceInKm = MIHLocationAPI().getDistanceInMeaters(
widget.myLocation!, widget.business.gps_location) / directoryProvider.userLocation, widget.business.gps_location) /
1000; 1000;
return "${distanceInKm.toStringAsFixed(2)} km"; return "${distanceInKm.toStringAsFixed(2)} km";
} catch (error) { } catch (error) {
@@ -41,17 +41,19 @@ class _MihBusinessProfilePreviewState extends State<MihBusinessProfilePreview> {
@override @override
void initState() { void initState() {
super.initState(); super.initState();
futureImageUrl =
MihFileApi.getMinioFileUrl(widget.business.logo_path, context);
} }
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
double profilePictureWidth = 60; double profilePictureWidth = 60;
return Consumer<MzansiDirectoryProvider>(
builder: (BuildContext context, MzansiDirectoryProvider directoryProvider,
Widget? child) {
return Row( return Row(
children: [ children: [
FutureBuilder( FutureBuilder(
future: futureImageUrl, future: MihFileApi.getMinioFileUrl(
widget.business.logo_path, context),
builder: (context, asyncSnapshot) { builder: (context, asyncSnapshot) {
if (asyncSnapshot.connectionState == ConnectionState.done && if (asyncSnapshot.connectionState == ConnectionState.done &&
asyncSnapshot.hasData) { asyncSnapshot.hasData) {
@@ -63,9 +65,11 @@ class _MihBusinessProfilePreviewState extends State<MihBusinessProfilePreview> {
fileNameController: TextEditingController(), fileNameController: TextEditingController(),
userSelectedfile: file, userSelectedfile: file,
frameColor: MihColors.getSecondaryColor( frameColor: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"), MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
backgroundColor: MihColors.getPrimaryColor( backgroundColor: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"), MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
onChange: () {}, onChange: () {},
); );
} else { } else {
@@ -73,7 +77,8 @@ class _MihBusinessProfilePreviewState extends State<MihBusinessProfilePreview> {
MihIcons.iDontKnow, MihIcons.iDontKnow,
size: profilePictureWidth, size: profilePictureWidth,
color: MihColors.getSecondaryColor( color: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"), MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
); );
} }
} else { } else {
@@ -81,7 +86,8 @@ class _MihBusinessProfilePreviewState extends State<MihBusinessProfilePreview> {
MihIcons.mihRing, MihIcons.mihRing,
size: profilePictureWidth, size: profilePictureWidth,
color: MihColors.getSecondaryColor( color: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"), MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
); );
} }
}), }),
@@ -104,8 +110,8 @@ class _MihBusinessProfilePreviewState extends State<MihBusinessProfilePreview> {
), ),
), ),
Text( Text(
widget.myLocation != null || widget.myLocation!.isEmpty directoryProvider.userPosition != null
? calculateDistance() ? calculateDistance(directoryProvider)
: "0.00 km", : "0.00 km",
style: TextStyle( style: TextStyle(
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
@@ -116,5 +122,7 @@ class _MihBusinessProfilePreviewState extends State<MihBusinessProfilePreview> {
) )
], ],
); );
},
);
} }
} }

View File

@@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
class MihButton extends StatelessWidget { class MihButton extends StatelessWidget {
final void Function()? onPressed; final void Function()? onPressed;
final void Function()? onLongPressed;
final Color buttonColor; final Color buttonColor;
final double? width; final double? width;
final double? height; final double? height;
@@ -12,6 +13,7 @@ class MihButton extends StatelessWidget {
const MihButton({ const MihButton({
super.key, super.key,
required this.onPressed, required this.onPressed,
this.onLongPressed,
required this.buttonColor, required this.buttonColor,
this.width, this.width,
this.height, this.height,
@@ -49,6 +51,7 @@ class MihButton extends StatelessWidget {
highlightColor: rippleColor.withValues(alpha: 0.2), highlightColor: rippleColor.withValues(alpha: 0.2),
hoverColor: rippleColor.withValues(alpha: 0.3), hoverColor: rippleColor.withValues(alpha: 0.3),
onTap: onPressed, onTap: onPressed,
onLongPress: onLongPressed,
child: Container( child: Container(
width: width, width: width,
height: height, height: height,

View File

@@ -1,6 +1,9 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:ken_logger/ken_logger.dart';
import 'package:mzansi_innovation_hub/main.dart'; import 'package:mzansi_innovation_hub/main.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_providers/mih_calendar_provider.dart';
import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart'; import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart';
import 'package:provider/provider.dart';
import 'package:table_calendar/table_calendar.dart'; import 'package:table_calendar/table_calendar.dart';
class MIHCalendar extends StatefulWidget { class MIHCalendar extends StatefulWidget {
@@ -19,16 +22,29 @@ class MIHCalendar extends StatefulWidget {
} }
class _MIHCalendarState extends State<MIHCalendar> { class _MIHCalendarState extends State<MIHCalendar> {
DateTime selectedDay = DateTime.now(); late DateTime selectedDay;
CalendarFormat _calendarFormat = CalendarFormat.week; CalendarFormat _calendarFormat = CalendarFormat.week;
void onDaySelected(DateTime day, DateTime focusedDay) { void onDaySelected(DateTime day, DateTime focusedDay) {
KenLogger.success("Selected Day: $day");
setState(() { setState(() {
selectedDay = day; selectedDay = day;
}); });
widget.setDate(selectedDay.toString().split(" ")[0]); widget.setDate(selectedDay.toString().split(" ")[0]);
} }
@override
void initState() {
super.initState();
MihCalendarProvider mihCalendarProvider =
context.read<MihCalendarProvider>();
if (mihCalendarProvider.selectedDay.isNotEmpty) {
selectedDay = DateTime.parse(mihCalendarProvider.selectedDay);
} else {
selectedDay = DateTime.now();
}
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return SizedBox( return SizedBox(

View File

@@ -10,7 +10,7 @@ class MihCircleAvatar extends StatefulWidget {
final ImageProvider<Object>? imageFile; final ImageProvider<Object>? imageFile;
final double width; final double width;
final bool editable; final bool editable;
final TextEditingController fileNameController; final TextEditingController? fileNameController;
final onChange; final onChange;
final PlatformFile? userSelectedfile; final PlatformFile? userSelectedfile;
final Color frameColor; final Color frameColor;
@@ -130,7 +130,7 @@ class _MihCircleAvatarState extends State<MihCircleAvatar> {
}); });
setState(() { setState(() {
widget.fileNameController.text = selectedFile.name; widget.fileNameController!.text = selectedFile.name;
}); });
} else { } else {
if (result != null) { if (result != null) {
@@ -148,7 +148,7 @@ class _MihCircleAvatarState extends State<MihCircleAvatar> {
}); });
setState(() { setState(() {
widget.fileNameController.text = widget.fileNameController!.text =
file.path.split('/').last; file.path.split('/').last;
}); });
} else { } else {
@@ -157,7 +157,7 @@ class _MihCircleAvatarState extends State<MihCircleAvatar> {
} }
} }
} catch (e) { } catch (e) {
print("Error: $e"); print("Here Error: $e");
} }
}, },
icon: Icon( icon: Icon(

View File

@@ -10,6 +10,7 @@ class MihDropdownField extends StatefulWidget {
final bool editable; final bool editable;
final bool enableSearch; final bool enableSearch;
final FormFieldValidator<String>? validator; final FormFieldValidator<String>? validator;
final Function(String?)? onSelected;
const MihDropdownField({ const MihDropdownField({
super.key, super.key,
@@ -20,6 +21,7 @@ class MihDropdownField extends StatefulWidget {
required this.editable, required this.editable,
required this.enableSearch, required this.enableSearch,
this.validator, this.validator,
this.onSelected,
}); });
@override @override
@@ -117,8 +119,10 @@ class _MihDropdownFieldState extends State<MihDropdownField> {
enableSearch: widget.enableSearch, enableSearch: widget.enableSearch,
enableFilter: widget.enableSearch, enableFilter: widget.enableSearch,
enabled: widget.editable, enabled: widget.editable,
textInputAction: TextInputAction.search, textInputAction: widget.enableSearch
requestFocusOnTap: true, ? TextInputAction.search
: TextInputAction.none,
requestFocusOnTap: widget.enableSearch,
menuHeight: 400, menuHeight: 400,
expandedInsets: EdgeInsets.zero, expandedInsets: EdgeInsets.zero,
textStyle: TextStyle( textStyle: TextStyle(
@@ -153,6 +157,7 @@ class _MihDropdownFieldState extends State<MihDropdownField> {
), ),
onSelected: (String? selectedValue) { onSelected: (String? selectedValue) {
field.didChange(selectedValue); field.didChange(selectedValue);
widget.onSelected?.call(selectedValue);
}, },
menuStyle: MenuStyle( menuStyle: MenuStyle(
backgroundColor: WidgetStatePropertyAll( backgroundColor: WidgetStatePropertyAll(

View File

@@ -11,54 +11,57 @@ class MihIcons {
// IconData constants based on your style.css file // IconData constants based on your style.css file
// Note: We convert the hex code from CSS (\eXXX) to an integer (0xeXXX) // Note: We convert the hex code from CSS (\eXXX) to an integer (0xeXXX)
static const IconData mzansiDirectory = static const IconData mineSweeper =
IconData(0xe900, fontFamily: _mihFontFam, fontPackage: _mihFontPkg); IconData(0xe900, fontFamily: _mihFontFam, fontPackage: _mihFontPkg);
static const IconData personalProfile = static const IconData mzansiDirectory =
IconData(0xe901, fontFamily: _mihFontFam, fontPackage: _mihFontPkg); IconData(0xe901, fontFamily: _mihFontFam, fontPackage: _mihFontPkg);
static const IconData aboutMih = static const IconData personalProfile =
IconData(0xe902, fontFamily: _mihFontFam, fontPackage: _mihFontPkg); IconData(0xe902, fontFamily: _mihFontFam, fontPackage: _mihFontPkg);
static const IconData accessControl = static const IconData aboutMih =
IconData(0xe903, fontFamily: _mihFontFam, fontPackage: _mihFontPkg); IconData(0xe903, fontFamily: _mihFontFam, fontPackage: _mihFontPkg);
static const IconData businessProfile = static const IconData accessControl =
IconData(0xe904, fontFamily: _mihFontFam, fontPackage: _mihFontPkg); IconData(0xe904, fontFamily: _mihFontFam, fontPackage: _mihFontPkg);
static const IconData businessSetup = static const IconData businessProfile =
IconData(0xe905, fontFamily: _mihFontFam, fontPackage: _mihFontPkg); IconData(0xe905, fontFamily: _mihFontFam, fontPackage: _mihFontPkg);
static const IconData iDontKnow = static const IconData businessSetup =
IconData(0xe906, fontFamily: _mihFontFam, fontPackage: _mihFontPkg); IconData(0xe906, fontFamily: _mihFontFam, fontPackage: _mihFontPkg);
static const IconData mihLogo = static const IconData calculator =
IconData(0xe907, fontFamily: _mihFontFam, fontPackage: _mihFontPkg); IconData(0xe907, fontFamily: _mihFontFam, fontPackage: _mihFontPkg);
static const IconData mihRing = static const IconData calendar =
IconData(0xe908, fontFamily: _mihFontFam, fontPackage: _mihFontPkg); IconData(0xe908, fontFamily: _mihFontFam, fontPackage: _mihFontPkg);
static const IconData mzansiAi = static const IconData iDontKnow =
IconData(0xe909, fontFamily: _mihFontFam, fontPackage: _mihFontPkg); IconData(0xe909, fontFamily: _mihFontFam, fontPackage: _mihFontPkg);
static const IconData mzansiWallet = static const IconData mihLogo =
IconData(0xe90a, fontFamily: _mihFontFam, fontPackage: _mihFontPkg); IconData(0xe90a, fontFamily: _mihFontFam, fontPackage: _mihFontPkg);
static const IconData notifications = static const IconData mihRing =
IconData(0xe90b, fontFamily: _mihFontFam, fontPackage: _mihFontPkg); IconData(0xe90b, fontFamily: _mihFontFam, fontPackage: _mihFontPkg);
static const IconData patientManager = static const IconData mzansiAi =
IconData(0xe90c, fontFamily: _mihFontFam, fontPackage: _mihFontPkg); IconData(0xe90c, fontFamily: _mihFontFam, fontPackage: _mihFontPkg);
static const IconData patientProfile = static const IconData mzansiWallet =
IconData(0xe90d, fontFamily: _mihFontFam, fontPackage: _mihFontPkg); IconData(0xe90d, fontFamily: _mihFontFam, fontPackage: _mihFontPkg);
static const IconData profileSetup = static const IconData notifications =
IconData(0xe90e, fontFamily: _mihFontFam, fontPackage: _mihFontPkg); IconData(0xe90e, fontFamily: _mihFontFam, fontPackage: _mihFontPkg);
static const IconData calculator = static const IconData patientManager =
IconData(0xe940, fontFamily: _mihFontFam, fontPackage: _mihFontPkg); IconData(0xe90f, fontFamily: _mihFontFam, fontPackage: _mihFontPkg);
static const IconData calendar = static const IconData patientProfile =
IconData(0xe953, fontFamily: _mihFontFam, fontPackage: _mihFontPkg); IconData(0xe910, fontFamily: _mihFontFam, fontPackage: _mihFontPkg);
static const IconData profileSetup =
IconData(0xe911, fontFamily: _mihFontFam, fontPackage: _mihFontPkg);
} }

View File

@@ -2,6 +2,7 @@ import 'dart:io';
import 'package:file_picker/file_picker.dart'; import 'package:file_picker/file_picker.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:ken_logger/ken_logger.dart';
import 'package:mzansi_innovation_hub/main.dart'; import 'package:mzansi_innovation_hub/main.dart';
import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart'; import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart';
@@ -32,19 +33,9 @@ class _MihImageDisplayState extends State<MihImageDisplay> {
late ImageProvider<Object>? imagePreview; late ImageProvider<Object>? imagePreview;
ImageProvider<Object>? getImage() { ImageProvider<Object>? getImage() {
Color dark = const Color(0XFF3A4454); KenLogger.success(widget.imageFile.toString());
if (widget.imageFile == null) { if (widget.imageFile == null) {
if (MihColors.getSecondaryColor( return null;
MzansiInnovationHub.of(context)!.theme.mode == "Dark") ==
dark) {
print("here in light icon");
return const AssetImage(
'lib/mih_components/mih_package_components/assets/images/i-dont-know-dark.png');
} else {
print("here in dark icon");
return const AssetImage(
'lib/mih_components/mih_package_components/assets/images/i-dont-know-light.png');
}
} else { } else {
return widget.imageFile; return widget.imageFile;
} }
@@ -69,9 +60,25 @@ class _MihImageDisplayState extends State<MihImageDisplay> {
child: Stack( child: Stack(
alignment: Alignment.center, alignment: Alignment.center,
children: [ children: [
ClipRRect( imagePreview != null
? ClipRRect(
borderRadius: BorderRadius.circular(widget.width * 0.1), borderRadius: BorderRadius.circular(widget.width * 0.1),
child: Image(image: imagePreview!), child: Image(image: imagePreview!),
)
: Container(
width: widget.width,
height: widget.height,
decoration: BoxDecoration(
color: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
borderRadius: BorderRadius.circular(widget.width * 0.1),
),
child: Icon(
Icons.image_not_supported_rounded,
size: widget.width * 0.3,
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
),
), ),
Visibility( Visibility(
visible: widget.editable, visible: widget.editable,
@@ -133,7 +140,7 @@ class _MihImageDisplayState extends State<MihImageDisplay> {
} }
} }
} catch (e) { } catch (e) {
print("Error: $e"); print("here 2 Error: $e");
} }
}, },
icon: const Icon( icon: const Icon(

View File

@@ -35,7 +35,7 @@ class _MihPackageAlertState extends State<MihPackageAlert> {
setState(() { setState(() {
popUpWidth = (size!.width / 4) * 2; popUpWidth = (size!.width / 4) * 2;
popUpheight = null; popUpheight = null;
popUpTitleSize = 25.0; popUpTitleSize = 30.0;
popUpSubtitleSize = 20.0; popUpSubtitleSize = 20.0;
popUpBodySize = 15; popUpBodySize = 15;
popUpPaddingSize = 25.0; popUpPaddingSize = 25.0;
@@ -45,7 +45,7 @@ class _MihPackageAlertState extends State<MihPackageAlert> {
setState(() { setState(() {
popUpWidth = size!.width - (size!.width * 0.1); popUpWidth = size!.width - (size!.width * 0.1);
popUpheight = null; popUpheight = null;
popUpTitleSize = 20.0; popUpTitleSize = 25.0;
popUpSubtitleSize = 18.0; popUpSubtitleSize = 18.0;
popUpBodySize = 15; popUpBodySize = 15;
popUpPaddingSize = 15.0; popUpPaddingSize = 15.0;

View File

@@ -191,7 +191,9 @@ class _MihTextFormFieldState extends State<MihTextFormField> {
), ),
decoration: InputDecoration( decoration: InputDecoration(
suffixIcon: widget.passwordMode == true suffixIcon: widget.passwordMode == true
? IconButton( ? FocusScope(
canRequestFocus: false,
child: IconButton(
icon: Icon( icon: Icon(
_obscureText _obscureText
? Icons.visibility_off ? Icons.visibility_off
@@ -203,6 +205,7 @@ class _MihTextFormFieldState extends State<MihTextFormField> {
_obscureText = !_obscureText; _obscureText = !_obscureText;
}); });
}, },
),
) )
: null, : null,
errorStyle: const TextStyle( errorStyle: const TextStyle(

View File

@@ -0,0 +1,19 @@
import 'package:flutter/foundation.dart';
class AboutMihProvider extends ChangeNotifier {
int toolIndex;
AboutMihProvider({
this.toolIndex = 0,
});
void reset() {
toolIndex = 0;
notifyListeners();
}
void setToolIndex(int index) {
toolIndex = index;
notifyListeners();
}
}

View File

@@ -0,0 +1,37 @@
import 'package:flutter/material.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_objects/patient_access.dart';
class MihAccessControllsProvider extends ChangeNotifier {
int toolIndex;
List<PatientAccess>? accessList;
MihAccessControllsProvider({
this.toolIndex = 0,
});
void reset() {
toolIndex = 0;
accessList = null;
notifyListeners();
}
void setToolIndex(int index) {
toolIndex = index;
}
void setAccessList(List<PatientAccess> accesses) {
accessList = accesses;
notifyListeners();
}
void editAccessItem(PatientAccess updatedAccess) {
if (accessList == null) return;
int index = accessList!.indexWhere((access) =>
access.app_id == updatedAccess.app_id &&
access.business_id == updatedAccess.business_id);
if (index != -1) {
accessList![index] = updatedAccess;
notifyListeners();
}
}
}

View File

@@ -0,0 +1,19 @@
import 'package:flutter/foundation.dart';
class MihAuthenticationProvider extends ChangeNotifier {
int toolIndex;
MihAuthenticationProvider({
this.toolIndex = 0,
});
void reset() {
toolIndex = 0;
notifyListeners();
}
void setToolIndex(int index) {
toolIndex = index;
notifyListeners();
}
}

View File

@@ -0,0 +1,62 @@
import 'package:flutter/foundation.dart';
import 'package:google_mobile_ads/google_mobile_ads.dart';
import 'package:mzansi_innovation_hub/mih_config/mih_env.dart';
class MihBannerAdProvider extends ChangeNotifier {
BannerAd? bannerAd;
final adUnitId = AppEnviroment.bannerAdUnitId;
bool isBannerAdLoaded = false;
String errorMessage = '';
MihBannerAdProvider({
this.bannerAd,
this.isBannerAdLoaded = false,
this.errorMessage = '',
});
void reset() {
bannerAd = null;
isBannerAdLoaded = false;
errorMessage = "";
notifyListeners();
}
@override
void dispose() {
bannerAd?.dispose();
super.dispose();
}
void loadBannerAd() {
if (bannerAd != null) {
bannerAd!.dispose();
bannerAd = null;
isBannerAdLoaded = false;
}
bannerAd = BannerAd(
adUnitId: adUnitId,
request: const AdRequest(),
size: AdSize.banner,
listener: BannerAdListener(
onAdLoaded: (ad) {
debugPrint('$ad loaded.');
isBannerAdLoaded = true;
notifyListeners();
},
onAdFailedToLoad: (ad, err) {
debugPrint('BannerAd failed to load: $err');
errorMessage =
'Failed to load ad- Message: ${err.message} Code :${err.code}';
ad.dispose(); // Dispose the ad to free resources
isBannerAdLoaded = false; // ⬅️ Explicitly set to false
bannerAd = null; // ⬅️ Explicitly set to null
notifyListeners();
},
onAdOpened: (Ad ad) => debugPrint('$ad opened.'),
onAdClosed: (Ad ad) => debugPrint('$ad closed.'),
onAdImpression: (Ad ad) => debugPrint('$ad impression.'),
),
);
bannerAd!.load();
}
}

View File

@@ -0,0 +1,27 @@
import 'package:flutter/foundation.dart';
class MihCalculatorProvider extends ChangeNotifier {
List<String> availableCurrencies;
int toolIndex;
MihCalculatorProvider({
this.availableCurrencies = const [],
this.toolIndex = 0,
});
void reset() {
availableCurrencies = [];
toolIndex = 0;
notifyListeners();
}
void setToolIndex(int index) {
toolIndex = index;
notifyListeners();
}
void setAvailableCurrencies({required List<String> currencies}) async {
availableCurrencies = currencies;
notifyListeners();
}
}

View File

@@ -0,0 +1,89 @@
import 'package:flutter/foundation.dart';
import 'package:ken_logger/ken_logger.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_objects/appointment.dart';
class MihCalendarProvider extends ChangeNotifier {
int toolIndex;
String selectedDay = DateTime.now().toString().split(" ")[0];
List<Appointment>? personalAppointments;
List<Appointment>? businessAppointments;
MihCalendarProvider({
this.toolIndex = 0,
});
void reset() {
toolIndex = 0;
personalAppointments = null;
businessAppointments = null;
notifyListeners();
}
void setToolIndex(int index) {
toolIndex = index;
notifyListeners();
}
void setSelectedDay(String day) {
selectedDay = day;
notifyListeners();
}
void resetSelectedDay() {
selectedDay = DateTime.now().toString().split(" ")[0];
notifyListeners();
}
void setPersonalAppointments({required List<Appointment> appointments}) {
personalAppointments = appointments;
notifyListeners();
}
void setBusinessAppointments({required List<Appointment> appointments}) {
businessAppointments = appointments;
notifyListeners();
}
void addPersonalAppointment({required Appointment newAppointment}) {
personalAppointments?.add(newAppointment);
notifyListeners();
}
void addBusinessAppointment({required Appointment newAppointment}) {
businessAppointments?.add(newAppointment);
notifyListeners();
}
void editPersonalAppointment({required Appointment updatedAppointment}) {
int index = personalAppointments?.indexWhere((appointment) =>
appointment.idappointments == updatedAppointment.idappointments) ??
-1;
KenLogger.success("Edit Patient Index: $index");
if (index != -1) {
personalAppointments?[index] = updatedAppointment;
notifyListeners();
}
}
void editBusinessAppointment({required Appointment updatedAppointment}) {
int index = businessAppointments?.indexWhere((appointment) =>
appointment.idappointments == updatedAppointment.idappointments) ??
-1;
if (index != -1) {
businessAppointments?[index] = updatedAppointment;
notifyListeners();
}
}
void deletePersonalAppointment({required int appointmentId}) {
personalAppointments?.removeWhere(
(appointment) => appointment.idappointments == appointmentId);
notifyListeners();
}
void deleteBusinessAppointment({required int appointmentId}) {
businessAppointments?.removeWhere(
(appointment) => appointment.idappointments == appointmentId);
notifyListeners();
}
}

View File

@@ -0,0 +1,81 @@
import 'package:flutter/widgets.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_objects/minesweeper_player_score.dart';
class MihMineSweeperProvider extends ChangeNotifier {
String difficulty;
int toolIndex;
int rowCount;
int columnCount;
int totalMines;
List<MinesweeperPlayerScore>? leaderboard;
List<MinesweeperPlayerScore>? myScoreboard;
List<ImageProvider<Object>?> leaderboardUserPictures = [];
MihMineSweeperProvider({
this.difficulty = "Easy",
this.toolIndex = 0,
this.rowCount = 10,
this.columnCount = 10,
this.totalMines = 15,
});
void reset() {
difficulty = "Easy";
toolIndex = 0;
rowCount = 10;
columnCount = 10;
totalMines = 15;
notifyListeners();
}
void setDifficulty(String difficulty) {
this.difficulty = difficulty;
notifyListeners();
}
void setToolIndex(int index) {
toolIndex = index;
notifyListeners();
}
void setRowCount(int rowCount) {
this.rowCount = rowCount;
notifyListeners();
}
void setCoulmnCount(int columnCount) {
this.columnCount = columnCount;
notifyListeners();
}
void setTotalMines(int totalMines) {
this.totalMines = totalMines;
notifyListeners();
}
void setLeaderboard({required List<MinesweeperPlayerScore>? leaderboard}) {
if (leaderboard == null) {
this.leaderboard = [];
} else {
this.leaderboard = leaderboard;
}
notifyListeners();
}
void setMyScoreboard({
required List<MinesweeperPlayerScore>? myScoreboard,
}) {
if (myScoreboard == null) {
this.myScoreboard = [];
} else {
this.myScoreboard = myScoreboard;
}
notifyListeners();
}
void setLeaderboardUserPictures(
{required List<ImageProvider<Object>?> leaderboardUserPictures}) {
this.leaderboardUserPictures = leaderboardUserPictures;
notifyListeners();
}
}

View File

@@ -0,0 +1,26 @@
import 'package:flutter/material.dart';
class MzansiAiProvider extends ChangeNotifier {
int toolIndex;
String? startUpQuestion;
MzansiAiProvider({
this.toolIndex = 0,
});
void reset() {
toolIndex = 0;
startUpQuestion = null;
notifyListeners();
}
void setToolIndex(int index) {
toolIndex = index;
notifyListeners();
}
void setStartUpQuestion(String? question) {
startUpQuestion = question;
notifyListeners();
}
}

View File

@@ -0,0 +1,104 @@
import 'package:flutter/material.dart';
import 'package:geolocator/geolocator.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_objects/app_user.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_objects/bookmarked_business.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_objects/business.dart';
class MzansiDirectoryProvider extends ChangeNotifier {
int toolIndex;
Position? userPosition;
String userLocation;
bool personalSearch;
List<BookmarkedBusiness> bookmarkedBusinesses = [];
List<Business>? favouriteBusinessesList;
List<Business>? searchedBusinesses;
Business? selectedBusiness;
List<AppUser>? searchedUsers;
AppUser? selectedUser;
String searchTerm;
String businessTypeFilter;
MzansiDirectoryProvider({
this.toolIndex = 0,
this.personalSearch = true,
this.userLocation = "Unknown Location",
this.searchTerm = "",
this.businessTypeFilter = "",
});
void reset() {
toolIndex = 0;
userPosition = null;
userLocation = "Unknown Location";
personalSearch = true;
bookmarkedBusinesses = [];
searchedBusinesses = null;
selectedBusiness = null;
searchedUsers = null;
selectedUser = null;
searchTerm = "";
businessTypeFilter = "";
notifyListeners();
}
void setToolIndex(int index) {
toolIndex = index;
notifyListeners();
}
void setUserPosition(Position? position) {
userPosition = position;
if (position == null) {
userLocation = "Unknown Location";
} else {
userLocation = "${position.latitude}, ${position.longitude}";
}
notifyListeners();
}
void setPersonalSearch(bool personal) {
personalSearch = personal;
notifyListeners();
}
void setBookmarkedeBusinesses(
{required List<BookmarkedBusiness> businesses}) {
bookmarkedBusinesses = businesses;
notifyListeners();
}
void setFavouriteBusinesses({required List<Business> businesses}) {
favouriteBusinessesList = businesses;
notifyListeners();
}
void setSearchedBusinesses({required List<Business> searchedBusinesses}) {
this.searchedBusinesses = searchedBusinesses;
notifyListeners();
}
void setSelectedBusiness({required Business business}) {
selectedBusiness = business;
notifyListeners();
}
void setSearchedUsers({required List<AppUser> searchedUsers}) {
this.searchedUsers = searchedUsers;
notifyListeners();
}
void setSelectedUser({required AppUser user}) {
selectedUser = user;
notifyListeners();
}
void setSearchTerm({required String searchTerm}) {
this.searchTerm = searchTerm;
notifyListeners();
}
void setBusinessTypeFilter({required String businessTypeFilter}) {
this.businessTypeFilter = businessTypeFilter;
notifyListeners();
}
}

View File

@@ -0,0 +1,141 @@
import 'package:flutter/material.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_objects/app_user.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_objects/business.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_objects/business_employee.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_objects/business_user.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_objects/user_consent.dart';
class MzansiProfileProvider extends ChangeNotifier {
bool personalHome;
int personalIndex;
int businessIndex;
AppUser? user;
String? userProfilePicUrl;
ImageProvider<Object>? userProfilePicture;
Business? business;
String? businessProfilePicUrl;
ImageProvider<Object>? businessProfilePicture;
BusinessUser? businessUser;
String? businessUserSignatureUrl;
ImageProvider<Object>? businessUserSignature;
UserConsent? userConsent;
List<BusinessEmployee>? employeeList;
List<AppUser> userSearchResults = [];
MzansiProfileProvider({
this.personalHome = true,
this.personalIndex = 0,
this.businessIndex = 0,
});
void reset() {
personalHome = true;
personalIndex = 0;
businessIndex = 0;
user = null;
userProfilePicUrl = null;
userProfilePicture = null;
business = null;
businessProfilePicUrl = null;
businessProfilePicture = null;
businessUser = null;
businessUserSignatureUrl = null;
businessUserSignature = null;
userConsent = null;
notifyListeners();
}
void setPersonalHome(bool isPersonalHome) {
personalHome = isPersonalHome;
notifyListeners();
}
void setPersonalIndex(int index) {
personalIndex = index;
notifyListeners();
}
void setBusinessIndex(int index) {
businessIndex = index;
notifyListeners();
}
void setUser({
required AppUser newUser,
}) {
user = newUser;
notifyListeners();
}
void setUserProfilePicUrl(String url) {
userProfilePicUrl = url;
userProfilePicture = url.isNotEmpty ? NetworkImage(url) : null;
notifyListeners();
}
void setBusiness({
Business? newBusiness,
}) {
business = newBusiness;
notifyListeners();
}
void setBusinessProfilePicUrl(String url) {
businessProfilePicUrl = url;
businessProfilePicture = url.isNotEmpty ? NetworkImage(url) : null;
notifyListeners();
}
void setBusinessUser({required BusinessUser newBusinessUser}) {
businessUser = newBusinessUser;
notifyListeners();
}
void setBusinessUserSignatureUrl(String url) {
businessUserSignatureUrl = url;
businessUserSignature = url.isNotEmpty ? NetworkImage(url) : null;
notifyListeners();
}
void setUserConsent(UserConsent? newUserConsent) {
userConsent = newUserConsent;
notifyListeners();
}
void setEmployeeList({required List<BusinessEmployee> employeeList}) {
this.employeeList = employeeList;
notifyListeners();
}
void addLoyaltyCard({required BusinessEmployee newEmployee}) {
employeeList!.add(newEmployee);
notifyListeners();
}
void updateEmplyeeDetails({required BusinessEmployee updatedEmployee}) {
int index = employeeList!.indexWhere((employee) =>
employee.business_id == updatedEmployee.business_id &&
employee.app_id == updatedEmployee.app_id);
if (index != -1) {
employeeList![index] = updatedEmployee;
notifyListeners();
}
}
void deleteEmplyee({required BusinessEmployee deletedEmployee}) {
employeeList!.removeWhere((employee) =>
employee.business_id == deletedEmployee.business_id &&
employee.app_id == deletedEmployee.app_id);
notifyListeners();
}
void addEmployee({required BusinessEmployee newEmployee}) {
employeeList!.add(newEmployee);
notifyListeners();
}
void setUserearchResults({required List<AppUser> userSearchResults}) {
this.userSearchResults = userSearchResults;
notifyListeners();
}
}

View File

@@ -0,0 +1,49 @@
import 'package:flutter/material.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_objects/loyalty_card.dart';
class MzansiWalletProvider extends ChangeNotifier {
List<MIHLoyaltyCard> loyaltyCards;
List<MIHLoyaltyCard> favouriteCards;
int toolIndex;
MzansiWalletProvider({
this.loyaltyCards = const [],
this.favouriteCards = const [],
this.toolIndex = 0,
});
void reset() {
toolIndex = 0;
loyaltyCards = [];
favouriteCards = [];
}
void setToolIndex(int index) {
toolIndex = index;
notifyListeners();
}
void setLoyaltyCards({required List<MIHLoyaltyCard> cards}) async {
loyaltyCards = cards;
notifyListeners();
}
void setFavouriteCards({required List<MIHLoyaltyCard> cards}) async {
favouriteCards = cards;
notifyListeners();
}
void deleteLoyaltyCard({required int cardId}) {
loyaltyCards.removeWhere((card) => card.idloyalty_cards == cardId);
notifyListeners();
}
void editLoyaltyCard({required MIHLoyaltyCard updatedCard}) {
int index = loyaltyCards.indexWhere(
(card) => card.idloyalty_cards == updatedCard.idloyalty_cards);
if (index != -1) {
loyaltyCards[index] = updatedCard;
notifyListeners();
}
}
}

View File

@@ -0,0 +1,84 @@
import 'package:flutter/material.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_objects/claim_statement_file.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_objects/files.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_objects/notes.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_objects/patient_access.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_objects/patients.dart';
class PatientManagerProvider extends ChangeNotifier {
int patientProfileIndex;
int patientManagerIndex;
int fileViewerIndex;
bool personalMode;
List<PatientAccess>? myPaitentList;
Patient? selectedPatient;
List<Note>? consultationNotes;
List<PFile>? patientDocuments;
List<ClaimStatementFile>? patientClaimsDocuments;
List<Patient> patientSearchResults = [];
PatientManagerProvider({
this.patientProfileIndex = 0,
this.patientManagerIndex = 0,
this.fileViewerIndex = 0,
this.personalMode = true,
});
void reset() {
patientProfileIndex = 0;
patientManagerIndex = 0;
personalMode = true;
selectedPatient = null;
}
void setPatientProfileIndex(int index) {
patientProfileIndex = index;
notifyListeners();
}
void setPatientManagerIndex(int index) {
patientManagerIndex = index;
notifyListeners();
}
void setFileViewerIndex(int index) {
patientProfileIndex = index;
notifyListeners();
}
void setPersonalMode(bool personalMode) {
this.personalMode = personalMode;
notifyListeners();
}
void setSelectedPatient({required Patient? selectedPatient}) {
this.selectedPatient = selectedPatient;
notifyListeners();
}
void setMyPatientList({required List<PatientAccess>? myPaitentList}) {
this.myPaitentList = myPaitentList ?? [];
notifyListeners();
}
void setConsultationNotes({required List<Note>? consultationNotes}) {
this.consultationNotes = consultationNotes ?? [];
notifyListeners();
}
void setPatientDocuments({required List<PFile>? patientDocuments}) {
this.patientDocuments = patientDocuments ?? [];
notifyListeners();
}
void setClaimsDocuments(
{required List<ClaimStatementFile>? patientClaimsDocuments}) {
this.patientClaimsDocuments = patientClaimsDocuments ?? [];
notifyListeners();
}
void setPatientSearchResults({required List<Patient> patientSearchResults}) {
this.patientSearchResults = patientSearchResults;
notifyListeners();
}
}

View File

@@ -37,7 +37,7 @@ class MihColors {
if (darkMode == true) { if (darkMode == true) {
return const Color(0xff8ae290); return const Color(0xff8ae290);
} else { } else {
return const Color(0xffB0F2B4); return const Color(0xFF41B349);
} }
} }
@@ -63,7 +63,7 @@ class MihColors {
return const Color(0xffd69d7d); return const Color(0xffd69d7d);
} else { } else {
// Add a different shade of pink for light mode // Add a different shade of pink for light mode
return const Color(0xffd69d7d); return const Color(0xFFBD7145);
} }
} }
@@ -81,7 +81,7 @@ class MihColors {
return const Color(0xff6e7dcc); return const Color(0xff6e7dcc);
} else { } else {
// Add a different shade of pink for light mode // Add a different shade of pink for light mode
return const Color(0xff6e7dcc); return const Color(0xFF5567C0);
} }
} }
@@ -90,7 +90,34 @@ class MihColors {
return const Color(0xffb682e7); return const Color(0xffb682e7);
} else { } else {
// Add a different shade of pink for light mode // Add a different shade of pink for light mode
return const Color(0xffb682e7); return const Color(0xFF9857D4);
}
}
static Color getGoldColor(bool darkMode) {
if (darkMode == true) {
return const Color(0xFFD4AF37);
} else {
// Add a different shade of pink for light mode
return const Color(0xffFFD700);
}
}
static Color getSilverColor(bool darkMode) {
if (darkMode == true) {
return const Color(0xffC0C0C0);
} else {
// Add a different shade of pink for light mode
return const Color(0xFFA6A6A6);
}
}
static Color getBronze(bool darkMode) {
if (darkMode == true) {
return const Color(0xffB1560F);
} else {
// Add a different shade of pink for light mode
return const Color(0xFFCD7F32);
} }
} }
} }

View File

@@ -1,9 +1,10 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:go_router/go_router.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_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_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_package_components/Example/package_test.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_providers/mzansi_directory_provider.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_providers/mzansi_profile_provider.dart';
import 'package:mzansi_innovation_hub/mih_packages/about_mih/about_mih.dart'; import 'package:mzansi_innovation_hub/mih_packages/about_mih/about_mih.dart';
import 'package:mzansi_innovation_hub/mih_packages/access_review/mih_access.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/calculator/mih_calculator.dart';
@@ -13,21 +14,22 @@ import 'package:mzansi_innovation_hub/mih_packages/mih_authentication/mih_auth_p
import 'package:mzansi_innovation_hub/mih_packages/mih_authentication/mih_authentication.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/mih_home/mih_home.dart';
import 'package:mzansi_innovation_hub/mih_packages/mih_home/mih_route_error.dart'; import 'package:mzansi_innovation_hub/mih_packages/mih_home/mih_route_error.dart';
import 'package:mzansi_innovation_hub/mih_packages/mine_sweeper/mih_mine_sweeper.dart';
import 'package:mzansi_innovation_hub/mih_packages/mzansi_ai/mzansi_ai.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_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/busines_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/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/business_profile/mzansi_set_up_business_profile.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.dart';
import 'package:mzansi_innovation_hub/mih_packages/mzansi_profile/personal_profile/mzansi_profile_view.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: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/components/mih_barcode_scanner.dart';
import 'package:mzansi_innovation_hub/mih_packages/mzansi_wallet/mih_wallet.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_manager/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_manager/pat_profile/components/full_screen_file.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_manager/pat_profile/patient_profile.dart';
import 'package:mzansi_innovation_hub/mih_packages/patient_profile/pat_profile/patient_edit.dart'; import 'package:mzansi_innovation_hub/mih_packages/patient_manager/pat_profile/patient_set_up.dart';
import 'package:mzansi_innovation_hub/mih_packages/patient_profile/pat_profile/patient_profile.dart'; import 'package:provider/provider.dart';
import 'package:supertokens_flutter/supertokens.dart'; import 'package:supertokens_flutter/supertokens.dart';
class MihGoRouterPaths { class MihGoRouterPaths {
@@ -50,7 +52,6 @@ class MihGoRouterPaths {
static const String businessProfileView = '/business-profile/view'; static const String businessProfileView = '/business-profile/view';
static const String patientProfile = '/patient-profile'; static const String patientProfile = '/patient-profile';
static const String patientProfileSetup = '/patient-profile/set-up'; static const String patientProfileSetup = '/patient-profile/set-up';
static const String patientProfileEdit = '/patient-profile/edit';
static const String mzansiWallet = '/mzansi-wallet'; static const String mzansiWallet = '/mzansi-wallet';
static const String mzansiDirectory = '/mzansi-directory'; static const String mzansiDirectory = '/mzansi-directory';
static const String mihAccess = '/mih-access'; static const String mihAccess = '/mih-access';
@@ -63,6 +64,7 @@ class MihGoRouterPaths {
static const String barcodeScanner = '/scanner'; static const String barcodeScanner = '/scanner';
static const String calculator = '/calculator'; static const String calculator = '/calculator';
static const String mzansiAi = '/mzansi-ai'; static const String mzansiAi = '/mzansi-ai';
static const String mihMineSweeper = '/mih-minesweeper';
static const String packageDevTest = '/package-dev'; static const String packageDevTest = '/package-dev';
} }
@@ -131,16 +133,8 @@ class MihGoRouter {
path: MihGoRouterPaths.mihHome, path: MihGoRouterPaths.mihHome,
builder: (BuildContext context, GoRouterState state) { builder: (BuildContext context, GoRouterState state) {
KenLogger.success("MihGoRouter: mihHome"); KenLogger.success("MihGoRouter: mihHome");
if (state.extra != null) {
final bool personalSelected = state.extra as bool;
return MihHome( return MihHome(
key: UniqueKey(), key: UniqueKey(),
personalSelected: personalSelected,
);
}
return MihHome(
key: UniqueKey(),
personalSelected: true,
); );
}, },
), ),
@@ -150,14 +144,7 @@ class MihGoRouter {
path: MihGoRouterPaths.aboutMih, path: MihGoRouterPaths.aboutMih,
builder: (BuildContext context, GoRouterState state) { builder: (BuildContext context, GoRouterState state) {
KenLogger.success("MihGoRouter: aboutMih"); KenLogger.success("MihGoRouter: aboutMih");
final AboutArguments? args = state.extra as AboutArguments?; return AboutMih();
int index = 0;
bool personalSelected = true;
if (args != null) {
index = args.packageIndex ?? 0;
personalSelected = args.personalSelected;
}
return AboutMih(arguments: AboutArguments(personalSelected, index));
}, },
), ),
// ========================== Mzansi Profile Personal ================================== // ========================== Mzansi Profile Personal ==================================
@@ -166,15 +153,13 @@ class MihGoRouter {
path: MihGoRouterPaths.mzansiProfileManage, path: MihGoRouterPaths.mzansiProfileManage,
builder: (BuildContext context, GoRouterState state) { builder: (BuildContext context, GoRouterState state) {
KenLogger.success("MihGoRouter: mzansiProfileManage"); KenLogger.success("MihGoRouter: mzansiProfileManage");
final AppProfileUpdateArguments? args = if (context.watch<MzansiProfileProvider>().user == null) {
state.extra as AppProfileUpdateArguments?;
if (args == null) {
WidgetsBinding.instance.addPostFrameCallback((_) { WidgetsBinding.instance.addPostFrameCallback((_) {
context.go(MihGoRouterPaths.mihHome); context.go(MihGoRouterPaths.mihHome);
}); });
return const SizedBox.shrink(); return const SizedBox.shrink();
} }
return MzansiProfile(arguments: args); return MzansiProfile();
}, },
), ),
GoRoute( GoRoute(
@@ -182,14 +167,15 @@ class MihGoRouter {
path: MihGoRouterPaths.mzansiProfileView, path: MihGoRouterPaths.mzansiProfileView,
builder: (BuildContext context, GoRouterState state) { builder: (BuildContext context, GoRouterState state) {
KenLogger.success("MihGoRouter: mzansiProfileView"); KenLogger.success("MihGoRouter: mzansiProfileView");
final AppUser? user = state.extra as AppUser?; MzansiDirectoryProvider directoryProvider =
if (user == null) { context.read<MzansiDirectoryProvider>();
if (directoryProvider.selectedUser == null) {
WidgetsBinding.instance.addPostFrameCallback((_) { WidgetsBinding.instance.addPostFrameCallback((_) {
context.go(MihGoRouterPaths.mihHome); context.go(MihGoRouterPaths.mihHome);
}); });
return const SizedBox.shrink(); return const SizedBox.shrink();
} }
return MzansiProfileView(user: user); return MzansiProfileView();
}, },
), ),
// ========================== Mzansi Profile Business ================================== // ========================== Mzansi Profile Business ==================================
@@ -198,17 +184,16 @@ class MihGoRouter {
path: MihGoRouterPaths.businessProfileManage, path: MihGoRouterPaths.businessProfileManage,
builder: (BuildContext context, GoRouterState state) { builder: (BuildContext context, GoRouterState state) {
KenLogger.success("MihGoRouter: businessProfileManage"); KenLogger.success("MihGoRouter: businessProfileManage");
final BusinessArguments? args = state.extra as BusinessArguments?; if (context.watch<MzansiProfileProvider>().business == null) {
if (args == null) {
WidgetsBinding.instance.addPostFrameCallback((_) { WidgetsBinding.instance.addPostFrameCallback((_) {
context.go(MihGoRouterPaths.mihHome); context.go(MihGoRouterPaths.mihHome);
}); });
return const SizedBox.shrink(); return const SizedBox.shrink();
} }
return MzansiBusinessProfile( return BusinesProfile();
key: UniqueKey(), // return MzansiBusinessProfile(
arguments: args, // key: UniqueKey(),
); // );
}, },
), ),
GoRoute( GoRoute(
@@ -218,9 +203,10 @@ class MihGoRouter {
KenLogger.success("MihGoRouter: businessProfileView"); KenLogger.success("MihGoRouter: businessProfileView");
String? businessId = state.uri.queryParameters['business_id']; String? businessId = state.uri.queryParameters['business_id'];
KenLogger.success("businessId: $businessId"); KenLogger.success("businessId: $businessId");
final BusinessViewArguments? args = MzansiDirectoryProvider directoryProvider =
state.extra as BusinessViewArguments?; context.read<MzansiDirectoryProvider>();
if (args == null && businessId == null) { if (directoryProvider.selectedBusiness == null &&
businessId == null) {
WidgetsBinding.instance.addPostFrameCallback((_) { WidgetsBinding.instance.addPostFrameCallback((_) {
context.go(MihGoRouterPaths.mihHome); context.go(MihGoRouterPaths.mihHome);
}); });
@@ -228,7 +214,6 @@ class MihGoRouter {
} }
return MzansiBusinessProfileView( return MzansiBusinessProfileView(
key: UniqueKey(), key: UniqueKey(),
arguments: args,
businessId: businessId, businessId: businessId,
); );
}, },
@@ -238,8 +223,7 @@ class MihGoRouter {
path: MihGoRouterPaths.businessProfileSetup, path: MihGoRouterPaths.businessProfileSetup,
builder: (BuildContext context, GoRouterState state) { builder: (BuildContext context, GoRouterState state) {
KenLogger.success("MihGoRouter: businessProfileSetup"); KenLogger.success("MihGoRouter: businessProfileSetup");
final AppUser? signedInUser = state.extra as AppUser?; return MzansiSetUpBusinessProfile();
return ProfileBusinessAdd(signedInUser: signedInUser!);
}, },
), ),
// ========================== MIH Calculator ================================== // ========================== MIH Calculator ==================================
@@ -248,12 +232,7 @@ class MihGoRouter {
path: MihGoRouterPaths.calculator, path: MihGoRouterPaths.calculator,
builder: (BuildContext context, GoRouterState state) { builder: (BuildContext context, GoRouterState state) {
KenLogger.success("MihGoRouter: mihCalculator"); KenLogger.success("MihGoRouter: mihCalculator");
final bool? personalSelected = state.extra as bool?; return MIHCalculator();
bool personal = true;
if (personalSelected != null) {
personal = personalSelected;
}
return MIHCalculator(personalSelected: personal);
}, },
), ),
// ========================== MIH Calculator ================================== // ========================== MIH Calculator ==================================
@@ -262,8 +241,7 @@ class MihGoRouter {
path: MihGoRouterPaths.calendar, path: MihGoRouterPaths.calendar,
builder: (BuildContext context, GoRouterState state) { builder: (BuildContext context, GoRouterState state) {
KenLogger.success("MihGoRouter: mihCalendar"); KenLogger.success("MihGoRouter: mihCalendar");
final CalendarArguments? args = state.extra as CalendarArguments?; if (context.watch<MzansiProfileProvider>().user == null) {
if (args == null) {
WidgetsBinding.instance.addPostFrameCallback((_) { WidgetsBinding.instance.addPostFrameCallback((_) {
context.go(MihGoRouterPaths.mihHome); context.go(MihGoRouterPaths.mihHome);
}); });
@@ -271,7 +249,6 @@ class MihGoRouter {
} }
return MzansiCalendar( return MzansiCalendar(
key: UniqueKey(), key: UniqueKey(),
arguments: args,
); );
}, },
), ),
@@ -281,14 +258,13 @@ class MihGoRouter {
path: MihGoRouterPaths.mzansiAi, path: MihGoRouterPaths.mzansiAi,
builder: (BuildContext context, GoRouterState state) { builder: (BuildContext context, GoRouterState state) {
KenLogger.success("MihGoRouter: mzansiAi"); KenLogger.success("MihGoRouter: mzansiAi");
final MzansiAiArguments? args = state.extra as MzansiAiArguments?; if (context.watch<MzansiProfileProvider>().user == null) {
if (args == null) {
WidgetsBinding.instance.addPostFrameCallback((_) { WidgetsBinding.instance.addPostFrameCallback((_) {
context.go(MihGoRouterPaths.mihHome); context.go(MihGoRouterPaths.mihHome);
}); });
return const SizedBox.shrink(); return const SizedBox.shrink();
} }
return MzansiAi(arguments: args); return MzansiAi();
}, },
), ),
// ========================== Mzansi Wallet ================================== // ========================== Mzansi Wallet ==================================
@@ -297,8 +273,7 @@ class MihGoRouter {
path: MihGoRouterPaths.mzansiWallet, path: MihGoRouterPaths.mzansiWallet,
builder: (BuildContext context, GoRouterState state) { builder: (BuildContext context, GoRouterState state) {
KenLogger.success("MihGoRouter: mzansiWallet"); KenLogger.success("MihGoRouter: mzansiWallet");
final WalletArguments? args = state.extra as WalletArguments?; if (context.watch<MzansiProfileProvider>().user == null) {
if (args == null) {
WidgetsBinding.instance.addPostFrameCallback((_) { WidgetsBinding.instance.addPostFrameCallback((_) {
context.go(MihGoRouterPaths.mihHome); context.go(MihGoRouterPaths.mihHome);
}); });
@@ -306,7 +281,6 @@ class MihGoRouter {
} }
return MihWallet( return MihWallet(
key: UniqueKey(), key: UniqueKey(),
arguments: args,
); );
}, },
), ),
@@ -347,8 +321,8 @@ class MihGoRouter {
name: "mihAccess", name: "mihAccess",
path: MihGoRouterPaths.mihAccess, path: MihGoRouterPaths.mihAccess,
builder: (BuildContext context, GoRouterState state) { builder: (BuildContext context, GoRouterState state) {
final AppUser? signedInUser = state.extra as AppUser?; KenLogger.success("MihGoRouter: mihAccess");
if (signedInUser == null) { if (context.watch<MzansiProfileProvider>().user == null) {
WidgetsBinding.instance.addPostFrameCallback((_) { WidgetsBinding.instance.addPostFrameCallback((_) {
context.go(MihGoRouterPaths.mihHome); context.go(MihGoRouterPaths.mihHome);
}); });
@@ -356,7 +330,6 @@ class MihGoRouter {
} }
return MihAccess( return MihAccess(
key: UniqueKey(), key: UniqueKey(),
signedInUser: signedInUser,
); );
}, },
), ),
@@ -365,44 +338,36 @@ class MihGoRouter {
name: "patientProfile", name: "patientProfile",
path: MihGoRouterPaths.patientProfile, path: MihGoRouterPaths.patientProfile,
builder: (BuildContext context, GoRouterState state) { builder: (BuildContext context, GoRouterState state) {
final PatientViewArguments? args = KenLogger.success("MihGoRouter: patientProfile");
state.extra as PatientViewArguments?; if (context.watch<MzansiProfileProvider>().user == null) {
if (args == null) {
WidgetsBinding.instance.addPostFrameCallback((_) { WidgetsBinding.instance.addPostFrameCallback((_) {
context.go(MihGoRouterPaths.mihHome); context.go(MihGoRouterPaths.mihHome);
}); });
return const SizedBox.shrink(); return const SizedBox.shrink();
} }
return AddOrViewPatient( return PatientProfile();
key: UniqueKey(),
arguments: args,
);
}, },
), ),
GoRoute( GoRoute(
name: "patientProfileEdit", name: "patientProfileSetup",
path: MihGoRouterPaths.patientProfileEdit, path: MihGoRouterPaths.patientProfileSetup,
builder: (BuildContext context, GoRouterState state) { builder: (BuildContext context, GoRouterState state) {
final PatientEditArguments? args = KenLogger.success("MihGoRouter: patientProfileSetup");
state.extra as PatientEditArguments?; if (context.watch<MzansiProfileProvider>().user == null) {
if (args == null) {
WidgetsBinding.instance.addPostFrameCallback((_) { WidgetsBinding.instance.addPostFrameCallback((_) {
context.go(MihGoRouterPaths.mihHome); context.go(MihGoRouterPaths.mihHome);
}); });
return const SizedBox.shrink(); return const SizedBox.shrink();
} }
return EditPatient( return PatientSetUp();
signedInUser: args.signedInUser,
selectedPatient: args.selectedPatient,
);
}, },
), ),
GoRoute( GoRoute(
name: "patientManager", name: "patientManager",
path: MihGoRouterPaths.patientManager, path: MihGoRouterPaths.patientManager,
builder: (BuildContext context, GoRouterState state) { builder: (BuildContext context, GoRouterState state) {
final PatManagerArguments? args = state.extra as PatManagerArguments?; KenLogger.success("MihGoRouter: patientManager");
if (args == null) { if (context.watch<MzansiProfileProvider>().business == null) {
WidgetsBinding.instance.addPostFrameCallback((_) { WidgetsBinding.instance.addPostFrameCallback((_) {
context.go(MihGoRouterPaths.mihHome); context.go(MihGoRouterPaths.mihHome);
}); });
@@ -410,7 +375,6 @@ class MihGoRouter {
} }
return PatManager( return PatManager(
key: UniqueKey(), key: UniqueKey(),
arguments: args,
); );
}, },
), ),
@@ -418,15 +382,14 @@ class MihGoRouter {
name: "patientManagerPatient", name: "patientManagerPatient",
path: MihGoRouterPaths.patientManagerPatient, path: MihGoRouterPaths.patientManagerPatient,
builder: (BuildContext context, GoRouterState state) { builder: (BuildContext context, GoRouterState state) {
final PatientViewArguments? args = KenLogger.success("MihGoRouter: patientManagerPatient");
state.extra as PatientViewArguments?; if (context.watch<MzansiProfileProvider>().user == null) {
if (args == null) {
WidgetsBinding.instance.addPostFrameCallback((_) { WidgetsBinding.instance.addPostFrameCallback((_) {
context.go(MihGoRouterPaths.mihHome); context.go(MihGoRouterPaths.mihHome);
}); });
return const SizedBox.shrink(); return const SizedBox.shrink();
} }
return PatientProfile(arguments: args); return PatientProfile();
}, },
), ),
// ========================== Mzansi Directory ================================== // ========================== Mzansi Directory ==================================
@@ -434,15 +397,14 @@ class MihGoRouter {
name: "mzansiDirectory", name: "mzansiDirectory",
path: MihGoRouterPaths.mzansiDirectory, path: MihGoRouterPaths.mzansiDirectory,
builder: (BuildContext context, GoRouterState state) { builder: (BuildContext context, GoRouterState state) {
final MzansiDirectoryArguments? args = KenLogger.success("MihGoRouter: mzansiDirectory");
state.extra as MzansiDirectoryArguments?; if (context.watch<MzansiProfileProvider>().user == null) {
if (args == null) {
WidgetsBinding.instance.addPostFrameCallback((_) { WidgetsBinding.instance.addPostFrameCallback((_) {
context.go(MihGoRouterPaths.mihHome); context.go(MihGoRouterPaths.mihHome);
}); });
return const SizedBox.shrink(); return const SizedBox.shrink();
} }
return MzansiDirectory(arguments: args); return MzansiDirectory();
}, },
), ),
// ========================== End ================================== // ========================== End ==================================
@@ -450,6 +412,7 @@ class MihGoRouter {
name: "fileViewer", name: "fileViewer",
path: MihGoRouterPaths.fileViewer, path: MihGoRouterPaths.fileViewer,
builder: (BuildContext context, GoRouterState state) { builder: (BuildContext context, GoRouterState state) {
KenLogger.success("MihGoRouter: fileViewer");
final FileViewArguments? args = state.extra as FileViewArguments?; final FileViewArguments? args = state.extra as FileViewArguments?;
return FullScreenFileViewer(arguments: args!); return FullScreenFileViewer(arguments: args!);
}, },
@@ -458,11 +421,27 @@ class MihGoRouter {
name: "printPreview", name: "printPreview",
path: MihGoRouterPaths.printPreview, path: MihGoRouterPaths.printPreview,
builder: (BuildContext context, GoRouterState state) { builder: (BuildContext context, GoRouterState state) {
KenLogger.success("MihGoRouter: printPreview");
final PrintPreviewArguments? args = final PrintPreviewArguments? args =
state.extra as PrintPreviewArguments?; state.extra as PrintPreviewArguments?;
return MIHPrintPreview(arguments: args!); return MIHPrintPreview(arguments: args!);
}, },
), ),
// ========================== MIH Minesweeper ==================================
GoRoute(
name: "mihMinesweeper",
path: MihGoRouterPaths.mihMineSweeper,
builder: (BuildContext context, GoRouterState state) {
KenLogger.success("MihGoRouter: mihMineSweeper");
if (context.watch<MzansiProfileProvider>().user == null) {
WidgetsBinding.instance.addPostFrameCallback((_) {
context.go(MihGoRouterPaths.mihHome);
});
return const SizedBox.shrink();
}
return MihMineSweeper();
},
),
// ========================== End ================================== // ========================== End ==================================
// GoRoute( // GoRoute(
// name: "notifications", // name: "notifications",

View File

@@ -14,7 +14,7 @@ class MihTheme {
late String loadingAssetText; late String loadingAssetText;
late TargetPlatform platform; late TargetPlatform platform;
bool kIsWeb = const bool.fromEnvironment('dart.library.js_util'); bool kIsWeb = const bool.fromEnvironment('dart.library.js_util');
String latestVersion = "1.2.1"; String latestVersion = "1.2.2";
// Options:- // Options:-
// f3f9d2 = Cream // f3f9d2 = Cream
// f0f0c9 = cream2 // f0f0c9 = cream2

View File

@@ -1,19 +1,18 @@
import 'package:go_router/go_router.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.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_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_package_tools.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_providers/about_mih_provider.dart';
import 'package:mzansi_innovation_hub/mih_packages/about_mih/package_tools/mih_%20attributes.dart'; import 'package:mzansi_innovation_hub/mih_packages/about_mih/package_tools/mih_%20attributes.dart';
import 'package:mzansi_innovation_hub/mih_packages/about_mih/package_tools/mih_info.dart'; import 'package:mzansi_innovation_hub/mih_packages/about_mih/package_tools/mih_info.dart';
import 'package:mzansi_innovation_hub/mih_packages/about_mih/package_tools/mih_privacy_policy.dart'; import 'package:mzansi_innovation_hub/mih_packages/about_mih/package_tools/mih_privacy_policy.dart';
import 'package:mzansi_innovation_hub/mih_packages/about_mih/package_tools/mih_terms_of_service.dart'; import 'package:mzansi_innovation_hub/mih_packages/about_mih/package_tools/mih_terms_of_service.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class AboutMih extends StatefulWidget { class AboutMih extends StatefulWidget {
final AboutArguments? arguments;
const AboutMih({ const AboutMih({
super.key, super.key,
this.arguments,
}); });
@override @override
@@ -21,21 +20,9 @@ class AboutMih extends StatefulWidget {
} }
class _AboutMihState extends State<AboutMih> { class _AboutMihState extends State<AboutMih> {
late int _selcetedIndex;
late bool _personalSelected;
@override @override
void initState() { void initState() {
super.initState(); super.initState();
setState(() {
if (widget.arguments == null) {
_selcetedIndex = 0;
_personalSelected = true;
} else {
_selcetedIndex = widget.arguments!.packageIndex!;
_personalSelected = widget.arguments!.personalSelected;
}
});
} }
@override @override
@@ -45,12 +32,9 @@ class _AboutMihState extends State<AboutMih> {
appTools: getTools(), appTools: getTools(),
appBody: getToolBody(), appBody: getToolBody(),
appToolTitles: getToolTitle(), appToolTitles: getToolTitle(),
selectedbodyIndex: _selcetedIndex, selectedbodyIndex: context.watch<AboutMihProvider>().toolIndex,
onIndexChange: (newValue) { onIndexChange: (newIndex) {
setState(() { context.read<AboutMihProvider>().setToolIndex(newIndex);
_selcetedIndex = newValue;
});
// print("Index: $_selcetedIndex");
}, },
); );
} }
@@ -62,7 +46,6 @@ class _AboutMihState extends State<AboutMih> {
onTap: () { onTap: () {
context.goNamed( context.goNamed(
'mihHome', 'mihHome',
extra: _personalSelected,
); );
FocusScope.of(context).unfocus(); FocusScope.of(context).unfocus();
}, },
@@ -72,28 +55,20 @@ class _AboutMihState extends State<AboutMih> {
MihPackageTools getTools() { MihPackageTools getTools() {
Map<Widget, void Function()?> temp = {}; Map<Widget, void Function()?> temp = {};
temp[const Icon(Icons.info)] = () { temp[const Icon(Icons.info)] = () {
setState(() { context.read<AboutMihProvider>().setToolIndex(0);
_selcetedIndex = 0;
});
}; };
temp[const Icon(Icons.policy)] = () { temp[const Icon(Icons.policy)] = () {
setState(() { context.read<AboutMihProvider>().setToolIndex(1);
_selcetedIndex = 1;
});
}; };
temp[const Icon(Icons.design_services)] = () { temp[const Icon(Icons.design_services)] = () {
setState(() { context.read<AboutMihProvider>().setToolIndex(2);
_selcetedIndex = 2;
});
}; };
temp[const Icon(Icons.star_rounded)] = () { temp[const Icon(Icons.star_rounded)] = () {
setState(() { context.read<AboutMihProvider>().setToolIndex(3);
_selcetedIndex = 3;
});
}; };
return MihPackageTools( return MihPackageTools(
tools: temp, tools: temp,
selcetedIndex: _selcetedIndex, selcetedIndex: context.watch<AboutMihProvider>().toolIndex,
); );
} }

View File

@@ -1,6 +1,5 @@
import 'package:go_router/go_router.dart'; import 'package:go_router/go_router.dart';
import 'package:mzansi_innovation_hub/main.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_tile.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_tile.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.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_icons.dart';
@@ -8,11 +7,9 @@ import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart';
class AboutMihTile extends StatefulWidget { class AboutMihTile extends StatefulWidget {
final double packageSize; final double packageSize;
final bool personalSelected;
const AboutMihTile({ const AboutMihTile({
super.key, super.key,
required this.packageSize, required this.packageSize,
required this.personalSelected,
}); });
@override @override
@@ -26,10 +23,6 @@ class _AboutMihTileState extends State<AboutMihTile> {
onTap: () { onTap: () {
context.goNamed( context.goNamed(
"aboutMih", "aboutMih",
extra: AboutArguments(
widget.personalSelected,
0,
),
); );
// Navigator.of(context).pushNamed( // Navigator.of(context).pushNamed(
// '/about', // '/about',

View File

@@ -506,8 +506,8 @@ class _MihInfoState extends State<MihInfo> {
void shareMIHLink(BuildContext context, String message, String link) { void shareMIHLink(BuildContext context, String message, String link) {
String shareText = "$message: $link"; String shareText = "$message: $link";
Share.share( SharePlus.instance.share(
shareText, ShareParams(text: shareText),
); );
} }
@@ -610,7 +610,7 @@ class _MihInfoState extends State<MihInfo> {
), ),
const SizedBox(width: 10), const SizedBox(width: 10),
Text( Text(
"Users", "People",
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: TextStyle( style: TextStyle(
fontWeight: FontWeight.normal, fontWeight: FontWeight.normal,

View File

@@ -2,7 +2,10 @@ import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart'; import 'package:go_router/go_router.dart';
import 'package:ken_logger/ken_logger.dart'; import 'package:ken_logger/ken_logger.dart';
import 'package:mzansi_innovation_hub/main.dart'; import 'package:mzansi_innovation_hub/main.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_objects/patient_access.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_alert.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_providers/mih_access_controlls_provider.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_providers/mzansi_profile_provider.dart';
import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart'; import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_access_controls_services.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_button.dart';
@@ -10,18 +13,15 @@ import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_
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_error_message.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_warning_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_config/mih_env.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_objects/app_user.dart'; import 'package:provider/provider.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_objects/patient_access.dart';
class BuildBusinessAccessList extends StatefulWidget { class BuildBusinessAccessList extends StatefulWidget {
final List<PatientAccess> patientAccessList; final String filterText;
final AppUser signedInUser;
final void Function()? onSuccessUpate; final void Function()? onSuccessUpate;
const BuildBusinessAccessList({ const BuildBusinessAccessList({
super.key, super.key,
required this.patientAccessList, required this.filterText,
required this.signedInUser,
required this.onSuccessUpate, required this.onSuccessUpate,
}); });
@@ -60,18 +60,20 @@ class _BuildPatientsListState extends State<BuildBusinessAccessList> {
); );
} }
Widget displayQueue(int index) { Widget displayQueue(
String line1 = MzansiProfileProvider mzansiProfileProvider,
"Business Name: ${widget.patientAccessList[index].requested_by}"; MihAccessControllsProvider accessProvider,
int index,
List<PatientAccess> filteredList) {
String line1 = "Business Name: ${filteredList[index].requested_by}";
String line2 = ""; String line2 = "";
line2 += line2 +=
"Request Date: ${widget.patientAccessList[index].requested_on.substring(0, 16).replaceAll("T", " ")}\n"; "Request Date: ${filteredList[index].requested_on.substring(0, 16).replaceAll("T", " ")}\n";
line2 += line2 += "Profile Type: ${filteredList[index].type.toUpperCase()}\n";
"Profile Type: ${widget.patientAccessList[index].type.toUpperCase()}\n";
//subtitle += "Business Type: ${widget.patientAccessList[index].type}\n"; //subtitle += "Business Type: ${widget.patientAccessList[index].type}\n";
String line3 = "Status: "; String line3 = "Status: ";
String access = widget.patientAccessList[index].status.toUpperCase(); String access = filteredList[index].status.toUpperCase();
TextSpan accessWithColour; TextSpan accessWithColour;
if (access == "APPROVED") { if (access == "APPROVED") {
@@ -118,7 +120,7 @@ class _BuildPatientsListState extends State<BuildBusinessAccessList> {
// ), // ),
// ), // ),
onTap: () { onTap: () {
viewApprovalPopUp(index); viewApprovalPopUp(mzansiProfileProvider, accessProvider, index);
}, },
// trailing: Icon( // trailing: Icon(
// Icons.arrow_forward, // Icons.arrow_forward,
@@ -153,23 +155,24 @@ class _BuildPatientsListState extends State<BuildBusinessAccessList> {
} }
} }
void viewApprovalPopUp(int index) { void viewApprovalPopUp(MzansiProfileProvider mzansiProfileProvider,
MihAccessControllsProvider accessProvider, int index) {
String subtitle = String subtitle =
"Business Name: ${widget.patientAccessList[index].requested_by}\n"; "Business Name: ${accessProvider.accessList![index].requested_by}\n";
subtitle += subtitle +=
"Requested Date: ${widget.patientAccessList[index].requested_on.substring(0, 16).replaceAll("T", " ")}\n"; "Requested Date: ${accessProvider.accessList![index].requested_on.substring(0, 16).replaceAll("T", " ")}\n";
subtitle += subtitle +=
"Profile Type: ${widget.patientAccessList[index].type.toUpperCase()}\n"; "Profile Type: ${accessProvider.accessList![index].type.toUpperCase()}\n";
subtitle += subtitle +=
"Status: ${widget.patientAccessList[index].status.toUpperCase()}"; "Status: ${accessProvider.accessList![index].status.toUpperCase()}";
if (widget.patientAccessList[index].status == 'pending') { if (accessProvider.accessList![index].status == 'pending') {
// "\nYou are about to approve an access request to your patient profile.\nPlease be aware that once approved, ${widget.patientAccessList[index].requested_by} will have access to your profile forever and will be able to contribute to it.\nIf you are unsure about an upcoming appointment with ${widget.patientAccessList[index].requested_by}, please contact *Add Number here* for clarification before approving this request."; // "\nYou are about to approve an access request to your patient profile.\nPlease be aware that once approved, ${widget.patientAccessList[index].requested_by} will have access to your profile forever and will be able to contribute to it.\nIf you are unsure about an upcoming appointment with ${widget.patientAccessList[index].requested_by}, please contact *Add Number here* for clarification before approving this request.";
} else { } else {
subtitle += subtitle +=
"\nActioned By: ${widget.patientAccessList[index].approved_by}\n"; "\nActioned By: ${accessProvider.accessList![index].approved_by}\n";
subtitle += subtitle +=
"Actioned On: ${widget.patientAccessList[index].approved_on.substring(0, 16).replaceAll("T", " ")}"; "Actioned On: ${accessProvider.accessList![index].approved_on.substring(0, 16).replaceAll("T", " ")}";
// subtitle += // subtitle +=
// "You have approved this access request to your patient profile.\nPlease be aware that once approved, ${widget.patientAccessList[index].requested_by} will have access to your profile forever and will be able to contribute to it."; // "You have approved this access request to your patient profile.\nPlease be aware that once approved, ${widget.patientAccessList[index].requested_by} will have access to your profile forever and will be able to contribute to it.";
} }
@@ -199,7 +202,7 @@ class _BuildPatientsListState extends State<BuildBusinessAccessList> {
), ),
const SizedBox(height: 20.0), const SizedBox(height: 20.0),
Visibility( Visibility(
visible: widget.patientAccessList[index].status == 'pending', visible: accessProvider.accessList![index].status == 'pending',
child: Column( child: Column(
mainAxisSize: MainAxisSize.max, mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start,
@@ -271,7 +274,7 @@ class _BuildPatientsListState extends State<BuildBusinessAccessList> {
), ),
), ),
Visibility( Visibility(
visible: widget.patientAccessList[index].status == 'approved', visible: accessProvider.accessList![index].status == 'approved',
child: Column( child: Column(
mainAxisSize: MainAxisSize.max, mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start,
@@ -338,7 +341,7 @@ class _BuildPatientsListState extends State<BuildBusinessAccessList> {
height: 20, height: 20,
), ),
Visibility( Visibility(
visible: widget.patientAccessList[index].status == 'pending', visible: accessProvider.accessList![index].status == 'pending',
child: Wrap( child: Wrap(
runSpacing: 10, runSpacing: 10,
spacing: 10, spacing: 10,
@@ -348,15 +351,20 @@ class _BuildPatientsListState extends State<BuildBusinessAccessList> {
print("request declined"); print("request declined");
int statusCode = await MihAccessControlsServices() int statusCode = await MihAccessControlsServices()
.updatePatientAccessAPICall( .updatePatientAccessAPICall(
widget.patientAccessList[index].business_id, accessProvider.accessList![index].business_id,
widget.patientAccessList[index].requested_by, accessProvider.accessList![index].requested_by,
widget.patientAccessList[index].app_id, accessProvider.accessList![index].app_id,
"declined", "declined",
"${widget.signedInUser.fname} ${widget.signedInUser.lname}", "${mzansiProfileProvider.user!.fname} ${mzansiProfileProvider.user!.lname}",
widget.signedInUser, mzansiProfileProvider.user!,
context, context,
); );
if (statusCode == 200) { if (statusCode == 200) {
await MihAccessControlsServices()
.getBusinessAccessListOfPatient(
mzansiProfileProvider.user!.app_id,
accessProvider,
);
context.pop(); context.pop();
successPopUp("Successfully Actioned Request", successPopUp("Successfully Actioned Request",
"You have successfully Declined access request"); "You have successfully Declined access request");
@@ -384,15 +392,20 @@ class _BuildPatientsListState extends State<BuildBusinessAccessList> {
print("request approved"); print("request approved");
int statusCode = await MihAccessControlsServices() int statusCode = await MihAccessControlsServices()
.updatePatientAccessAPICall( .updatePatientAccessAPICall(
widget.patientAccessList[index].business_id, accessProvider.accessList![index].business_id,
widget.patientAccessList[index].requested_by, accessProvider.accessList![index].requested_by,
widget.patientAccessList[index].app_id, accessProvider.accessList![index].app_id,
"approved", "approved",
"${widget.signedInUser.fname} ${widget.signedInUser.lname}", "${mzansiProfileProvider.user!.fname} ${mzansiProfileProvider.user!.lname}",
widget.signedInUser, mzansiProfileProvider.user!,
context, context,
); );
if (statusCode == 200) { if (statusCode == 200) {
await MihAccessControlsServices()
.getBusinessAccessListOfPatient(
mzansiProfileProvider.user!.app_id,
accessProvider,
);
context.pop(); context.pop();
successPopUp("Successfully Actioned Request", successPopUp("Successfully Actioned Request",
"You have successfully Accepted access request"); "You have successfully Accepted access request");
@@ -487,6 +500,16 @@ class _BuildPatientsListState extends State<BuildBusinessAccessList> {
); );
} }
List<PatientAccess> filterAccessList(List<PatientAccess> accessList) {
if (widget.filterText == "All") {
return accessList;
}
return accessList
.where((item) =>
item.status.toLowerCase() == widget.filterText.toLowerCase())
.toList();
}
@override @override
void dispose() { void dispose() {
super.dispose(); super.dispose();
@@ -500,6 +523,11 @@ class _BuildPatientsListState extends State<BuildBusinessAccessList> {
height = size.height; height = size.height;
}); });
checkScreenSize(); checkScreenSize();
return Consumer2<MzansiProfileProvider, MihAccessControllsProvider>(
builder: (BuildContext context,
MzansiProfileProvider mzansiProfileProvider,
MihAccessControllsProvider accessProvider,
Widget? child) {
return ListView.separated( return ListView.separated(
shrinkWrap: true, shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(), physics: const NeverScrollableScrollPhysics(),
@@ -509,11 +537,15 @@ class _BuildPatientsListState extends State<BuildBusinessAccessList> {
MzansiInnovationHub.of(context)!.theme.mode == "Dark"), MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
); );
}, },
itemCount: widget.patientAccessList.length, itemCount: filterAccessList(accessProvider.accessList!).length,
itemBuilder: (context, index) { itemBuilder: (context, index) {
//final patient = widget.patients[index].id_no.contains(widget.searchString); //final patient = widget.patients[index].id_no.contains(widget.searchString);
//print(index); //print(index);
return displayQueue(index); final filteredList = filterAccessList(accessProvider.accessList!);
return displayQueue(
mzansiProfileProvider, accessProvider, index, filteredList);
},
);
}, },
); );
} }

View File

@@ -2,15 +2,14 @@ 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.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_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_package_tools.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_objects/app_user.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_providers/mih_access_controlls_provider.dart';
import 'package:mzansi_innovation_hub/mih_packages/access_review/package_tools/mih_access_requests.dart'; import 'package:mzansi_innovation_hub/mih_packages/access_review/package_tools/mih_access_requests.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class MihAccess extends StatefulWidget { class MihAccess extends StatefulWidget {
final AppUser signedInUser;
const MihAccess({ const MihAccess({
super.key, super.key,
required this.signedInUser,
}); });
@override @override
@@ -18,7 +17,6 @@ class MihAccess extends StatefulWidget {
} }
class _MihAccessState extends State<MihAccess> { class _MihAccessState extends State<MihAccess> {
int _selcetedIndex = 0;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return MihPackage( return MihPackage(
@@ -26,12 +24,9 @@ class _MihAccessState extends State<MihAccess> {
appTools: getTools(), appTools: getTools(),
appBody: getToolBody(), appBody: getToolBody(),
appToolTitles: getToolTitle(), appToolTitles: getToolTitle(),
selectedbodyIndex: _selcetedIndex, selectedbodyIndex: context.watch<MihAccessControllsProvider>().toolIndex,
onIndexChange: (newValue) { onIndexChange: (newValue) {
setState(() { context.read<MihAccessControllsProvider>().setToolIndex(newValue);
_selcetedIndex = newValue;
});
print("Index: $_selcetedIndex");
}, },
); );
} }
@@ -43,7 +38,6 @@ class _MihAccessState extends State<MihAccess> {
onTap: () { onTap: () {
context.goNamed( context.goNamed(
'mihHome', 'mihHome',
extra: true,
); );
FocusScope.of(context).unfocus(); FocusScope.of(context).unfocus();
}, },
@@ -53,21 +47,17 @@ class _MihAccessState extends State<MihAccess> {
MihPackageTools getTools() { MihPackageTools getTools() {
Map<Widget, void Function()?> temp = {}; Map<Widget, void Function()?> temp = {};
temp[const Icon(Icons.people)] = () { temp[const Icon(Icons.people)] = () {
setState(() { context.read<MihAccessControllsProvider>().setToolIndex(0);
_selcetedIndex = 0;
});
}; };
return MihPackageTools( return MihPackageTools(
tools: temp, tools: temp,
selcetedIndex: _selcetedIndex, selcetedIndex: context.watch<MihAccessControllsProvider>().toolIndex,
); );
} }
List<Widget> getToolBody() { List<Widget> getToolBody() {
List<Widget> toolBodies = [ List<Widget> toolBodies = [
MihAccessRequest( MihAccessRequest(),
signedInUser: widget.signedInUser,
),
]; ];
return toolBodies; return toolBodies;
} }

View File

@@ -2,17 +2,14 @@ import 'package:go_router/go_router.dart';
import 'package:mzansi_innovation_hub/main.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_package_tile.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_icons.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_objects/app_user.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart'; import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart';
class MihAccessTile extends StatefulWidget { class MihAccessTile extends StatefulWidget {
final AppUser signedInUser;
final double packageSize; final double packageSize;
const MihAccessTile({ const MihAccessTile({
super.key, super.key,
required this.signedInUser,
required this.packageSize, required this.packageSize,
}); });
@@ -28,7 +25,6 @@ class _MihAccessTileState extends State<MihAccessTile> {
onTap: () { onTap: () {
context.goNamed( context.goNamed(
"mihAccess", "mihAccess",
extra: widget.signedInUser,
); );
// Navigator.of(context).pushNamed( // Navigator.of(context).pushNamed(
// '/mih-access', // '/mih-access',

View File

@@ -1,28 +1,24 @@
import 'package:go_router/go_router.dart'; import 'package:go_router/go_router.dart';
import 'package:ken_logger/ken_logger.dart'; import 'package:ken_logger/ken_logger.dart';
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_package_components/mih_icons.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_layout/mih_header.dart';
import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_objects/patient_access.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_loading_circle.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_providers/mih_access_controlls_provider.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_providers/mzansi_profile_provider.dart';
import 'package:mzansi_innovation_hub/mih_config/mih_env.dart';
import 'package:mzansi_innovation_hub/mih_packages/access_review/builder/build_business_access_list.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_access_controls_services.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_validation_services.dart'; import 'package:mzansi_innovation_hub/mih_services/mih_validation_services.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_single_child_scroll.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_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_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_package_components/mih_package_tool_body.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import '../../../mih_services/mih_service_calls.dart'; import 'package:provider/provider.dart';
import '../../../mih_components/mih_layout/mih_action.dart';
import '../../../mih_components/mih_layout/mih_header.dart';
import '../../../mih_components/mih_pop_up_messages/mih_loading_circle.dart';
import '../../../mih_config/mih_env.dart';
import '../../../mih_components/mih_objects/app_user.dart';
import '../../../mih_components/mih_objects/patient_access.dart';
import '../builder/build_business_access_list.dart';
class MihAccessRequest extends StatefulWidget { class MihAccessRequest extends StatefulWidget {
final AppUser signedInUser;
const MihAccessRequest({ const MihAccessRequest({
super.key, super.key,
required this.signedInUser,
}); });
@override @override
@@ -31,7 +27,7 @@ class MihAccessRequest extends StatefulWidget {
class _MihAccessRequestState extends State<MihAccessRequest> { class _MihAccessRequestState extends State<MihAccessRequest> {
TextEditingController filterController = TextEditingController(); TextEditingController filterController = TextEditingController();
bool isLoading = true;
String baseUrl = AppEnviroment.baseApiUrl; String baseUrl = AppEnviroment.baseApiUrl;
String errorCode = ""; String errorCode = "";
@@ -41,35 +37,8 @@ class _MihAccessRequestState extends State<MihAccessRequest> {
bool forceRefresh = false; bool forceRefresh = false;
late String selectedDropdown; late String selectedDropdown;
late Future<List<PatientAccess>> accessList;
// Future<List<AccessRequest>> fetchAccessRequests() async {
// //print("Patien manager page: $endpoint");
// final response = await http.get(
// Uri.parse("$baseUrl/access-requests/${widget.signedInUser.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<AccessRequest> patientQueue = List<AccessRequest>.from(
// l.map((model) => AccessRequest.fromJson(model)));
// //print("Here3");
// //print(patientQueue);
// return patientQueue;
// } else {
// throw Exception('failed to load patients');
// }
// }
List<PatientAccess> filterSearchResults(List<PatientAccess> accessList) { List<PatientAccess> filterSearchResults(List<PatientAccess> accessList) {
List<PatientAccess> templist = []; List<PatientAccess> templist = [];
for (var item in accessList) { for (var item in accessList) {
if (filterController.text == "All") { if (filterController.text == "All") {
templist.add(item); templist.add(item);
@@ -83,16 +52,24 @@ class _MihAccessRequestState extends State<MihAccessRequest> {
} }
void refreshList() { void refreshList() {
MzansiProfileProvider mzansiProfileProvider =
context.read<MzansiProfileProvider>();
MihAccessControllsProvider accessProvider =
context.read<MihAccessControllsProvider>();
if (forceRefresh == true) { if (forceRefresh == true) {
MihAccessControlsServices().getBusinessAccessListOfPatient(
mzansiProfileProvider.user!.app_id,
accessProvider,
);
setState(() { setState(() {
accessList = MIHApiCalls.getBusinessAccessListOfPatient(
widget.signedInUser.app_id);
forceRefresh = false; forceRefresh = false;
}); });
} else if (selectedDropdown != filterController.text) { } else if (selectedDropdown != filterController.text) {
MihAccessControlsServices().getBusinessAccessListOfPatient(
mzansiProfileProvider.user!.app_id,
accessProvider,
);
setState(() { setState(() {
accessList = MIHApiCalls.getBusinessAccessListOfPatient(
widget.signedInUser.app_id);
selectedDropdown = filterController.text; selectedDropdown = filterController.text;
}); });
} }
@@ -131,6 +108,16 @@ class _MihAccessRequestState extends State<MihAccessRequest> {
} }
Widget getBody() { Widget getBody() {
return Consumer2<MzansiProfileProvider, MihAccessControllsProvider>(
builder: (BuildContext context,
MzansiProfileProvider mzansiProfileProvider,
MihAccessControllsProvider accessProvider,
Widget? child) {
if (isLoading) {
return const Center(
child: Mihloadingcircle(),
);
}
return MihSingleChildScroll( return MihSingleChildScroll(
child: Column( child: Column(
children: [ children: [
@@ -174,121 +161,37 @@ class _MihAccessRequestState extends State<MihAccessRequest> {
], ],
), ),
const SizedBox(height: 10), const SizedBox(height: 10),
FutureBuilder( BuildBusinessAccessList(
future: accessList, filterText: filterController.text,
builder: (context, snapshot) {
//print("patient Queue List ${snapshot.hasData}");
if (snapshot.connectionState == ConnectionState.waiting) {
return const Mihloadingcircle();
} else if (snapshot.connectionState == ConnectionState.done) {
List<PatientAccess> accessRequestList;
accessRequestList = filterSearchResults(snapshot.requireData);
if (accessRequestList.isNotEmpty) {
return BuildBusinessAccessList(
signedInUser: widget.signedInUser,
patientAccessList: accessRequestList,
onSuccessUpate: () { onSuccessUpate: () {
setState(() { setState(() {
forceRefresh = true; forceRefresh = true;
}); });
refreshList(); refreshList();
}, },
);
} else {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 10.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
const SizedBox(height: 50),
Icon(
MihIcons.accessControl,
size: 165,
color: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
), ),
const SizedBox(height: 10),
Text(
"No access has been granted to your MIH 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: 10),
// Center(
// child: RichText(
// textAlign: TextAlign.center,
// text: TextSpan(
// style: TextStyle(
// fontSize: 20,
// fontWeight: FontWeight.normal,
// color: MzansiInnovationHub.of(context)!
// .theme
// .secondaryColor(),
// ),
// children: [
// TextSpan(text: "Press "),
// WidgetSpan(
// alignment: PlaceholderAlignment.middle,
// child: Icon(
// Icons.menu,
// size: 20,
// color: MzansiInnovationHub.of(context)!
// .theme
// .secondaryColor(),
// ),
// ),
// TextSpan(
// text: " to add your first loyalty card."),
// ],
// ),
// ),
// ),
], ],
), ),
); );
// return Center( },
// child: Text( );
// "No Request have been made.",
// style: TextStyle(
// fontSize: 25,
// color: MzansiInnovationHub.of(context)!
// .theme
// .messageTextColor()),
// textAlign: TextAlign.center,
// ),
// );
} }
// return Expanded( Future<void> initiasizeAccessList() async {
// child: displayAccessRequestList(accessRequestList), MzansiProfileProvider mzansiProfileProvider =
// ); context.read<MzansiProfileProvider>();
} else { MihAccessControllsProvider accessProvider =
return Center( context.read<MihAccessControllsProvider>();
child: Text( setState(() {
"$errorCode: Error pulling Patients Data\n$baseUrl/queue/patients/\n$errorBody", isLoading = true;
style: TextStyle( });
fontSize: 25, await MihAccessControlsServices().getBusinessAccessListOfPatient(
color: MihColors.getGreenColor( mzansiProfileProvider.user!.app_id,
MzansiInnovationHub.of(context)!.theme.mode == accessProvider,
"Dark")),
textAlign: TextAlign.center,
),
);
}
},
),
],
),
); );
setState(() {
isLoading = false;
});
} }
@override @override
@@ -302,9 +205,8 @@ class _MihAccessRequestState extends State<MihAccessRequest> {
selectedDropdown = "All"; selectedDropdown = "All";
filterController.text = "All"; filterController.text = "All";
filterController.addListener(refreshList); filterController.addListener(refreshList);
setState(() { WidgetsBinding.instance.addPostFrameCallback((_) async {
accessList = MIHApiCalls.getBusinessAccessListOfPatient( await initiasizeAccessList();
widget.signedInUser.app_id);
}); });
super.initState(); super.initState();
} }

View File

@@ -2,16 +2,17 @@ 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.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_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_package_tools.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_providers/mih_calculator_provider.dart';
import 'package:mzansi_innovation_hub/mih_packages/calculator/package_tools/currency_exchange_rate.dart'; import 'package:mzansi_innovation_hub/mih_packages/calculator/package_tools/currency_exchange_rate.dart';
import 'package:mzansi_innovation_hub/mih_packages/calculator/package_tools/simple_calc.dart'; import 'package:mzansi_innovation_hub/mih_packages/calculator/package_tools/simple_calc.dart';
import 'package:mzansi_innovation_hub/mih_packages/calculator/package_tools/tip_calc.dart'; import 'package:mzansi_innovation_hub/mih_packages/calculator/package_tools/tip_calc.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_currency_exchange_rate_services.dart';
import 'package:provider/provider.dart';
class MIHCalculator extends StatefulWidget { class MIHCalculator extends StatefulWidget {
final bool personalSelected;
const MIHCalculator({ const MIHCalculator({
super.key, super.key,
required this.personalSelected,
}); });
@override @override
@@ -19,7 +20,17 @@ class MIHCalculator extends StatefulWidget {
} }
class _MIHCalculatorState extends State<MIHCalculator> { class _MIHCalculatorState extends State<MIHCalculator> {
int _selectedIndex = 0; Future<void> getCurrencyCodeList() async {
await MihCurrencyExchangeRateServices.getCurrencyCodeList(context);
}
@override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) async {
await getCurrencyCodeList();
});
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@@ -28,12 +39,9 @@ class _MIHCalculatorState extends State<MIHCalculator> {
appTools: getTools(), appTools: getTools(),
appBody: getToolBody(), appBody: getToolBody(),
appToolTitles: getToolTitle(), appToolTitles: getToolTitle(),
selectedbodyIndex: _selectedIndex, selectedbodyIndex: context.watch<MihCalculatorProvider>().toolIndex,
onIndexChange: (newValue) { onIndexChange: (newIndex) {
setState(() { context.read<MihCalculatorProvider>().setToolIndex(newIndex);
_selectedIndex = newValue;
});
print("Index: $_selectedIndex");
}, },
); );
} }
@@ -45,7 +53,6 @@ class _MIHCalculatorState extends State<MIHCalculator> {
onTap: () { onTap: () {
context.goNamed( context.goNamed(
'mihHome', 'mihHome',
extra: widget.personalSelected,
); );
FocusScope.of(context).unfocus(); FocusScope.of(context).unfocus();
}, },
@@ -55,23 +62,17 @@ class _MIHCalculatorState extends State<MIHCalculator> {
MihPackageTools getTools() { MihPackageTools getTools() {
Map<Widget, void Function()?> temp = {}; Map<Widget, void Function()?> temp = {};
temp[const Icon(Icons.calculate)] = () { temp[const Icon(Icons.calculate)] = () {
setState(() { context.read<MihCalculatorProvider>().setToolIndex(0);
_selectedIndex = 0;
});
}; };
temp[const Icon(Icons.money)] = () { temp[const Icon(Icons.money)] = () {
setState(() { context.read<MihCalculatorProvider>().setToolIndex(1);
_selectedIndex = 1;
});
}; };
temp[const Icon(Icons.currency_exchange)] = () { temp[const Icon(Icons.currency_exchange)] = () {
setState(() { context.read<MihCalculatorProvider>().setToolIndex(2);
_selectedIndex = 2;
});
}; };
return MihPackageTools( return MihPackageTools(
tools: temp, tools: temp,
selcetedIndex: _selectedIndex, selcetedIndex: context.watch<MihCalculatorProvider>().toolIndex,
); );
} }

View File

@@ -6,12 +6,10 @@ import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_
import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart'; import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart';
class MihCalculatorTile extends StatefulWidget { class MihCalculatorTile extends StatefulWidget {
final bool personalSelected;
final double packageSize; final double packageSize;
const MihCalculatorTile({ const MihCalculatorTile({
super.key, super.key,
required this.personalSelected,
required this.packageSize, required this.packageSize,
}); });
@@ -26,12 +24,7 @@ class _MihCalculatorTileState extends State<MihCalculatorTile> {
onTap: () { onTap: () {
context.goNamed( context.goNamed(
"mihCalculator", "mihCalculator",
extra: widget.personalSelected,
); );
// Navigator.of(context).pushNamed(
// '/calculator',
// arguments: widget.personalSelected,
// );
}, },
appName: "Calculator", appName: "Calculator",
appIcon: Icon( appIcon: Icon(

View File

@@ -9,11 +9,12 @@ import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_
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_package_window.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_single_child_scroll.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_single_child_scroll.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_text_form_field.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_text_form_field.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_loading_circle.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_providers/mih_calculator_provider.dart';
import 'package:mzansi_innovation_hub/mih_config/mih_colors.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_alert_services.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_currency_exchange_rate_services.dart'; import 'package:mzansi_innovation_hub/mih_services/mih_currency_exchange_rate_services.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_validation_services.dart'; import 'package:mzansi_innovation_hub/mih_services/mih_validation_services.dart';
import 'package:provider/provider.dart';
class CurrencyExchangeRate extends StatefulWidget { class CurrencyExchangeRate extends StatefulWidget {
const CurrencyExchangeRate({super.key}); const CurrencyExchangeRate({super.key});
@@ -28,8 +29,6 @@ class _CurrencyExchangeRateState extends State<CurrencyExchangeRate> {
final TextEditingController _toCurrencyController = TextEditingController(); final TextEditingController _toCurrencyController = TextEditingController();
final TextEditingController _fromAmountController = TextEditingController(); final TextEditingController _fromAmountController = TextEditingController();
final TextEditingController _toAmountController = TextEditingController(); final TextEditingController _toAmountController = TextEditingController();
late Future<List<String>> availableCurrencies;
MihBannerAd _bannerAd = MihBannerAd();
Future<void> submitForm() async { Future<void> submitForm() async {
String fromCurrencyCode = _fromCurrencyController.text.split(" - ")[0]; String fromCurrencyCode = _fromCurrencyController.text.split(" - ")[0];
@@ -67,9 +66,6 @@ class _CurrencyExchangeRateState extends State<CurrencyExchangeRate> {
fullscreen: false, fullscreen: false,
windowTitle: "Calculation Results", windowTitle: "Calculation Results",
onWindowTapClose: () { onWindowTapClose: () {
setState(() {
_bannerAd = MihBannerAd();
});
Navigator.pop(context); Navigator.pop(context);
}, },
windowBody: Column( windowBody: Column(
@@ -160,7 +156,9 @@ class _CurrencyExchangeRateState extends State<CurrencyExchangeRate> {
], ],
), ),
SizedBox(height: 10), SizedBox(height: 10),
SizedBox(child: _bannerAd), Consumer(builder: (context, bannerAdDisplay, child) {
return MihBannerAd();
}),
], ],
), ),
), ),
@@ -275,7 +273,6 @@ class _CurrencyExchangeRateState extends State<CurrencyExchangeRate> {
@override @override
void initState() { void initState() {
super.initState(); super.initState();
availableCurrencies = MihCurrencyExchangeRateServices.getCurrencyCodeList();
} }
@override @override
@@ -289,16 +286,12 @@ class _CurrencyExchangeRateState extends State<CurrencyExchangeRate> {
} }
Widget getBody(double width) { Widget getBody(double width) {
return FutureBuilder( return Consumer<MihCalculatorProvider>(
future: availableCurrencies, builder: (context, calculatorProvider, child) {
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const Mihloadingcircle();
} else if (snapshot.connectionState == ConnectionState.done) {
return MihSingleChildScroll( return MihSingleChildScroll(
child: Padding( child: Padding(
padding: MzansiInnovationHub.of(context)!.theme.screenType == padding:
"desktop" MzansiInnovationHub.of(context)!.theme.screenType == "desktop"
? EdgeInsets.symmetric(horizontal: width * 0.2) ? EdgeInsets.symmetric(horizontal: width * 0.2)
: EdgeInsets.symmetric(horizontal: width * 0.075), : EdgeInsets.symmetric(horizontal: width * 0.075),
child: Column( child: Column(
@@ -326,7 +319,7 @@ class _CurrencyExchangeRateState extends State<CurrencyExchangeRate> {
MihDropdownField( MihDropdownField(
controller: _fromCurrencyController, controller: _fromCurrencyController,
hintText: "From", hintText: "From",
dropdownOptions: snapshot.data!, dropdownOptions: calculatorProvider.availableCurrencies,
editable: true, editable: true,
enableSearch: true, enableSearch: true,
validator: (value) { validator: (value) {
@@ -338,7 +331,7 @@ class _CurrencyExchangeRateState extends State<CurrencyExchangeRate> {
MihDropdownField( MihDropdownField(
controller: _toCurrencyController, controller: _toCurrencyController,
hintText: "To", hintText: "To",
dropdownOptions: snapshot.data!, dropdownOptions: calculatorProvider.availableCurrencies,
editable: true, editable: true,
enableSearch: true, enableSearch: true,
validator: (value) { validator: (value) {
@@ -358,16 +351,13 @@ class _CurrencyExchangeRateState extends State<CurrencyExchangeRate> {
), ),
children: [ children: [
const TextSpan( const TextSpan(
text: text: "* Experimental Feature: Please review "),
"* Experimental Feature: Please review "),
TextSpan( TextSpan(
text: "Diclaimer", text: "Diclaimer",
style: TextStyle( style: TextStyle(
decoration: TextDecoration.underline, decoration: TextDecoration.underline,
color: MihColors.getSecondaryColor( color: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)! MzansiInnovationHub.of(context)!.theme.mode ==
.theme
.mode ==
"Dark"), "Dark"),
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
), ),
@@ -398,9 +388,7 @@ class _CurrencyExchangeRateState extends State<CurrencyExchangeRate> {
} }
}, },
buttonColor: MihColors.getGreenColor( buttonColor: MihColors.getGreenColor(
MzansiInnovationHub.of(context)! MzansiInnovationHub.of(context)!.theme.mode ==
.theme
.mode ==
"Dark"), "Dark"),
width: 300, width: 300,
child: Text( child: Text(
@@ -421,9 +409,7 @@ class _CurrencyExchangeRateState extends State<CurrencyExchangeRate> {
clearInput(); clearInput();
}, },
buttonColor: MihColors.getRedColor( buttonColor: MihColors.getRedColor(
MzansiInnovationHub.of(context)! MzansiInnovationHub.of(context)!.theme.mode ==
.theme
.mode ==
"Dark"), "Dark"),
width: 300, width: 300,
child: Text( child: Text(
@@ -448,18 +434,7 @@ class _CurrencyExchangeRateState extends State<CurrencyExchangeRate> {
), ),
), ),
); );
} else { },
return Center(
child: Text(
"Error pulling Currency Exchange Data.",
style: TextStyle(
fontSize: 25,
color: MihColors.getRedColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark")),
textAlign: TextAlign.center,
),
); );
} }
});
}
} }

View File

@@ -14,6 +14,7 @@ import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:math_expressions/math_expressions.dart'; import 'package:math_expressions/math_expressions.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_toggle.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_toggle.dart';
import 'package:provider/provider.dart';
class TipCalc extends StatefulWidget { class TipCalc extends StatefulWidget {
const TipCalc({super.key}); const TipCalc({super.key});
@@ -30,7 +31,6 @@ class _TipCalcState extends State<TipCalc> {
final ValueNotifier<String> splitValue = ValueNotifier(""); final ValueNotifier<String> splitValue = ValueNotifier("");
late bool splitPosition; late bool splitPosition;
final _formKey = GlobalKey<FormState>(); final _formKey = GlobalKey<FormState>();
MihBannerAd _bannerAd = MihBannerAd();
String tip = ""; String tip = "";
String total = ""; String total = "";
String amountPerPerson = ""; String amountPerPerson = "";
@@ -98,9 +98,6 @@ class _TipCalcState extends State<TipCalc> {
fullscreen: false, fullscreen: false,
windowTitle: "Calculation Results", windowTitle: "Calculation Results",
onWindowTapClose: () { onWindowTapClose: () {
setState(() {
_bannerAd = MihBannerAd();
});
Navigator.pop(context); Navigator.pop(context);
}, },
windowBody: Column( windowBody: Column(
@@ -231,7 +228,9 @@ class _TipCalcState extends State<TipCalc> {
), ),
), ),
SizedBox(height: 10), SizedBox(height: 10),
SizedBox(child: _bannerAd), Consumer(builder: (context, bannerAdDisplay, child) {
return MihBannerAd();
}),
// if (splitBillController.text == "Yes") const Divider(), // if (splitBillController.text == "Yes") const Divider(),
], ],
), ),

View File

@@ -2,8 +2,10 @@ import 'package:flutter_speed_dial/flutter_speed_dial.dart';
import 'package:go_router/go_router.dart'; import 'package:go_router/go_router.dart';
import 'package:ken_logger/ken_logger.dart'; import 'package:ken_logger/ken_logger.dart';
import 'package:mzansi_innovation_hub/main.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/appointment.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_alert.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_providers/mih_calendar_provider.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_providers/mzansi_profile_provider.dart';
import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart'; import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_alert_services.dart'; import 'package:mzansi_innovation_hub/mih_services/mih_alert_services.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_mzansi_calendar_services.dart'; import 'package:mzansi_innovation_hub/mih_services/mih_mzansi_calendar_services.dart';
@@ -17,18 +19,10 @@ 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_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_error_message.dart';
import 'package:mzansi_innovation_hub/mih_config/mih_env.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/appointment.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 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class BuildAppointmentList extends StatefulWidget { class BuildAppointmentList extends StatefulWidget {
final List<Appointment> appointmentList;
final AppUser signedInUser;
final Business? business;
final BusinessUser? businessUser;
final bool personalSelected;
final bool inWaitingRoom; final bool inWaitingRoom;
final TextEditingController titleController; final TextEditingController titleController;
final TextEditingController descriptionIDController; final TextEditingController descriptionIDController;
@@ -38,11 +32,6 @@ class BuildAppointmentList extends StatefulWidget {
const BuildAppointmentList({ const BuildAppointmentList({
super.key, super.key,
required this.appointmentList,
required this.signedInUser,
required this.business,
required this.businessUser,
required this.personalSelected,
required this.inWaitingRoom, required this.inWaitingRoom,
required this.titleController, required this.titleController,
required this.descriptionIDController, required this.descriptionIDController,
@@ -69,6 +58,13 @@ class _BuildAppointmentListState extends State<BuildAppointmentList> {
late double width; late double width;
late double height; late double height;
void clearControllers() {
widget.titleController.clear();
widget.descriptionIDController.clear();
widget.dateController.clear();
widget.timeController.clear();
}
double getPaddingSize() { double getPaddingSize() {
if (MzansiInnovationHub.of(context)!.theme.screenType == "desktop") { if (MzansiInnovationHub.of(context)!.theme.screenType == "desktop") {
return (width / 10); return (width / 10);
@@ -77,25 +73,46 @@ class _BuildAppointmentListState extends State<BuildAppointmentList> {
} }
} }
Widget displayAppointment(int index, double bodyWidth) { Widget displayAppointment(MzansiProfileProvider mzansiProfileProvider,
MihCalendarProvider mihCalendarProvider, int index, double bodyWidth) {
List<Appointment> appointmentList = mzansiProfileProvider.personalHome
? mihCalendarProvider.personalAppointments!
: mihCalendarProvider.businessAppointments!;
// SAFELY EXTRACT DATE AND TIME
String dateTimeString = appointmentList[index].date_time;
String timePart = "";
String datePart = "";
if (dateTimeString.contains("T")) {
List<String> parts = dateTimeString.split('T');
datePart = parts[0];
timePart = parts[1].substring(0, 5);
} else if (dateTimeString.contains(" ")) {
List<String> parts = dateTimeString.split(' ');
datePart = parts[0];
timePart = parts[1].substring(0, 5);
} else {
// Fallback if format is unexpected
datePart = dateTimeString;
timePart = "00:00";
}
String heading = String heading =
"${widget.appointmentList[index].date_time.split('T')[1].substring(0, 5)} - ${widget.appointmentList[index].title.toUpperCase()}"; "$timePart - ${appointmentList[index].title.toUpperCase()}";
String description = widget.appointmentList[index].description; String description = appointmentList[index].description;
DateTime now = new DateTime.now();
DateTime now = DateTime.now();
int hourNow = int.parse(now.toString().split(' ')[1].substring(0, 2)); int hourNow = int.parse(now.toString().split(' ')[1].substring(0, 2));
String date = String currentDate =
new DateTime(now.year, now.month, now.day).toString().split(' ')[0]; DateTime(now.year, now.month, now.day).toString().split(' ')[0];
String appointDate = widget.appointmentList[index].date_time.split('T')[0];
int appointHour = int.parse( int appointHour = int.parse(timePart.split(':')[0]);
widget.appointmentList[index].date_time.split('T')[1].substring(0, 2));
// print("Date Time Now: $now");
// print("Hour Now: $hourNow");
// print("Date: $date");
// print("Appointment Date: $appointDate");
// print("Appointment Hour: $appointHour");
Color appointmentColor = MihColors.getSecondaryColor( Color appointmentColor = MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"); MzansiInnovationHub.of(context)!.theme.mode == "Dark");
if (date == appointDate) {
if (currentDate == datePart) {
if (appointHour < hourNow) { if (appointHour < hourNow) {
appointmentColor = MihColors.getGreyColor( appointmentColor = MihColors.getGreyColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"); MzansiInnovationHub.of(context)!.theme.mode == "Dark");
@@ -103,7 +120,7 @@ class _BuildAppointmentListState extends State<BuildAppointmentList> {
appointmentColor = MihColors.getGreenColor( appointmentColor = MihColors.getGreenColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"); MzansiInnovationHub.of(context)!.theme.mode == "Dark");
} }
} else if (DateTime.parse(appointDate).isBefore(DateTime.parse(date))) { } else if (DateTime.parse(datePart).isBefore(DateTime.parse(currentDate))) {
appointmentColor = MihColors.getGreyColor( appointmentColor = MihColors.getGreyColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"); MzansiInnovationHub.of(context)!.theme.mode == "Dark");
} }
@@ -131,27 +148,29 @@ class _BuildAppointmentListState extends State<BuildAppointmentList> {
), ),
), ),
onTap: () { onTap: () {
// SAFELY SET CONTROLLER VALUES
setState(() { setState(() {
widget.titleController.text = widget.appointmentList[index].title; widget.titleController.text = appointmentList[index].title;
widget.descriptionIDController.text = widget.descriptionIDController.text =
widget.appointmentList[index].description; appointmentList[index].description;
widget.dateController.text = widget.dateController.text = datePart;
widget.appointmentList[index].date_time.split('T')[0]; widget.timeController.text = timePart;
widget.timeController.text = widget.appointmentList[index].date_time
.split('T')[1]
.substring(0, 5);
}); });
if (widget.inWaitingRoom == false) { if (widget.inWaitingRoom == false) {
appointmentDetailsWindow(index, bodyWidth); appointmentDetailsWindow(
mzansiProfileProvider, mihCalendarProvider, index, bodyWidth);
} else { } else {
waitingRiinAppointmentDetailsWindow(index, bodyWidth); waitingRoomAppointmentDetailsWindow(
mzansiProfileProvider, mihCalendarProvider, index, bodyWidth);
} }
}, },
), ),
); );
} }
void appointmentDetailsWindow(int index, double bodyWidth) { void appointmentDetailsWindow(MzansiProfileProvider mzansiProfileProvider,
MihCalendarProvider mihCalendarProvider, int index, double bodyWidth) {
showDialog( showDialog(
context: context, context: context,
barrierDismissible: false, barrierDismissible: false,
@@ -177,7 +196,8 @@ class _BuildAppointmentListState extends State<BuildAppointmentList> {
backgroundColor: MihColors.getGreenColor( backgroundColor: MihColors.getGreenColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"), MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
onTap: () { onTap: () {
appointmentUpdateWindow(index, bodyWidth); appointmentUpdateWindow(mzansiProfileProvider,
mihCalendarProvider, index, bodyWidth);
}, },
), ),
SpeedDialChild( SpeedDialChild(
@@ -197,16 +217,14 @@ class _BuildAppointmentListState extends State<BuildAppointmentList> {
backgroundColor: MihColors.getGreenColor( backgroundColor: MihColors.getGreenColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"), MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
onTap: () { onTap: () {
deleteAppointmentConfirmationWindow(index); deleteAppointmentConfirmationWindow(
mzansiProfileProvider, mihCalendarProvider, index);
}, },
), ),
], ],
onWindowTapClose: () { onWindowTapClose: () {
context.pop(); context.pop();
widget.dateController.clear(); clearControllers();
widget.timeController.clear();
widget.titleController.clear();
widget.descriptionIDController.clear();
}, },
windowBody: Padding( windowBody: Padding(
padding: padding:
@@ -273,7 +291,11 @@ class _BuildAppointmentListState extends State<BuildAppointmentList> {
); );
} }
void waitingRiinAppointmentDetailsWindow(int index, double bodyWidth) { void waitingRoomAppointmentDetailsWindow(
MzansiProfileProvider mzansiProfileProvider,
MihCalendarProvider mihCalendarProvider,
int index,
double bodyWidth) {
showDialog( showDialog(
context: context, context: context,
barrierDismissible: false, barrierDismissible: false,
@@ -299,7 +321,8 @@ class _BuildAppointmentListState extends State<BuildAppointmentList> {
backgroundColor: MihColors.getGreenColor( backgroundColor: MihColors.getGreenColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"), MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
onTap: () { onTap: () {
appointmentUpdateWindow(index, bodyWidth); appointmentUpdateWindow(mzansiProfileProvider,
mihCalendarProvider, index, bodyWidth);
}, },
), ),
SpeedDialChild( SpeedDialChild(
@@ -319,16 +342,14 @@ class _BuildAppointmentListState extends State<BuildAppointmentList> {
backgroundColor: MihColors.getGreenColor( backgroundColor: MihColors.getGreenColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"), MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
onTap: () { onTap: () {
deleteAppointmentConfirmationWindow(index); deleteAppointmentConfirmationWindow(
mzansiProfileProvider, mihCalendarProvider, index);
}, },
), ),
], ],
onWindowTapClose: () { onWindowTapClose: () {
context.pop(); context.pop();
widget.dateController.clear(); clearControllers();
widget.timeController.clear();
widget.titleController.clear();
widget.descriptionIDController.clear();
}, },
windowBody: Padding( windowBody: Padding(
padding: padding:
@@ -405,7 +426,11 @@ class _BuildAppointmentListState extends State<BuildAppointmentList> {
); );
} }
void appointmentUpdateWindow(int index, double bodyWidth) { void appointmentUpdateWindow(MzansiProfileProvider mzansiProfileProvider,
MihCalendarProvider mihCalendarProvider, int index, double bodyWidth) {
List<Appointment> appointmentList = mzansiProfileProvider.personalHome
? mihCalendarProvider.personalAppointments!
: mihCalendarProvider.businessAppointments!;
showDialog( showDialog(
context: context, context: context,
barrierDismissible: false, barrierDismissible: false,
@@ -415,13 +440,13 @@ class _BuildAppointmentListState extends State<BuildAppointmentList> {
windowTitle: "Update Appointment", windowTitle: "Update Appointment",
onWindowTapClose: () { onWindowTapClose: () {
setState(() { setState(() {
widget.titleController.text = widget.appointmentList[index].title; widget.titleController.text = appointmentList[index].title;
widget.descriptionIDController.text = widget.descriptionIDController.text =
widget.appointmentList[index].description; appointmentList[index].description;
widget.dateController.text = widget.dateController.text =
widget.appointmentList[index].date_time.split('T')[0]; appointmentList[index].date_time.split('T')[0];
widget.timeController.text = widget widget.timeController.text = appointmentList[index]
.appointmentList[index].date_time .date_time
.split('T')[1] .split('T')[1]
.substring(0, 5); .substring(0, 5);
}); });
@@ -497,7 +522,8 @@ class _BuildAppointmentListState extends State<BuildAppointmentList> {
MihButton( MihButton(
onPressed: () { onPressed: () {
if (_formKey.currentState!.validate()) { if (_formKey.currentState!.validate()) {
updateAppointmentCall(index); updateAppointmentCall(mzansiProfileProvider,
mihCalendarProvider, index);
} else { } else {
MihAlertServices() MihAlertServices()
.formNotFilledCompletely(context); .formNotFilledCompletely(context);
@@ -542,7 +568,10 @@ class _BuildAppointmentListState extends State<BuildAppointmentList> {
} }
} }
void deleteAppointmentConfirmationWindow(int index) { void deleteAppointmentConfirmationWindow(
MzansiProfileProvider mzansiProfileProvider,
MihCalendarProvider mihCalendarProvider,
int index) {
showDialog( showDialog(
context: context, context: context,
barrierDismissible: false, barrierDismissible: false,
@@ -550,46 +579,56 @@ class _BuildAppointmentListState extends State<BuildAppointmentList> {
return MIHDeleteMessage( return MIHDeleteMessage(
deleteType: "Appointment", deleteType: "Appointment",
onTap: () { onTap: () {
deleteAppointmentCall(index); deleteAppointmentCall(
mzansiProfileProvider, mihCalendarProvider, index);
}); });
}, },
); );
} }
Future<void> updateAppointmentCall(int index) async { Future<void> updateAppointmentCall(
MzansiProfileProvider mzansiProfileProvider,
MihCalendarProvider mihCalendarProvider,
int index) async {
int statusCode; int statusCode;
if (isAppointmentInputValid()) { if (isAppointmentInputValid()) {
if (widget.personalSelected == true) { List<Appointment> appointmentList = mzansiProfileProvider.personalHome
? mihCalendarProvider.personalAppointments!
: mihCalendarProvider.businessAppointments!;
KenLogger.success("ersonalHome: ${mzansiProfileProvider.personalHome}");
if (mzansiProfileProvider.personalHome == true) {
statusCode = await MihMzansiCalendarApis.updatePersonalAppointment( statusCode = await MihMzansiCalendarApis.updatePersonalAppointment(
widget.signedInUser, mzansiProfileProvider.user!,
widget.business, mzansiProfileProvider.business,
null, null,
widget.appointmentList[index].idappointments, appointmentList[index].idappointments,
widget.titleController.text, widget.titleController.text,
widget.descriptionIDController.text, widget.descriptionIDController.text,
widget.dateController.text, widget.dateController.text,
widget.timeController.text, widget.timeController.text,
mihCalendarProvider,
context, context,
); );
} else if (widget.personalSelected == false && } else if (mzansiProfileProvider.personalHome == false &&
widget.inWaitingRoom == false) { widget.inWaitingRoom == false) {
statusCode = await MihMzansiCalendarApis.updateBusinessAppointment( statusCode = await MihMzansiCalendarApis.updateBusinessAppointment(
widget.signedInUser, mzansiProfileProvider.user!,
widget.business, mzansiProfileProvider.business,
widget.businessUser, mzansiProfileProvider.businessUser,
widget.appointmentList[index].idappointments, appointmentList[index].idappointments,
widget.titleController.text, widget.titleController.text,
widget.descriptionIDController.text, widget.descriptionIDController.text,
widget.dateController.text, widget.dateController.text,
widget.timeController.text, widget.timeController.text,
mihCalendarProvider,
context, context,
); );
} else { } else {
statusCode = await MihMzansiCalendarApis.updatePatientAppointment( statusCode = await MihMzansiCalendarApis.updatePatientAppointment(
widget.signedInUser, mzansiProfileProvider.user!,
widget.business, mzansiProfileProvider.business,
widget.businessUser, mzansiProfileProvider.businessUser,
widget.appointmentList[index].idappointments, appointmentList[index].idappointments,
widget.titleController.text, widget.titleController.text,
widget.descriptionIDController.text, widget.descriptionIDController.text,
widget.dateController.text, widget.dateController.text,
@@ -600,35 +639,30 @@ class _BuildAppointmentListState extends State<BuildAppointmentList> {
if (statusCode == 200) { if (statusCode == 200) {
context.pop(); context.pop();
context.pop(); context.pop();
if (!widget.inWaitingRoom) { successPopUp("Successfully Updated Appointment",
KenLogger.warning("calendar route"); "You appointment has been successfully updated.");
context.goNamed( // if (!widget.inWaitingRoom) {
"mihCalendar", // KenLogger.warning("calendar route");
extra: CalendarArguments( // context.goNamed(
widget.signedInUser, // "mihCalendar",
widget.personalSelected, // );
widget.business, // } else {
widget.businessUser, // KenLogger.warning("waiting room route");
), // // GoRouter.of(context).refresh();
); // context.goNamed(
} else { // 'mihHome',
KenLogger.warning("waiting room route"); // );
// GoRouter.of(context).refresh(); // context.goNamed(
context.goNamed( // 'patientManager',
'mihHome', // extra: PatManagerArguments(
extra: false, // mzansiProfileProvider.user!,
); // false,
context.goNamed( // mzansiProfileProvider.business,
'patientManager', // mzansiProfileProvider.businessUser,
extra: PatManagerArguments( // ),
widget.signedInUser, // );
false, // // context.pop();
widget.business, // }
widget.businessUser,
),
);
// context.pop();
}
} else { } else {
internetConnectionPopUp(); internetConnectionPopUp();
} }
@@ -642,22 +676,26 @@ class _BuildAppointmentListState extends State<BuildAppointmentList> {
} }
} }
Future<void> deleteAppointmentCall(int index) async { Future<void> deleteAppointmentCall(
MzansiProfileProvider mzansiProfileProvider,
MihCalendarProvider mihCalendarProvider,
int index) async {
List<Appointment> appointmentList = mzansiProfileProvider.personalHome
? mihCalendarProvider.personalAppointments!
: mihCalendarProvider.businessAppointments!;
int statucCode = await MihMzansiCalendarApis.deleteAppointmentAPICall( int statucCode = await MihMzansiCalendarApis.deleteAppointmentAPICall(
widget.signedInUser, mzansiProfileProvider.user!,
widget.personalSelected, mzansiProfileProvider.personalHome,
widget.business, mzansiProfileProvider.business,
widget.businessUser, mzansiProfileProvider.businessUser,
widget.inWaitingRoom, widget.inWaitingRoom,
widget.appointmentList[index].idappointments, appointmentList[index].idappointments,
mihCalendarProvider,
context, context,
); );
if (statucCode == 200) { if (statucCode == 200) {
context.pop(); context.pop();
context.pop(); context.pop();
setState(() {
widget.appointmentList.removeAt(index);
});
successPopUp("Successfully Deleted Appointment", successPopUp("Successfully Deleted Appointment",
"You appointment has been successfully deleted from your calendar."); "You appointment has been successfully deleted from your calendar.");
} else { } else {
@@ -693,6 +731,7 @@ class _BuildAppointmentListState extends State<BuildAppointmentList> {
child: MihButton( child: MihButton(
onPressed: () { onPressed: () {
context.pop(); context.pop();
clearControllers();
}, },
buttonColor: MihColors.getGreenColor( buttonColor: MihColors.getGreenColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"), MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
@@ -730,20 +769,24 @@ class _BuildAppointmentListState extends State<BuildAppointmentList> {
); );
} }
bool canEditAppointment(int index) { bool canEditAppointment(MzansiProfileProvider mzansiProfileProvider,
if (widget.personalSelected == true && MihCalendarProvider mihCalendarProvider, int index) {
widget.appointmentList[index].app_id == widget.signedInUser.app_id && List<Appointment> appointmentList = mzansiProfileProvider.personalHome
widget.appointmentList[index].business_id == "") { ? mihCalendarProvider.personalAppointments!
: mihCalendarProvider.businessAppointments!;
if (mzansiProfileProvider.personalHome == true &&
appointmentList[index].app_id == mzansiProfileProvider.user!.app_id &&
appointmentList[index].business_id == "") {
return true; return true;
} else if (widget.personalSelected == false && } else if (mzansiProfileProvider.personalHome == false &&
widget.appointmentList[index].business_id == appointmentList[index].business_id ==
widget.business!.business_id && mzansiProfileProvider.business!.business_id &&
widget.appointmentList[index].app_id.isEmpty) { appointmentList[index].app_id.isEmpty) {
return true; return true;
} else if (widget.personalSelected == false && } else if (mzansiProfileProvider.personalHome == false &&
widget.appointmentList[index].business_id == appointmentList[index].business_id ==
widget.business!.business_id && mzansiProfileProvider.business!.business_id &&
widget.appointmentList[index].app_id.isNotEmpty) { appointmentList[index].app_id.isNotEmpty) {
return true; return true;
} else { } else {
return false; return false;
@@ -765,16 +808,29 @@ class _BuildAppointmentListState extends State<BuildAppointmentList> {
width = size.width; width = size.width;
height = size.height; height = size.height;
}); });
return Consumer2<MzansiProfileProvider, MihCalendarProvider>(
builder: (BuildContext context,
MzansiProfileProvider mzansiProfileProvider,
MihCalendarProvider mihCalendarProvider,
Widget? child) {
// List<Appointment> appointmentList = mzansiProfileProvider.personalHome
// ? mihCalendarProvider.personalAppointments!
// : mihCalendarProvider.businessAppointments!;
return Padding( return Padding(
padding: EdgeInsets.symmetric(horizontal: getPaddingSize()), padding: EdgeInsets.symmetric(horizontal: getPaddingSize()),
child: ListView.builder( child: ListView.builder(
physics: const NeverScrollableScrollPhysics(), physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true, shrinkWrap: true,
itemCount: widget.appointmentList.length, itemCount: mzansiProfileProvider.personalHome
? mihCalendarProvider.personalAppointments!.length
: mihCalendarProvider.businessAppointments!.length,
itemBuilder: (context, index) { itemBuilder: (context, index) {
return displayAppointment(index, width); return displayAppointment(
mzansiProfileProvider, mihCalendarProvider, index, width);
}, },
), ),
); );
},
);
} }
} }

View File

@@ -2,15 +2,15 @@ import 'package:go_router/go_router.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package.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_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_package_tools.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_objects/arguments.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_providers/mih_calendar_provider.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_providers/mzansi_profile_provider.dart';
import 'package:mzansi_innovation_hub/mih_packages/calendar/package_tools/appointments.dart'; import 'package:mzansi_innovation_hub/mih_packages/calendar/package_tools/appointments.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class MzansiCalendar extends StatefulWidget { class MzansiCalendar extends StatefulWidget {
final CalendarArguments arguments;
const MzansiCalendar({ const MzansiCalendar({
super.key, super.key,
required this.arguments,
}); });
@override @override
@@ -18,8 +18,6 @@ class MzansiCalendar extends StatefulWidget {
} }
class _MzansiCalendarState extends State<MzansiCalendar> { class _MzansiCalendarState extends State<MzansiCalendar> {
int _selcetedIndex = 0;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return MihPackage( return MihPackage(
@@ -27,12 +25,9 @@ class _MzansiCalendarState extends State<MzansiCalendar> {
appTools: getTools(), appTools: getTools(),
appBody: getToolBody(), appBody: getToolBody(),
appToolTitles: getToolTitle(), appToolTitles: getToolTitle(),
selectedbodyIndex: _selcetedIndex, selectedbodyIndex: context.watch<MihCalendarProvider>().toolIndex,
onIndexChange: (newValue) { onIndexChange: (newIndex) {
setState(() { context.read<MihCalendarProvider>().setToolIndex(newIndex);
_selcetedIndex = newValue;
});
print("Index: $_selcetedIndex");
}, },
); );
} }
@@ -42,10 +37,9 @@ class _MzansiCalendarState extends State<MzansiCalendar> {
icon: const Icon(Icons.arrow_back), icon: const Icon(Icons.arrow_back),
iconSize: 35, iconSize: 35,
onTap: () { onTap: () {
// Navigator.of(context).pop(); context.read<MihCalendarProvider>().resetSelectedDay();
context.goNamed( context.goNamed(
'mihHome', 'mihHome',
extra: widget.arguments.personalSelected,
); );
FocusScope.of(context).unfocus(); FocusScope.of(context).unfocus();
}, },
@@ -55,33 +49,28 @@ class _MzansiCalendarState extends State<MzansiCalendar> {
MihPackageTools getTools() { MihPackageTools getTools() {
Map<Widget, void Function()?> temp = {}; Map<Widget, void Function()?> temp = {};
temp[const Icon(Icons.calendar_month)] = () { temp[const Icon(Icons.calendar_month)] = () {
setState(() { context.read<MihCalendarProvider>().setToolIndex(0);
_selcetedIndex = 0;
});
}; };
return MihPackageTools( return MihPackageTools(
tools: temp, tools: temp,
selcetedIndex: _selcetedIndex, selcetedIndex: context.watch<MihCalendarProvider>().toolIndex,
); );
} }
List<Widget> getToolBody() { List<Widget> getToolBody() {
List<Widget> toolBodies = [ List<Widget> toolBodies = [
//appointment here //appointment here
Appointments( Appointments(),
signedInUser: widget.arguments.signedInUser,
business: widget.arguments.business,
businessUser: widget.arguments.businessUser,
personalSelected: widget.arguments.personalSelected,
),
]; ];
return toolBodies; return toolBodies;
} }
List<String> getToolTitle() { List<String> getToolTitle() {
MzansiProfileProvider mzansiProfileProvider =
context.read<MzansiProfileProvider>();
List<String> toolTitles = [ List<String> toolTitles = [
widget.arguments.personalSelected == true ? "Personal" : "Business", mzansiProfileProvider.personalHome == true ? "Personal" : "Business",
]; ];
return toolTitles; return toolTitles;
} }

View File

@@ -2,17 +2,14 @@ import 'package:go_router/go_router.dart';
import 'package:mzansi_innovation_hub/main.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_package_tile.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_icons.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_objects/arguments.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart'; import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart';
class MzansiCalendarTile extends StatefulWidget { class MzansiCalendarTile extends StatefulWidget {
final CalendarArguments arguments;
final double packageSize; final double packageSize;
const MzansiCalendarTile({ const MzansiCalendarTile({
super.key, super.key,
required this.arguments,
required this.packageSize, required this.packageSize,
}); });
@@ -27,7 +24,6 @@ class _MzansiCalendarTileState extends State<MzansiCalendarTile> {
onTap: () { onTap: () {
context.goNamed( context.goNamed(
"mihCalendar", "mihCalendar",
extra: widget.arguments,
); );
// Navigator.of(context).pushNamed( // Navigator.of(context).pushNamed(
// '/calendar', // '/calendar',

View File

@@ -1,7 +1,13 @@
import 'package:flutter/material.dart';
import 'package:flutter_speed_dial/flutter_speed_dial.dart'; import 'package:flutter_speed_dial/flutter_speed_dial.dart';
import 'package:go_router/go_router.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_calendar.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_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_package_alert.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_loading_circle.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_providers/mih_calendar_provider.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_providers/mzansi_profile_provider.dart';
import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart'; import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_alert_services.dart'; import 'package:mzansi_innovation_hub/mih_services/mih_alert_services.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_mzansi_calendar_services.dart'; import 'package:mzansi_innovation_hub/mih_services/mih_mzansi_calendar_services.dart';
@@ -17,29 +23,12 @@ import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_time_field.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_time_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_error_message.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_objects/appointment.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_objects/appointment.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_packages/calendar/builder/build_appointment_list.dart'; import 'package:mzansi_innovation_hub/mih_packages/calendar/builder/build_appointment_list.dart';
import 'package:flutter/material.dart'; import 'package:provider/provider.dart';
import '../../../main.dart';
import '../../../mih_components/mih_package_components/mih_calendar.dart';
import '../../../mih_components/mih_pop_up_messages/mih_loading_circle.dart';
import '../../../mih_config/mih_env.dart';
import '../../../mih_components/mih_objects/app_user.dart';
class Appointments extends StatefulWidget { class Appointments extends StatefulWidget {
final AppUser signedInUser;
final Business? business;
final BusinessUser? businessUser;
final bool personalSelected;
const Appointments({ const Appointments({
super.key, super.key,
required this.signedInUser,
required this.business,
required this.businessUser,
required this.personalSelected,
}); });
@override @override
@@ -57,25 +46,18 @@ class _PatientAccessRequestState extends State<Appointments> {
TextEditingController(); TextEditingController();
final TextEditingController _appointmentTimeController = final TextEditingController _appointmentTimeController =
TextEditingController(); TextEditingController();
String baseUrl = AppEnviroment.baseApiUrl;
String selectedDay = DateTime.now().toString().split(" ")[0];
late Future<List<Appointment>> personalAppointmentResults;
late Future<List<Appointment>> businessAppointmentResults;
late Future<List<Appointment>> appointmentResults;
bool isLoading = true;
final _formKey = GlobalKey<FormState>(); final _formKey = GlobalKey<FormState>();
Widget displayAppointmentList(List<Appointment> appointmentList) { Widget displayAppointmentList(MzansiProfileProvider mzansiProfileProvider,
MihCalendarProvider mihCalendarProvider) {
List<Appointment> appointmentList = mzansiProfileProvider.personalHome
? mihCalendarProvider.personalAppointments!
: mihCalendarProvider.businessAppointments!;
if (appointmentList.isNotEmpty) { if (appointmentList.isNotEmpty) {
return Expanded( return Expanded(
child: BuildAppointmentList( child: BuildAppointmentList(
appointmentList: appointmentList,
signedInUser: widget.signedInUser,
business: widget.business,
businessUser: widget.businessUser,
personalSelected: widget.personalSelected,
inWaitingRoom: false, inWaitingRoom: false,
titleController: _appointmentTitleController, titleController: _appointmentTitleController,
descriptionIDController: _appointmentDescriptionIDController, descriptionIDController: _appointmentDescriptionIDController,
@@ -101,7 +83,7 @@ class _PatientAccessRequestState extends State<Appointments> {
), ),
const SizedBox(height: 10), const SizedBox(height: 10),
Text( Text(
"No appointments for $selectedDay", "No appointments for ${mihCalendarProvider.selectedDay}",
textAlign: TextAlign.center, textAlign: TextAlign.center,
overflow: TextOverflow.visible, overflow: TextOverflow.visible,
style: TextStyle( style: TextStyle(
@@ -147,7 +129,8 @@ class _PatientAccessRequestState extends State<Appointments> {
); );
} }
void addAppointmentWindow(double width) { void addAppointmentWindow(MzansiProfileProvider mzansiProfileProvider,
MihCalendarProvider mihCalendarProvider, double width) {
showDialog( showDialog(
context: context, context: context,
barrierDismissible: false, barrierDismissible: false,
@@ -156,7 +139,7 @@ class _PatientAccessRequestState extends State<Appointments> {
fullscreen: false, fullscreen: false,
windowTitle: "Add Appointment", windowTitle: "Add Appointment",
onWindowTapClose: () { onWindowTapClose: () {
Navigator.of(context).pop(); context.pop();
_appointmentDateController.clear(); _appointmentDateController.clear();
_appointmentTimeController.clear(); _appointmentTimeController.clear();
_appointmentTitleController.clear(); _appointmentTitleController.clear();
@@ -227,7 +210,8 @@ class _PatientAccessRequestState extends State<Appointments> {
child: MihButton( child: MihButton(
onPressed: () { onPressed: () {
if (_formKey.currentState!.validate()) { if (_formKey.currentState!.validate()) {
addAppointmentCall(); addAppointmentCall(
mzansiProfileProvider, mihCalendarProvider);
} else { } else {
MihAlertServices().formNotFilledCompletely(context); MihAlertServices().formNotFilledCompletely(context);
} }
@@ -269,28 +253,33 @@ class _PatientAccessRequestState extends State<Appointments> {
} }
} }
Future<void> addAppointmentCall() async { Future<void> addAppointmentCall(
MzansiProfileProvider mzansiProfileProvider,
MihCalendarProvider mihCalendarProvider,
) async {
if (isAppointmentInputValid()) { if (isAppointmentInputValid()) {
int statusCode; int statusCode;
if (widget.personalSelected == false) { if (mzansiProfileProvider.personalHome == false) {
statusCode = await MihMzansiCalendarApis.addBusinessAppointment( statusCode = await MihMzansiCalendarApis.addBusinessAppointment(
widget.signedInUser, mzansiProfileProvider.user!,
widget.business!, mzansiProfileProvider.business!,
widget.businessUser!, mzansiProfileProvider.businessUser!,
false, false,
_appointmentTitleController.text, _appointmentTitleController.text,
_appointmentDescriptionIDController.text, _appointmentDescriptionIDController.text,
_appointmentDateController.text, _appointmentDateController.text,
_appointmentTimeController.text, _appointmentTimeController.text,
mihCalendarProvider,
context, context,
); );
} else { } else {
statusCode = await MihMzansiCalendarApis.addPersonalAppointment( statusCode = await MihMzansiCalendarApis.addPersonalAppointment(
widget.signedInUser, mzansiProfileProvider.user!,
_appointmentTitleController.text, _appointmentTitleController.text,
_appointmentDescriptionIDController.text, _appointmentDescriptionIDController.text,
_appointmentDateController.text, _appointmentDateController.text,
_appointmentTimeController.text, _appointmentTimeController.text,
mihCalendarProvider,
context, context,
); );
} }
@@ -298,20 +287,20 @@ class _PatientAccessRequestState extends State<Appointments> {
context.pop(); context.pop();
successPopUp("Successfully Added Appointment", successPopUp("Successfully Added Appointment",
"You appointment has been successfully added to your calendar."); "You appointment has been successfully added to your calendar.");
setState(() { if (mzansiProfileProvider.personalHome == true) {
if (widget.personalSelected) { await MihMzansiCalendarApis.getPersonalAppointments(
appointmentResults = MihMzansiCalendarApis.getPersonalAppointments( mzansiProfileProvider.user!.app_id,
widget.signedInUser.app_id, mihCalendarProvider.selectedDay,
selectedDay, mihCalendarProvider,
); );
} else { } else {
appointmentResults = MihMzansiCalendarApis.getBusinessAppointments( await MihMzansiCalendarApis.getBusinessAppointments(
widget.business!.business_id, mzansiProfileProvider.business!.business_id,
false, false,
selectedDay, mihCalendarProvider.selectedDay,
mihCalendarProvider,
); );
} }
});
} else { } else {
internetConnectionPopUp(); internetConnectionPopUp();
} }
@@ -397,8 +386,8 @@ class _PatientAccessRequestState extends State<Appointments> {
); );
} }
String getTitle() { String getTitle(MzansiProfileProvider mzansiProfileProvider) {
if (widget.personalSelected == false) { if (mzansiProfileProvider.personalHome == false) {
return "Business Appointments"; return "Business Appointments";
} else { } else {
return "Personal Appointments"; return "Personal Appointments";
@@ -407,22 +396,22 @@ class _PatientAccessRequestState extends State<Appointments> {
void checkforchange() { void checkforchange() {
setState(() { setState(() {
if (widget.personalSelected == false) { isLoading = true;
appointmentResults = MihMzansiCalendarApis.getBusinessAppointments(
widget.business!.business_id,
false,
selectedDay,
);
} else {
appointmentResults = MihMzansiCalendarApis.getPersonalAppointments(
widget.signedInUser.app_id,
selectedDay,
);
}
}); });
_loadInitialAppointments();
} }
Widget getBody(double width) { Widget getBody(double width) {
if (isLoading) {
return const Center(
child: Mihloadingcircle(),
);
}
return Consumer2<MzansiProfileProvider, MihCalendarProvider>(
builder: (BuildContext context,
MzansiProfileProvider mzansiProfileProvider,
MihCalendarProvider mihCalendarProvider,
Widget? child) {
return Stack( return Stack(
children: [ children: [
MihSingleChildScroll( MihSingleChildScroll(
@@ -432,9 +421,9 @@ class _PatientAccessRequestState extends State<Appointments> {
calendarWidth: 500, calendarWidth: 500,
rowHeight: 35, rowHeight: 35,
setDate: (value) { setDate: (value) {
mihCalendarProvider.setSelectedDay(value);
setState(() { setState(() {
selectedDay = value; selectedAppointmentDateController.text = value;
selectedAppointmentDateController.text = selectedDay;
}); });
}), }),
// Divider( // Divider(
@@ -443,33 +432,10 @@ class _PatientAccessRequestState extends State<Appointments> {
Row( Row(
mainAxisSize: MainAxisSize.max, mainAxisSize: MainAxisSize.max,
children: [ children: [
FutureBuilder( displayAppointmentList(
future: appointmentResults, mzansiProfileProvider,
builder: (context, snapshot) { mihCalendarProvider,
if (snapshot.connectionState ==
ConnectionState.waiting) {
return const Expanded(
child: Center(child: Mihloadingcircle()));
} else if (snapshot.connectionState ==
ConnectionState.done &&
snapshot.hasData) {
return displayAppointmentList(snapshot.requireData);
} else {
return Center(
child: Text(
"Error pulling appointments",
style: TextStyle(
fontSize: 25,
color: MihColors.getRedColor(
MzansiInnovationHub.of(context)!
.theme
.mode ==
"Dark")),
textAlign: TextAlign.center,
), ),
);
}
}),
], ],
) )
], ],
@@ -486,20 +452,23 @@ class _PatientAccessRequestState extends State<Appointments> {
child: Icon( child: Icon(
Icons.add, Icons.add,
color: MihColors.getPrimaryColor( color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"), MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
), ),
label: "Add Appointment", label: "Add Appointment",
labelBackgroundColor: MihColors.getGreenColor( labelBackgroundColor: MihColors.getGreenColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"), MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
labelStyle: TextStyle( labelStyle: TextStyle(
color: MihColors.getPrimaryColor( color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"), MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
), ),
backgroundColor: MihColors.getGreenColor( backgroundColor: MihColors.getGreenColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"), MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
onTap: () { onTap: () {
addAppointmentWindow(width); addAppointmentWindow(
mzansiProfileProvider, mihCalendarProvider, width);
}, },
) )
], ],
@@ -507,6 +476,32 @@ class _PatientAccessRequestState extends State<Appointments> {
), ),
], ],
); );
},
);
}
Future<void> _loadInitialAppointments() async {
MzansiProfileProvider mzansiProfileProvider =
context.read<MzansiProfileProvider>();
MihCalendarProvider mihCalendarProvider =
context.read<MihCalendarProvider>();
if (mzansiProfileProvider.personalHome == false) {
await MihMzansiCalendarApis.getBusinessAppointments(
mzansiProfileProvider.business!.business_id,
false,
mihCalendarProvider.selectedDay,
mihCalendarProvider,
);
} else {
await MihMzansiCalendarApis.getPersonalAppointments(
mzansiProfileProvider.user!.app_id,
mihCalendarProvider.selectedDay,
mihCalendarProvider,
);
}
setState(() {
isLoading = false;
});
} }
@override @override
@@ -522,19 +517,8 @@ class _PatientAccessRequestState extends State<Appointments> {
@override @override
void initState() { void initState() {
selectedAppointmentDateController.addListener(checkforchange); selectedAppointmentDateController.addListener(checkforchange);
setState(() { WidgetsBinding.instance.addPostFrameCallback((_) async {
if (widget.personalSelected == false) { _loadInitialAppointments();
appointmentResults = MihMzansiCalendarApis.getBusinessAppointments(
widget.business!.business_id,
false,
selectedDay,
);
} else {
appointmentResults = MihMzansiCalendarApis.getPersonalAppointments(
widget.signedInUser.app_id,
selectedDay,
);
}
}); });
super.initState(); super.initState();
} }

View File

@@ -4,8 +4,10 @@ import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_
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.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_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_package_tools.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_providers/mih_authentication_provider.dart';
import 'package:mzansi_innovation_hub/mih_packages/mih_authentication/package_tools/mih_register.dart'; import 'package:mzansi_innovation_hub/mih_packages/mih_authentication/package_tools/mih_register.dart';
import 'package:mzansi_innovation_hub/mih_packages/mih_authentication/package_tools/mih_sign_in.dart'; import 'package:mzansi_innovation_hub/mih_packages/mih_authentication/package_tools/mih_sign_in.dart';
import 'package:provider/provider.dart';
class MihAuthentication extends StatefulWidget { class MihAuthentication extends StatefulWidget {
const MihAuthentication({super.key}); const MihAuthentication({super.key});
@@ -15,56 +17,35 @@ class MihAuthentication extends StatefulWidget {
} }
class _MihAuthenticationState extends State<MihAuthentication> { class _MihAuthenticationState extends State<MihAuthentication> {
int _selcetedIndex = 0;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return MihPackage( return MihPackage(
appActionButton: getAction(), appActionButton: getAction(),
appTools: getTools(), appTools: getTools(),
appBody: getToolBody(), appBody: getToolBody(),
selectedbodyIndex: _selcetedIndex, selectedbodyIndex: context.watch<MihAuthenticationProvider>().toolIndex,
onIndexChange: (newValue) { onIndexChange: (newIndex) {
setState(() { context.read<MihAuthenticationProvider>().setToolIndex(newIndex);
_selcetedIndex = newValue;
});
}, },
); );
} }
List<Widget> getToolBody() { List<Widget> getToolBody() {
List<Widget> toolBodies = [ List<Widget> toolBodies = [MihSignIn(), MihRegister()];
MihSignIn(
onNewUserButtonTap: () {
setState(() {
_selcetedIndex = 1;
});
},
),
MihRegister(onExistingUserButtonTap: () {
setState(() {
_selcetedIndex = 0;
});
})
];
return toolBodies; return toolBodies;
} }
MihPackageTools getTools() { MihPackageTools getTools() {
Map<Widget, void Function()?> temp = {}; Map<Widget, void Function()?> temp = {};
temp[const Icon(Icons.perm_identity)] = () { temp[const Icon(Icons.perm_identity)] = () {
setState(() { context.read<MihAuthenticationProvider>().setToolIndex(0);
_selcetedIndex = 0;
});
}; };
temp[const Icon(Icons.create)] = () { temp[const Icon(Icons.create)] = () {
setState(() { context.read<MihAuthenticationProvider>().setToolIndex(1);
_selcetedIndex = 1;
});
}; };
return MihPackageTools( return MihPackageTools(
tools: temp, tools: temp,
selcetedIndex: _selcetedIndex, selcetedIndex: context.watch<MihAuthenticationProvider>().toolIndex,
); );
} }
@@ -75,7 +56,7 @@ class _MihAuthenticationState extends State<MihAuthentication> {
icon: const Icon(MihIcons.mihLogo), icon: const Icon(MihIcons.mihLogo),
iconSize: 45, iconSize: 45,
onTap: () { onTap: () {
context.goNamed("aboutMih", extra: 0); context.goNamed("aboutMih", extra: true);
}, },
), ),
); );

View File

@@ -11,19 +11,20 @@ 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_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_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_loading_circle.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_providers/mih_authentication_provider.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_providers/mzansi_profile_provider.dart';
import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart'; import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart';
import 'package:mzansi_innovation_hub/mih_config/mih_env.dart'; import 'package:mzansi_innovation_hub/mih_config/mih_env.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_alert_services.dart'; import 'package:mzansi_innovation_hub/mih_services/mih_alert_services.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_user_services.dart'; import 'package:mzansi_innovation_hub/mih_services/mih_user_services.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_validation_services.dart'; import 'package:mzansi_innovation_hub/mih_services/mih_validation_services.dart';
import 'package:provider/provider.dart';
import 'package:supertokens_flutter/http.dart' as http; import 'package:supertokens_flutter/http.dart' as http;
import 'package:supertokens_flutter/supertokens.dart'; import 'package:supertokens_flutter/supertokens.dart';
class MihRegister extends StatefulWidget { class MihRegister extends StatefulWidget {
final void Function()? onExistingUserButtonTap;
const MihRegister({ const MihRegister({
super.key, super.key,
required this.onExistingUserButtonTap,
}); });
@override @override
@@ -75,6 +76,7 @@ class _MihRegisterState extends State<MihRegister> {
} }
Future<void> signUserUp() async { Future<void> signUserUp() async {
context.read<MzansiProfileProvider>().reset();
if (!validEmail()) { if (!validEmail()) {
emailError(); emailError();
} else if (passwordController.text != confirmPasswordController.text) { } else if (passwordController.text != confirmPasswordController.text) {
@@ -366,7 +368,11 @@ class _MihRegisterState extends State<MihRegister> {
), ),
), ),
MihButton( MihButton(
onPressed: widget.onExistingUserButtonTap, onPressed: () {
context
.read<MihAuthenticationProvider>()
.setToolIndex(0);
},
buttonColor: MihColors.getSecondaryColor( buttonColor: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"), "Dark"),

View File

@@ -9,18 +9,19 @@ import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_
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_single_child_scroll.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_text_form_field.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_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_error_message.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_providers/mih_authentication_provider.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_providers/mzansi_profile_provider.dart';
import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart'; import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart';
import 'package:mzansi_innovation_hub/mih_config/mih_env.dart'; import 'package:mzansi_innovation_hub/mih_config/mih_env.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_alert_services.dart'; import 'package:mzansi_innovation_hub/mih_services/mih_alert_services.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_authentication_services.dart'; import 'package:mzansi_innovation_hub/mih_services/mih_authentication_services.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_install_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_services/mih_validation_services.dart';
import 'package:provider/provider.dart';
class MihSignIn extends StatefulWidget { class MihSignIn extends StatefulWidget {
final void Function()? onNewUserButtonTap;
const MihSignIn({ const MihSignIn({
super.key, super.key,
required this.onNewUserButtonTap,
}); });
@override @override
@@ -39,6 +40,7 @@ class _MihSignInState extends State<MihSignIn> {
//sign user in //sign user in
Future<void> signUserIn() async { Future<void> signUserIn() async {
context.read<MzansiProfileProvider>().reset();
try { try {
successfulSignIn = await MihAuthenticationServices().signUserIn( successfulSignIn = await MihAuthenticationServices().signUserIn(
emailController.text, emailController.text,
@@ -381,7 +383,11 @@ class _MihSignInState extends State<MihSignIn> {
), ),
), ),
MihButton( MihButton(
onPressed: widget.onNewUserButtonTap, onPressed: () {
context
.read<MihAuthenticationProvider>()
.setToolIndex(1);
},
buttonColor: MihColors.getSecondaryColor( buttonColor: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"), "Dark"),

View File

@@ -1,21 +1,27 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:go_router/go_router.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'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_circle_avatar.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_icons.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_icons.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_providers/about_mih_provider.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_providers/mih_access_controlls_provider.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_providers/mih_authentication_provider.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_providers/mih_banner_ad_provider.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_providers/mih_calculator_provider.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_providers/mih_calendar_provider.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_providers/mih_mine_sweeper_provider.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_providers/mzansi_ai_provider.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_providers/mzansi_directory_provider.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_providers/mzansi_profile_provider.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_providers/mzansi_wallet_provider.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_providers/patient_manager_provider.dart';
import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart'; import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart';
import 'package:provider/provider.dart';
import '../../../main.dart'; import '../../../main.dart';
import 'package:supertokens_flutter/supertokens.dart'; import 'package:supertokens_flutter/supertokens.dart';
class MIHAppDrawer extends StatefulWidget { class MIHAppDrawer extends StatefulWidget {
final AppUser signedInUser;
final ImageProvider<Object>? propicFile;
const MIHAppDrawer({ const MIHAppDrawer({
super.key, super.key,
required this.signedInUser,
required this.propicFile,
}); });
@override @override
@@ -25,6 +31,21 @@ class MIHAppDrawer extends StatefulWidget {
class _MIHAppDrawerState extends State<MIHAppDrawer> { class _MIHAppDrawerState extends State<MIHAppDrawer> {
final proPicController = TextEditingController(); final proPicController = TextEditingController();
late Widget profilePictureLoaded; late Widget profilePictureLoaded;
void resetProviders() {
context.read<AboutMihProvider>().reset();
context.read<MihAccessControllsProvider>().reset();
context.read<MihAuthenticationProvider>().reset();
context.read<MihBannerAdProvider>().reset();
context.read<MihCalculatorProvider>().reset();
context.read<MihCalendarProvider>().reset();
context.read<MihMineSweeperProvider>().reset();
context.read<MzansiAiProvider>().reset();
context.read<MzansiDirectoryProvider>().reset();
context.read<MzansiWalletProvider>().reset();
context.read<PatientManagerProvider>().reset();
}
Future<bool> signOut() async { Future<bool> signOut() async {
await SuperTokens.signOut(completionHandler: (error) { await SuperTokens.signOut(completionHandler: (error) {
// handle error if any // handle error if any
@@ -32,19 +53,30 @@ class _MIHAppDrawerState extends State<MIHAppDrawer> {
return true; return true;
} }
Widget displayProPic() { Widget displayProPic(MzansiProfileProvider mzansiProfileProvider) {
return GestureDetector( return GestureDetector(
onTap: () { onTap: () {
if (mzansiProfileProvider.personalHome) {
context.goNamed( context.goNamed(
'mzansiProfileManage', 'mzansiProfileManage',
extra: AppProfileUpdateArguments(
widget.signedInUser,
widget.propicFile,
),
); );
} else {
if (mzansiProfileProvider.business == null) {
context.goNamed(
'businessProfileSetup',
extra: mzansiProfileProvider.user,
);
} else {
context.goNamed(
"businessProfileManage",
);
}
}
}, },
child: MihCircleAvatar( child: MihCircleAvatar(
imageFile: widget.propicFile, imageFile: mzansiProfileProvider.personalHome
? mzansiProfileProvider.userProfilePicture
: mzansiProfileProvider.businessProfilePicture,
width: 60, width: 60,
editable: false, editable: false,
fileNameController: proPicController, fileNameController: proPicController,
@@ -66,9 +98,6 @@ class _MIHAppDrawerState extends State<MIHAppDrawer> {
@override @override
void initState() { void initState() {
setState(() {
profilePictureLoaded = displayProPic();
});
super.initState(); super.initState();
} }
@@ -76,6 +105,9 @@ class _MIHAppDrawerState extends State<MIHAppDrawer> {
Widget build(BuildContext context) { Widget build(BuildContext context) {
// precacheImage( // precacheImage(
// MzansiInnovationHub.of(context)!.theme.logoImage().image, context); // MzansiInnovationHub.of(context)!.theme.logoImage().image, context);
return Consumer<MzansiProfileProvider>(
builder: (BuildContext context,
MzansiProfileProvider mzansiProfileProvider, Widget? child) {
return SafeArea( return SafeArea(
child: Drawer( child: Drawer(
//backgroundColor: MihColors.getPrimaryColor(MzansiInnovationHub.of(context)!.theme.mode == "Dark"), //backgroundColor: MihColors.getPrimaryColor(MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
@@ -96,15 +128,18 @@ class _MIHAppDrawerState extends State<MIHAppDrawer> {
"Dark"), "Dark"),
), ),
child: SizedBox( child: SizedBox(
height: 400, // height: 300,
width: constraints.maxWidth, width: constraints.maxWidth,
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.max, mainAxisSize: MainAxisSize.max,
children: [ children: [
profilePictureLoaded, displayProPic(mzansiProfileProvider),
Text( Visibility(
"${widget.signedInUser.fname} ${widget.signedInUser.lname}", visible: !mzansiProfileProvider.personalHome,
child: Text(
mzansiProfileProvider.business?.Name ??
"Setup Business",
style: TextStyle( style: TextStyle(
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
color: MihColors.getPrimaryColor( color: MihColors.getPrimaryColor(
@@ -114,8 +149,25 @@ class _MIHAppDrawerState extends State<MIHAppDrawer> {
"Dark"), "Dark"),
), ),
), ),
Text( ),
"@${widget.signedInUser.username}", Visibility(
visible: mzansiProfileProvider.personalHome,
child: Text(
"${mzansiProfileProvider.user!.fname} ${mzansiProfileProvider.user!.lname}",
style: TextStyle(
fontWeight: FontWeight.bold,
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!
.theme
.mode ==
"Dark"),
),
),
),
Visibility(
visible: !mzansiProfileProvider.personalHome,
child: Text(
mzansiProfileProvider.business?.type ?? "",
style: TextStyle( style: TextStyle(
fontSize: 12, fontSize: 12,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
@@ -126,8 +178,25 @@ class _MIHAppDrawerState extends State<MIHAppDrawer> {
"Dark"), "Dark"),
), ),
), ),
),
Visibility(
visible: mzansiProfileProvider.personalHome,
child: Text(
"@${mzansiProfileProvider.user!.username}",
style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.bold,
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!
.theme
.mode ==
"Dark"),
),
),
),
Text( Text(
widget.signedInUser.type.toUpperCase(), mzansiProfileProvider.user!.type
.toUpperCase(),
style: TextStyle( style: TextStyle(
fontSize: 10, fontSize: 10,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
@@ -200,12 +269,15 @@ class _MIHAppDrawerState extends State<MIHAppDrawer> {
], ],
), ),
onTap: () { onTap: () {
WidgetsBinding.instance
.addPostFrameCallback((_) async {
context
.read<AboutMihProvider>()
.setToolIndex(1);
});
context.goNamed( context.goNamed(
"aboutMih", "aboutMih",
extra: AboutArguments( extra: true,
true,
1,
),
); );
}, },
), ),
@@ -236,12 +308,15 @@ class _MIHAppDrawerState extends State<MIHAppDrawer> {
], ],
), ),
onTap: () { onTap: () {
WidgetsBinding.instance
.addPostFrameCallback((_) async {
context
.read<AboutMihProvider>()
.setToolIndex(2);
});
context.goNamed( context.goNamed(
"aboutMih", "aboutMih",
extra: AboutArguments( extra: true,
true,
2,
),
); );
}, },
), ),
@@ -278,15 +353,13 @@ class _MIHAppDrawerState extends State<MIHAppDrawer> {
}); });
if (await SuperTokens.doesSessionExist() == if (await SuperTokens.doesSessionExist() ==
false) { false) {
resetProviders();
await Future.delayed(Duration.zero);
if (context.mounted) {
context.goNamed( context.goNamed(
'mihHome', 'mihHome',
extra: true,
); );
// Navigator.of(context).pop(); }
// Navigator.of(context).popAndPushNamed(
// '/',
// arguments: AuthArguments(true, false),
// );
} }
}, },
), ),
@@ -302,26 +375,22 @@ class _MIHAppDrawerState extends State<MIHAppDrawer> {
height: 30, height: 30,
child: InkWell( child: InkWell(
onTap: () { onTap: () {
setState(() { // setState(() {
if (MzansiInnovationHub.of(context)?.theme.mode == // if (MzansiInnovationHub.of(context)?.theme.mode ==
"Dark") { // "Dark") {
//darkm = !darkm; // //darkm = !darkm;
MzansiInnovationHub.of(context)! // MzansiInnovationHub.of(context)!
.changeTheme(ThemeMode.light); // .changeTheme(ThemeMode.light);
//print("Dark Mode: $darkm"); // //print("Dark Mode: $darkm");
} else { // } else {
//darkm = !darkm; // //darkm = !darkm;
MzansiInnovationHub.of(context)! // MzansiInnovationHub.of(context)!
.changeTheme(ThemeMode.dark); // .changeTheme(ThemeMode.dark);
//print("Dark Mode: $darkm"); // //print("Dark Mode: $darkm");
} // }
Navigator.of(context).pop(); // // Navigator.of(context).popAndPushNamed('/',);
Navigator.of(context).popAndPushNamed( // });
'/', context.goNamed("aboutMih");
arguments: AuthArguments(true, false),
);
// Navigator.of(context).popAndPushNamed('/',);
});
}, },
child: Icon( child: Icon(
MihIcons.mihLogo, MihIcons.mihLogo,
@@ -358,5 +427,7 @@ class _MIHAppDrawerState extends State<MIHAppDrawer> {
), ),
), ),
); );
},
);
} }
} }

View File

@@ -1,7 +1,8 @@
import 'package:go_router/go_router.dart'; import 'package:go_router/go_router.dart';
import 'package:ken_logger/ken_logger.dart'; import 'package:ken_logger/ken_logger.dart';
import 'package:mzansi_innovation_hub/main.dart'; import 'package:mzansi_innovation_hub/main.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_objects/arguments.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_objects/business.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_objects/business_user.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_objects/user_consent.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_objects/user_consent.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_button.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_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.dart';
@@ -13,22 +14,24 @@ import 'package:mzansi_innovation_hub/mih_components/mih_objects/app_user.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_window.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_window.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_scack_bar.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_scack_bar.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_loading_circle.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_loading_circle.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_providers/about_mih_provider.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_providers/mzansi_profile_provider.dart';
import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart'; import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart';
import 'package:mzansi_innovation_hub/mih_config/mih_env.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/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_business_home.dart';
import 'package:mzansi_innovation_hub/mih_packages/mih_home/package_tools/mih_personal_home.dart'; import 'package:mzansi_innovation_hub/mih_packages/mih_home/package_tools/mih_personal_home.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_service_calls.dart'; import 'package:mzansi_innovation_hub/mih_services/mih_business_details_services.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_file_services.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_my_business_user_services.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_user_consent_services.dart'; import 'package:mzansi_innovation_hub/mih_services/mih_user_consent_services.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_user_services.dart';
import 'package:provider/provider.dart';
// ignore: must_be_immutable
class MihHome extends StatefulWidget { class MihHome extends StatefulWidget {
final bool personalSelected;
const MihHome({ const MihHome({
super.key, super.key,
required this.personalSelected,
}); });
@override @override
@@ -36,14 +39,77 @@ class MihHome extends StatefulWidget {
} }
class _MihHomeState extends State<MihHome> { class _MihHomeState extends State<MihHome> {
final proPicController = TextEditingController();
late int _selcetedIndex;
late bool _personalSelected;
late Future<HomeArguments> profileData;
late Future<UserConsent?> futureUserConsent;
bool showUserConsent = false;
DateTime latestPrivacyPolicyDate = DateTime.parse("2024-12-01"); DateTime latestPrivacyPolicyDate = DateTime.parse("2024-12-01");
DateTime latestTermOfServiceDate = DateTime.parse("2024-12-01"); DateTime latestTermOfServiceDate = DateTime.parse("2024-12-01");
bool _isLoadingInitialData = true;
Future<void> _loadInitialData() async {
if (mounted) {
setState(() {
_isLoadingInitialData = true;
});
}
MzansiProfileProvider mzansiProfileProvider =
context.read<MzansiProfileProvider>();
// Note: getUserData sets user and userProfilePicUrl in the provider
if (mzansiProfileProvider.user == null) {
await getUserData();
}
// Note: getUserConsentStatus sets userConsent in the provider
if (mzansiProfileProvider.userConsent == null) {
await getUserConsentStatus();
}
// 1. Get Business Data
if (mzansiProfileProvider.user != null &&
mzansiProfileProvider.user!.type == "business" &&
mzansiProfileProvider.business == null) {
KenLogger.success(mzansiProfileProvider.business == null
? "Business is null, fetching business data..."
: "Business data already loaded.");
await getBusinessData();
}
// 2. Set state after all data is loaded
if (mounted) {
setState(() {
_isLoadingInitialData = false;
});
}
}
Future<void> getBusinessData() async {
AppUser? user = context.read<MzansiProfileProvider>().user;
String logoUrl;
String signatureUrl;
Business? responseBusiness =
await MihBusinessDetailsServices().getBusinessDetailsByUser(context);
// if (responseBusiness == null && user!.type == "business") {
// if (mounted) {
// context.goNamed(
// 'businessProfileSetup',
// extra: user,
// );
// }
// }
if (responseBusiness != null && user!.type == "business") {
// Get Business
// Business Profile Set Up aleary
logoUrl = await MihFileApi.getMinioFileUrl(
context.read<MzansiProfileProvider>().business!.logo_path,
context,
);
context.read<MzansiProfileProvider>().setBusinessProfilePicUrl(logoUrl);
// Get Business User
await MihMyBusinessUserServices().getBusinessUser(context);
signatureUrl = await MihFileApi.getMinioFileUrl(
context.read<MzansiProfileProvider>().businessUser!.sig_path,
context,
);
context
.read<MzansiProfileProvider>()
.setBusinessUserSignatureUrl(signatureUrl);
}
}
bool showPolicyWindow(UserConsent? userConsent) { bool showPolicyWindow(UserConsent? userConsent) {
if (userConsent == null) { if (userConsent == null) {
@@ -60,20 +126,19 @@ class _MihHomeState extends State<MihHome> {
} }
} }
void createOrUpdateAccpetance(UserConsent? userConsent, String app_id) { void createOrUpdateAccpetance(MzansiProfileProvider mzansiProfileProvider) {
UserConsent? userConsent = mzansiProfileProvider.userConsent;
userConsent != null userConsent != null
? MihUserConsentServices() ? MihUserConsentServices()
.updateUserConsentStatus( .updateUserConsentStatus(
app_id,
DateTime.now().toIso8601String(), DateTime.now().toIso8601String(),
DateTime.now().toIso8601String(), DateTime.now().toIso8601String(),
mzansiProfileProvider,
context,
) )
.then((value) { .then((value) {
if (value == 200) { if (value == 200) {
// setState(() { context.goNamed("mihHome");
// showUserConsent = false;
// });
context.goNamed("mihHome", extra: false);
ScaffoldMessenger.of(context).showSnackBar( ScaffoldMessenger.of(context).showSnackBar(
MihSnackBar( MihSnackBar(
child: Text("Thank you for accepting our Policies"), child: Text("Thank you for accepting our Policies"),
@@ -89,16 +154,14 @@ class _MihHomeState extends State<MihHome> {
}) })
: MihUserConsentServices() : MihUserConsentServices()
.insertUserConsentStatus( .insertUserConsentStatus(
app_id,
DateTime.now().toIso8601String(), DateTime.now().toIso8601String(),
DateTime.now().toIso8601String(), DateTime.now().toIso8601String(),
mzansiProfileProvider,
context,
) )
.then((value) { .then((value) {
if (value == 201) { if (value == 201) {
// setState(() { context.goNamed("mihHome");
// showUserConsent = false;
// });
context.goNamed("mihHome", extra: false);
ScaffoldMessenger.of(context).showSnackBar( ScaffoldMessenger.of(context).showSnackBar(
MihSnackBar( MihSnackBar(
child: Text("Thank you for accepting our Policies"), child: Text("Thank you for accepting our Policies"),
@@ -114,6 +177,25 @@ class _MihHomeState extends State<MihHome> {
}); });
} }
Future<void> getUserData() async {
if (!mounted) return;
String url;
await MihUserServices().getUserDetails(
context,
);
if (!mounted) return;
url = await MihFileApi.getMinioFileUrl(
context.read<MzansiProfileProvider>().user!.pro_pic_path,
context,
);
context.read<MzansiProfileProvider>().setUserProfilePicUrl(url);
}
Future<void> getUserConsentStatus() async {
if (!mounted) return;
await MihUserConsentServices().getUserConsentStatus(context);
}
@override @override
void dispose() { void dispose() {
super.dispose(); super.dispose();
@@ -122,19 +204,7 @@ class _MihHomeState extends State<MihHome> {
@override @override
void initState() { void initState() {
super.initState(); super.initState();
profileData = MIHApiCalls().getProfile(10, context); _loadInitialData();
futureUserConsent = MihUserConsentServices().getUserConsentStatus();
if (widget.personalSelected == true) {
setState(() {
_selcetedIndex = 0;
_personalSelected = true;
});
} else {
setState(() {
_selcetedIndex = 1;
_personalSelected = false;
});
}
} }
List<String> getToolTitle() { List<String> getToolTitle() {
@@ -147,64 +217,46 @@ class _MihHomeState extends State<MihHome> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return FutureBuilder( return Consumer<MzansiProfileProvider>(
future: profileData, builder: (BuildContext context,
builder: (context, asyncSnapshot) { MzansiProfileProvider mzansiProfileProvider, Widget? child) {
if (asyncSnapshot.connectionState == ConnectionState.waiting) { if (_isLoadingInitialData) {
return Scaffold( return Scaffold(
body: const Mihloadingcircle( body: Center(
// message: "Fetching your Data...", child: Mihloadingcircle(),
), ),
); );
} else if (asyncSnapshot.connectionState == ConnectionState.done && }
asyncSnapshot.hasData) { // bool showConsentWindow =
// showPolicyWindow(mzansiProfileProvider.userConsent);
return Stack( return Stack(
children: [ children: [
MihPackage( RefreshIndicator(
appActionButton: getAction(asyncSnapshot.data!.profilePicUrl), onRefresh: () async {
appTools: getTools( await _loadInitialData();
asyncSnapshot.data!.signedInUser.type != "personal"), },
appBody: getToolBody(asyncSnapshot.data!), child: SingleChildScrollView(
physics: const AlwaysScrollableScrollPhysics(),
child: SizedBox(
height: MediaQuery.of(context).size.height,
child: MihPackage(
appActionButton: getAction(),
appTools: getTools(mzansiProfileProvider,
mzansiProfileProvider.user!.type != "personal"),
appBody: getToolBody(mzansiProfileProvider),
appToolTitles: getToolTitle(), appToolTitles: getToolTitle(),
actionDrawer: getActionDrawer( actionDrawer: getActionDrawer(),
asyncSnapshot.data!.signedInUser, selectedbodyIndex:
asyncSnapshot.data!.profilePicUrl, mzansiProfileProvider.personalHome ? 0 : 1,
),
selectedbodyIndex: _selcetedIndex,
onIndexChange: (newValue) { onIndexChange: (newValue) {
if (_selcetedIndex == 0) { mzansiProfileProvider.setPersonalHome(newValue == 0);
setState(() {
_selcetedIndex = newValue;
_personalSelected = true;
});
} else {
setState(() {
_selcetedIndex = newValue;
_personalSelected = false;
});
}
}, },
), ),
FutureBuilder( ),
future: futureUserConsent, ),
builder: (context, asyncSnapshotUserConsent) { ),
if (asyncSnapshotUserConsent.connectionState == Visibility(
ConnectionState.waiting) { visible: showPolicyWindow(mzansiProfileProvider.userConsent),
showUserConsent = false;
} else if (asyncSnapshotUserConsent.connectionState ==
ConnectionState.done &&
asyncSnapshotUserConsent.hasData) {
showUserConsent =
showPolicyWindow(asyncSnapshotUserConsent.data);
} else if (asyncSnapshotUserConsent.connectionState ==
ConnectionState.done &&
!asyncSnapshotUserConsent.hasData) {
showUserConsent = true;
} else {
showUserConsent = false;
}
return Visibility(
visible: showUserConsent,
child: Container( child: Container(
color: Colors.black.withValues(alpha: 0.5), color: Colors.black.withValues(alpha: 0.5),
child: Column( child: Column(
@@ -213,8 +265,7 @@ class _MihHomeState extends State<MihHome> {
children: [ children: [
MihPackageWindow( MihPackageWindow(
fullscreen: false, fullscreen: false,
windowTitle: windowTitle: "Privacy Policy & Terms Of Service Alert!",
"Privacy Policy & Terms Of Service Alert!",
onWindowTapClose: () { onWindowTapClose: () {
showDialog( showDialog(
context: context, context: context,
@@ -247,9 +298,7 @@ class _MihHomeState extends State<MihHome> {
), ),
), ),
alertColour: MihColors.getRedColor( alertColour: MihColors.getRedColor(
MzansiInnovationHub.of(context)! MzansiInnovationHub.of(context)!.theme.mode ==
.theme
.mode ==
"Dark", "Dark",
), ),
); );
@@ -261,9 +310,7 @@ class _MihHomeState extends State<MihHome> {
Icons.policy, Icons.policy,
size: 150, size: 150,
color: MihColors.getSecondaryColor( color: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)! MzansiInnovationHub.of(context)!.theme.mode ==
.theme
.mode ==
"Dark", "Dark",
), ),
), ),
@@ -273,9 +320,7 @@ class _MihHomeState extends State<MihHome> {
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: TextStyle( style: TextStyle(
color: MihColors.getSecondaryColor( color: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)! MzansiInnovationHub.of(context)!.theme.mode ==
.theme
.mode ==
"Dark", "Dark",
), ),
fontSize: 30, fontSize: 30,
@@ -288,9 +333,7 @@ class _MihHomeState extends State<MihHome> {
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: TextStyle( style: TextStyle(
color: MihColors.getSecondaryColor( color: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)! MzansiInnovationHub.of(context)!.theme.mode ==
.theme
.mode ==
"Dark", "Dark",
), ),
fontSize: 15, fontSize: 15,
@@ -306,13 +349,15 @@ class _MihHomeState extends State<MihHome> {
children: [ children: [
MihButton( MihButton(
onPressed: () { onPressed: () {
context.goNamed( WidgetsBinding.instance
"aboutMih", .addPostFrameCallback((_) async {
extra: AboutArguments( context
widget.personalSelected, .read<AboutMihProvider>()
1, .setToolIndex(1);
), });
); context.goNamed("aboutMih",
extra:
mzansiProfileProvider.personalHome);
}, },
buttonColor: MihColors.getOrangeColor( buttonColor: MihColors.getOrangeColor(
MzansiInnovationHub.of(context)! MzansiInnovationHub.of(context)!
@@ -325,8 +370,7 @@ class _MihHomeState extends State<MihHome> {
"Privacy Policy", "Privacy Policy",
style: TextStyle( style: TextStyle(
color: MihColors.getPrimaryColor( color: MihColors.getPrimaryColor(
MzansiInnovationHub.of( MzansiInnovationHub.of(context)!
context)!
.theme .theme
.mode == .mode ==
"Dark"), "Dark"),
@@ -337,13 +381,15 @@ class _MihHomeState extends State<MihHome> {
), ),
MihButton( MihButton(
onPressed: () { onPressed: () {
context.goNamed( WidgetsBinding.instance
"aboutMih", .addPostFrameCallback((_) async {
extra: AboutArguments( context
widget.personalSelected, .read<AboutMihProvider>()
2, .setToolIndex(2);
), });
); context.goNamed("aboutMih",
extra:
mzansiProfileProvider.personalHome);
}, },
buttonColor: MihColors.getYellowColor( buttonColor: MihColors.getYellowColor(
MzansiInnovationHub.of(context)! MzansiInnovationHub.of(context)!
@@ -356,8 +402,7 @@ class _MihHomeState extends State<MihHome> {
"Terms of Service", "Terms of Service",
style: TextStyle( style: TextStyle(
color: MihColors.getPrimaryColor( color: MihColors.getPrimaryColor(
MzansiInnovationHub.of( MzansiInnovationHub.of(context)!
context)!
.theme .theme
.mode == .mode ==
"Dark"), "Dark"),
@@ -369,13 +414,9 @@ class _MihHomeState extends State<MihHome> {
MihButton( MihButton(
onPressed: () { onPressed: () {
DateTime now = DateTime.now(); DateTime now = DateTime.now();
KenLogger.success( KenLogger.success("Date Time Now: $now");
"Date Time Now: $now");
createOrUpdateAccpetance( createOrUpdateAccpetance(
asyncSnapshotUserConsent.data, mzansiProfileProvider);
asyncSnapshot
.data!.signedInUser.app_id,
);
}, },
buttonColor: MihColors.getGreenColor( buttonColor: MihColors.getGreenColor(
MzansiInnovationHub.of(context)! MzansiInnovationHub.of(context)!
@@ -388,8 +429,7 @@ class _MihHomeState extends State<MihHome> {
"Accept", "Accept",
style: TextStyle( style: TextStyle(
color: MihColors.getPrimaryColor( color: MihColors.getPrimaryColor(
MzansiInnovationHub.of( MzansiInnovationHub.of(context)!
context)!
.theme .theme
.mode == .mode ==
"Dark"), "Dark"),
@@ -408,31 +448,37 @@ class _MihHomeState extends State<MihHome> {
], ],
), ),
), ),
); ),
}),
], ],
); );
} else {
return MihHomeError(
errorMessage: asyncSnapshot.hasError
? asyncSnapshot.error.toString()
: "An unknown error occurred",
);
}
}, },
); );
} }
Widget getAction(String proPicUrl) { Widget getAction() {
return Builder(builder: (context) { return Builder(builder: (context) {
return Consumer<MzansiProfileProvider>(
builder: (BuildContext context,
MzansiProfileProvider mzansiProfileProvider, Widget? child) {
ImageProvider<Object>? currentImage;
String imageKey;
if (mzansiProfileProvider.personalHome) {
currentImage = mzansiProfileProvider.userProfilePicture;
imageKey = 'user_${mzansiProfileProvider.userProfilePicUrl}';
} else {
currentImage = mzansiProfileProvider.businessProfilePicture;
imageKey =
'business_${mzansiProfileProvider.businessProfilePicUrl}';
}
return MihPackageAction( return MihPackageAction(
icon: Padding( icon: Padding(
padding: const EdgeInsets.only(left: 5.0), padding: const EdgeInsets.only(left: 5.0),
child: MihCircleAvatar( child: MihCircleAvatar(
imageFile: proPicUrl != "" ? NetworkImage(proPicUrl) : null, key: Key(imageKey),
imageFile: currentImage,
width: 50, width: 50,
editable: false, editable: false,
fileNameController: proPicController, fileNameController: null,
userSelectedfile: null, userSelectedfile: null,
// frameColor: frameColor, // frameColor: frameColor,
frameColor: MihColors.getSecondaryColor( frameColor: MihColors.getSecondaryColor(
@@ -441,17 +487,6 @@ class _MihHomeState extends State<MihHome> {
MzansiInnovationHub.of(context)!.theme.mode == "Dark"), MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
onChange: (_) {}, onChange: (_) {},
), ),
// MIHProfilePicture(
// profilePictureFile: widget.propicFile,
// proPicController: proPicController,
// proPic: null,
// width: 45,
// radius: 21,
// drawerMode: false,
// editable: false,
// frameColor: MihColors.getSecondaryColor(MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
// onChange: (newProPic) {},
// ),
), ),
iconSize: 45, iconSize: 45,
onTap: () { onTap: () {
@@ -461,61 +496,60 @@ class _MihHomeState extends State<MihHome> {
// FocusScope.of(context).unfocus(); // Unfocus any text fields // FocusScope.of(context).unfocus(); // Unfocus any text fields
}, },
); );
},
);
}); });
} }
MIHAppDrawer getActionDrawer(AppUser signedInUser, String proPicUrl) { MIHAppDrawer getActionDrawer() {
return MIHAppDrawer( return MIHAppDrawer();
signedInUser: signedInUser,
propicFile: proPicUrl != "" ? NetworkImage(proPicUrl) : null,
);
} }
MihPackageTools getTools(bool isBusinessUser) { MihPackageTools getTools(
MzansiProfileProvider mzansiProfileProvider, bool isBusinessUser) {
Map<Widget, void Function()?> temp = {}; Map<Widget, void Function()?> temp = {};
temp[const Icon(Icons.person)] = () { temp[const Icon(Icons.person)] = () {
setState(() { setState(() {
_selcetedIndex = 0; mzansiProfileProvider.setPersonalHome(true);
_personalSelected = true;
}); });
}; };
if (isBusinessUser) { if (isBusinessUser) {
temp[const Icon(Icons.business_center)] = () { temp[const Icon(Icons.business_center)] = () {
setState(() { setState(() {
_selcetedIndex = 1; mzansiProfileProvider.setPersonalHome(false);
_personalSelected = false;
}); });
}; };
} }
return MihPackageTools( return MihPackageTools(
tools: temp, tools: temp,
selcetedIndex: _selcetedIndex, selcetedIndex: mzansiProfileProvider.personalHome ? 0 : 1,
); );
} }
List<Widget> getToolBody(HomeArguments profData) { List<Widget> getToolBody(MzansiProfileProvider mzansiProfileProvider) {
List<Widget> toolBodies = []; List<Widget> toolBodies = [];
AppUser? user = mzansiProfileProvider.user;
Business? business = mzansiProfileProvider.business;
BusinessUser? businessUser = mzansiProfileProvider.businessUser;
String userProfilePictureUrl =
mzansiProfileProvider.userProfilePicUrl ?? "";
toolBodies.add( toolBodies.add(
MihPersonalHome( MihPersonalHome(
signedInUser: profData.signedInUser, signedInUser: user!,
personalSelected: _personalSelected, personalSelected: mzansiProfileProvider.personalHome,
business: profData.business, business: business,
businessUser: profData.businessUser, businessUser: businessUser,
propicFile: profData.profilePicUrl != "" propicFile: userProfilePictureUrl != ""
? NetworkImage(profData.profilePicUrl) ? NetworkImage(userProfilePictureUrl)
: null, : null,
isDevActive: AppEnviroment.getEnv() == "Dev", isDevActive: AppEnviroment.getEnv() == "Dev",
isUserNew: profData.signedInUser.username == "", isUserNew: user.username == "",
), ),
); );
if (profData.signedInUser.type != "personal") { if (user.type != "personal") {
toolBodies.add( toolBodies.add(
MihBusinessHome( MihBusinessHome(
signedInUser: profData.signedInUser, isLoading: _isLoadingInitialData,
personalSelected: _personalSelected,
businessUser: profData.businessUser,
business: profData.business,
isBusinessUserNew: profData.businessUser == null,
), ),
); );
} }

View File

@@ -4,10 +4,9 @@ import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_icons.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_tool_body.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_search_bar.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'; 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_providers/mzansi_ai_provider.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_objects/business_user.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_providers/mzansi_profile_provider.dart';
import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart'; import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart';
import 'package:mzansi_innovation_hub/mih_packages/about_mih/package_tile/about_mih_tile.dart'; import 'package:mzansi_innovation_hub/mih_packages/about_mih/package_tile/about_mih_tile.dart';
import 'package:mzansi_innovation_hub/mih_packages/calculator/package_tiles/mih_calculator_tile.dart'; import 'package:mzansi_innovation_hub/mih_packages/calculator/package_tiles/mih_calculator_tile.dart';
@@ -16,22 +15,15 @@ import 'package:mzansi_innovation_hub/mih_packages/mzansi_ai/package_tiles/mzans
import 'package:mzansi_innovation_hub/mih_packages/mzansi_directory/package_tiles/mzansi_directory_tile.dart'; import 'package:mzansi_innovation_hub/mih_packages/mzansi_directory/package_tiles/mzansi_directory_tile.dart';
import 'package:mzansi_innovation_hub/mih_packages/mzansi_profile/business_profile/package_tiles/mzansi_business_profile_tile.dart'; import 'package:mzansi_innovation_hub/mih_packages/mzansi_profile/business_profile/package_tiles/mzansi_business_profile_tile.dart';
import 'package:mzansi_innovation_hub/mih_packages/mzansi_profile/business_profile/package_tiles/mzansi_setup_business_profile_tile.dart'; import 'package:mzansi_innovation_hub/mih_packages/mzansi_profile/business_profile/package_tiles/mzansi_setup_business_profile_tile.dart';
import 'package:mzansi_innovation_hub/mih_packages/patient_profile/pat_manager/package_tiles/pat_manager_tile.dart'; import 'package:mzansi_innovation_hub/mih_packages/patient_manager/pat_manager/package_tiles/pat_manager_tile.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class MihBusinessHome extends StatefulWidget { class MihBusinessHome extends StatefulWidget {
final AppUser signedInUser; final bool isLoading;
final bool personalSelected;
final Business? business;
final BusinessUser? businessUser;
final bool isBusinessUserNew;
const MihBusinessHome({ const MihBusinessHome({
super.key, super.key,
required this.signedInUser, required this.isLoading,
required this.personalSelected,
required this.business,
required this.businessUser,
required this.isBusinessUserNew,
}); });
@override @override
@@ -70,7 +62,6 @@ class _MihBusinessHomeState extends State<MihBusinessHome>
List<Map<String, Widget>> temp = []; List<Map<String, Widget>> temp = [];
temp.add({ temp.add({
"Setup Business": MzansiSetupBusinessProfileTile( "Setup Business": MzansiSetupBusinessProfileTile(
signedInUser: widget.signedInUser,
packageSize: packageSize, packageSize: packageSize,
) )
}); });
@@ -78,15 +69,25 @@ class _MihBusinessHomeState extends State<MihBusinessHome>
} }
List<Map<String, Widget>> setBusinessPackages() { List<Map<String, Widget>> setBusinessPackages() {
MzansiProfileProvider mzansiProfileProvider =
context.read<MzansiProfileProvider>();
// if (mzansiProfileProvider.user == null ||
// mzansiProfileProvider.business == null ||
// mzansiProfileProvider.businessUser == null) {
// return []; // Return empty list if data isn't ready
// }
List<Map<String, Widget>> temp = []; List<Map<String, Widget>> temp = [];
if (mzansiProfileProvider.business == null && !widget.isLoading) {
temp.add({
"Setup Business": MzansiSetupBusinessProfileTile(
packageSize: packageSize,
)
});
return temp;
}
//=============== Biz Profile =============== //=============== Biz Profile ===============
temp.add({ temp.add({
"Business Profile": MzansiBusinessProfileTile( "Business Profile": MzansiBusinessProfileTile(
arguments: BusinessArguments(
widget.signedInUser,
widget.businessUser,
widget.business,
),
packageSize: packageSize, packageSize: packageSize,
) )
}); });
@@ -94,10 +95,10 @@ class _MihBusinessHomeState extends State<MihBusinessHome>
temp.add({ temp.add({
"Patient Manager": PatManagerTile( "Patient Manager": PatManagerTile(
arguments: PatManagerArguments( arguments: PatManagerArguments(
widget.signedInUser, mzansiProfileProvider.user!,
false, false,
widget.business, mzansiProfileProvider.business!,
widget.businessUser, mzansiProfileProvider.businessUser!,
), ),
packageSize: packageSize, packageSize: packageSize,
) )
@@ -105,12 +106,6 @@ class _MihBusinessHomeState extends State<MihBusinessHome>
//=============== Calendar =============== //=============== Calendar ===============
temp.add({ temp.add({
"Calendar": MzansiCalendarTile( "Calendar": MzansiCalendarTile(
arguments: CalendarArguments(
widget.signedInUser,
false,
widget.business,
widget.businessUser,
),
packageSize: packageSize, packageSize: packageSize,
) )
}); });
@@ -118,24 +113,17 @@ class _MihBusinessHomeState extends State<MihBusinessHome>
temp.add({ temp.add({
"Mzansi Directory": MzansiDirectoryTile( "Mzansi Directory": MzansiDirectoryTile(
packageSize: packageSize, packageSize: packageSize,
personalSelected: false,
) )
}); });
//=============== Calculator =============== //=============== Calculator ===============
temp.add({ temp.add({
"Calculator": MihCalculatorTile( "Calculator": MihCalculatorTile(
personalSelected: widget.personalSelected,
packageSize: packageSize, packageSize: packageSize,
) )
}); });
//=============== Mzansi AI =============== //=============== Mzansi AI ===============
temp.add({ temp.add({
"Mzansi AI": MzansiAiTile( "Mzansi AI": MzansiAiTile(
arguments: MzansiAiArguments(
widget.signedInUser,
"",
false,
),
packageSize: packageSize, packageSize: packageSize,
) )
}); });
@@ -143,7 +131,6 @@ class _MihBusinessHomeState extends State<MihBusinessHome>
temp.add({ temp.add({
"About MIH": AboutMihTile( "About MIH": AboutMihTile(
packageSize: packageSize, packageSize: packageSize,
personalSelected: false,
) )
}); });
return temp; return temp;
@@ -194,19 +181,9 @@ class _MihBusinessHomeState extends State<MihBusinessHome>
void initState() { void initState() {
super.initState(); super.initState();
searchController.addListener(searchPackage); searchController.addListener(searchPackage);
if (widget.isBusinessUserNew) {
businessPackagesMap = setNewBusinessUserPackages();
} else {
businessPackagesMap = setBusinessPackages(); businessPackagesMap = setBusinessPackages();
}
searchPackage(); searchPackage();
//Scrolling Banner message
// _marqueeController = AnimationController(
// vsync: this,
// duration: const Duration(seconds: 12),
// );
// _scrollController = ScrollController();
// WidgetsBinding.instance.addPostFrameCallback((_) => _startMarquee());
} }
@override @override
@@ -221,30 +198,25 @@ class _MihBusinessHomeState extends State<MihBusinessHome>
} }
Widget getBody(double width, double height) { Widget getBody(double width, double height) {
return Consumer2<MzansiProfileProvider, MzansiAiProvider>(
builder: (BuildContext context,
MzansiProfileProvider mzansiProfileProvider,
MzansiAiProvider mzansiAiProvider,
Widget? child) {
// if (mzansiProfileProvider.user == null ||
// mzansiProfileProvider.business == null ||
// mzansiProfileProvider.businessUser == null) {
// return Center(
// child: Mihloadingcircle(),
// );
// }
return MihSingleChildScroll( return MihSingleChildScroll(
child: Column( child: Column(
children: [ children: [
// Icon( Padding(
// MihIcons.mihLogo,
// size: width / 2,
// color: MihColors.getSecondaryColor(MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
// ),
// const SizedBox(height: 10),
// Text(
// // "Welcome, ${widget.signedInUser.fname}!",
// "Mzansi Innovation Hub",
// textAlign: TextAlign.center,
// style: TextStyle(
// fontSize: 30,
// fontWeight: FontWeight.bold,
// color: MihColors.getSecondaryColor(MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
// ),
// ),
// const SizedBox(height: 20),
Visibility(
visible: !widget.isBusinessUserNew,
child: Padding(
padding: EdgeInsets.symmetric(horizontal: width / 20), padding: EdgeInsets.symmetric(horizontal: width / 20),
child: Visibility(
visible: mzansiProfileProvider.business != null,
child: MihSearchBar( child: MihSearchBar(
controller: searchController, controller: searchController,
hintText: "Ask Mzansi", hintText: "Ask Mzansi",
@@ -255,25 +227,11 @@ class _MihBusinessHomeState extends State<MihBusinessHome>
hintColor: MihColors.getPrimaryColor( hintColor: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"), MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
onPrefixIconTap: () { onPrefixIconTap: () {
mzansiAiProvider
.setStartUpQuestion(searchController.text);
context.goNamed( context.goNamed(
"mzansiAi", "mzansiAi",
extra: MzansiAiArguments(
widget.signedInUser,
searchController.text.isEmpty
? null
: searchController.text,
false,
),
); );
// Navigator.of(context).pushNamed(
// '/mzansi-ai',
// arguments: MzansiAiArguments(
// widget.signedInUser,
// searchController.text.isEmpty
// ? null
// : searchController.text,
// ),
// );
searchController.clear(); searchController.clear();
}, },
searchFocusNode: _searchFocusNode, searchFocusNode: _searchFocusNode,
@@ -339,5 +297,7 @@ class _MihBusinessHomeState extends State<MihBusinessHome>
], ],
), ),
); );
},
);
} }
} }

View File

@@ -9,18 +9,21 @@ 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/arguments.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_objects/business.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/business_user.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_providers/mzansi_ai_provider.dart';
import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart'; import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart';
import 'package:mzansi_innovation_hub/mih_packages/about_mih/package_tile/about_mih_tile.dart'; import 'package:mzansi_innovation_hub/mih_packages/about_mih/package_tile/about_mih_tile.dart';
import 'package:mzansi_innovation_hub/mih_packages/access_review/package_tile/mih_access_tile.dart'; import 'package:mzansi_innovation_hub/mih_packages/access_review/package_tile/mih_access_tile.dart';
import 'package:mzansi_innovation_hub/mih_packages/calculator/package_tiles/mih_calculator_tile.dart'; import 'package:mzansi_innovation_hub/mih_packages/calculator/package_tiles/mih_calculator_tile.dart';
import 'package:mzansi_innovation_hub/mih_packages/calendar/package_tiles/mzansi_calendar_tile.dart'; import 'package:mzansi_innovation_hub/mih_packages/calendar/package_tiles/mzansi_calendar_tile.dart';
import 'package:mzansi_innovation_hub/mih_packages/mine_sweeper/package_tiles/mih_mine_sweeper_tile.dart';
import 'package:mzansi_innovation_hub/mih_packages/mzansi_ai/package_tiles/mzansi_ai_tile.dart'; import 'package:mzansi_innovation_hub/mih_packages/mzansi_ai/package_tiles/mzansi_ai_tile.dart';
import 'package:mzansi_innovation_hub/mih_packages/mzansi_directory/package_tiles/mzansi_directory_tile.dart'; import 'package:mzansi_innovation_hub/mih_packages/mzansi_directory/package_tiles/mzansi_directory_tile.dart';
import 'package:mzansi_innovation_hub/mih_packages/mzansi_profile/personal_profile/package_tiles/mzansi_profile_tile.dart'; import 'package:mzansi_innovation_hub/mih_packages/mzansi_profile/personal_profile/package_tiles/mzansi_profile_tile.dart';
import 'package:mzansi_innovation_hub/mih_packages/mzansi_profile/personal_profile/package_tiles/mzansi_setup_profile_tile.dart'; import 'package:mzansi_innovation_hub/mih_packages/mzansi_profile/personal_profile/package_tiles/mzansi_setup_profile_tile.dart';
import 'package:mzansi_innovation_hub/mih_packages/mzansi_wallet/package_tiles/mih_wallet_tile.dart'; import 'package:mzansi_innovation_hub/mih_packages/mzansi_wallet/package_tiles/mih_wallet_tile.dart';
import 'package:mzansi_innovation_hub/mih_packages/patient_profile/pat_profile/package_tiles/patient_profile_tile.dart'; import 'package:mzansi_innovation_hub/mih_packages/patient_manager/pat_profile/package_tiles/patient_profile_tile.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class MihPersonalHome extends StatefulWidget { class MihPersonalHome extends StatefulWidget {
final AppUser signedInUser; final AppUser signedInUser;
@@ -78,8 +81,6 @@ class _MihPersonalHomeState extends State<MihPersonalHome>
List<Map<String, Widget>> temp = []; List<Map<String, Widget>> temp = [];
temp.add({ temp.add({
"Setup Profile": MzansiSetupProfileTile( "Setup Profile": MzansiSetupProfileTile(
signedInUser: widget.signedInUser,
propicFile: widget.propicFile,
packageSize: packageSize, packageSize: packageSize,
) )
}); });
@@ -91,15 +92,12 @@ class _MihPersonalHomeState extends State<MihPersonalHome>
//=============== Mzansi Profile =============== //=============== Mzansi Profile ===============
temp.add({ temp.add({
"Mzansi Profile": MzansiProfileTile( "Mzansi Profile": MzansiProfileTile(
signedInUser: widget.signedInUser,
propicFile: widget.propicFile,
packageSize: packageSize, packageSize: packageSize,
) )
}); });
//=============== Mzansi Wallet =============== //=============== Mzansi Wallet ===============
temp.add({ temp.add({
"Mzansi Wallet": MihWalletTile( "Mzansi Wallet": MihWalletTile(
signedInUser: widget.signedInUser,
packageSize: packageSize, packageSize: packageSize,
) )
}); });
@@ -120,35 +118,29 @@ class _MihPersonalHomeState extends State<MihPersonalHome>
temp.add({ temp.add({
"Mzansi Directory": MzansiDirectoryTile( "Mzansi Directory": MzansiDirectoryTile(
packageSize: packageSize, packageSize: packageSize,
personalSelected: true,
) )
}); });
//=============== Calendar =============== //=============== Calendar ===============
temp.add({ temp.add({
"Calendar": MzansiCalendarTile( "Calendar": MzansiCalendarTile(
arguments: CalendarArguments(
widget.signedInUser,
true,
widget.business,
widget.businessUser,
),
packageSize: packageSize, packageSize: packageSize,
) )
}); });
//=============== Mzansi AI =============== //=============== Mzansi AI ===============
temp.add({ temp.add({
"Mzansi AI": MzansiAiTile( "Mzansi AI": MzansiAiTile(
arguments: MzansiAiArguments(
widget.signedInUser,
"",
true,
),
packageSize: packageSize, packageSize: packageSize,
) )
}); });
//=============== Calculator =============== //=============== Calculator ===============
temp.add({ temp.add({
"Calculator": MihCalculatorTile( "Calculator": MihCalculatorTile(
packageSize: packageSize,
)
});
//=============== Mine Sweeper ===============
temp.add({
"Mine Sweeper": MihMineSweeperTile(
personalSelected: widget.personalSelected, personalSelected: widget.personalSelected,
packageSize: packageSize, packageSize: packageSize,
) )
@@ -156,7 +148,6 @@ class _MihPersonalHomeState extends State<MihPersonalHome>
//=============== MIH Access =============== //=============== MIH Access ===============
temp.add({ temp.add({
"MIH Access": MihAccessTile( "MIH Access": MihAccessTile(
signedInUser: widget.signedInUser,
packageSize: packageSize, packageSize: packageSize,
) )
}); });
@@ -164,7 +155,6 @@ class _MihPersonalHomeState extends State<MihPersonalHome>
temp.add({ temp.add({
"About MIH": AboutMihTile( "About MIH": AboutMihTile(
packageSize: packageSize, packageSize: packageSize,
personalSelected: true,
) )
}); });
//=============== Dev =============== //=============== Dev ===============
@@ -259,6 +249,9 @@ class _MihPersonalHomeState extends State<MihPersonalHome>
} }
Widget getBody(double width, double height) { Widget getBody(double width, double height) {
return Consumer<MzansiAiProvider>(
builder: (BuildContext context, MzansiAiProvider mzansiAiProvider,
Widget? child) {
return MihSingleChildScroll( return MihSingleChildScroll(
child: Column( child: Column(
children: [ children: [
@@ -293,25 +286,11 @@ class _MihPersonalHomeState extends State<MihPersonalHome>
hintColor: MihColors.getPrimaryColor( hintColor: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"), MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
onPrefixIconTap: () { onPrefixIconTap: () {
mzansiAiProvider
.setStartUpQuestion(searchController.text);
context.goNamed( context.goNamed(
"mzansiAi", "mzansiAi",
extra: MzansiAiArguments(
widget.signedInUser,
searchController.text.isEmpty
? null
: searchController.text,
true,
),
); );
// Navigator.of(context).pushNamed(
// '/mzansi-ai',
// arguments: MzansiAiArguments(
// widget.signedInUser,
// searchController.text.isEmpty
// ? null
// : searchController.text,
// ),
// );
searchController.clear(); searchController.clear();
}, },
searchFocusNode: _searchFocusNode, searchFocusNode: _searchFocusNode,
@@ -378,5 +357,7 @@ class _MihPersonalHomeState extends State<MihPersonalHome>
], ],
), ),
); );
},
);
} }
} }

View File

@@ -0,0 +1,113 @@
import 'package:flutter/material.dart';
import 'package:mzansi_innovation_hub/main.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_circle_avatar.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_providers/mih_mine_sweeper_provider.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_providers/mzansi_profile_provider.dart';
import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart';
import 'package:provider/provider.dart';
class BuildMinesweeperLeaderboardList extends StatefulWidget {
const BuildMinesweeperLeaderboardList({super.key});
@override
State<BuildMinesweeperLeaderboardList> createState() =>
_BuildMinesweeperLeaderboardListState();
}
class _BuildMinesweeperLeaderboardListState
extends State<BuildMinesweeperLeaderboardList> {
Color getMedalColor(int index) {
switch (index) {
case (0):
return MihColors.getGoldColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark");
case (1):
return MihColors.getSilverColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark");
case (2):
return MihColors.getBronze(
MzansiInnovationHub.of(context)!.theme.mode == "Dark");
default:
return MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark");
}
}
@override
Widget build(BuildContext context) {
final double width = MediaQuery.sizeOf(context).width;
return Consumer2<MzansiProfileProvider, MihMineSweeperProvider>(
builder: (BuildContext context, MzansiProfileProvider profileProvider,
MihMineSweeperProvider mineSweeperProvider, Widget? child) {
return ListView.separated(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
separatorBuilder: (BuildContext context, index) {
return Divider(
color: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
);
},
itemCount: mineSweeperProvider.leaderboard!.length,
itemBuilder: (context, index) {
return Padding(
padding: EdgeInsets.symmetric(horizontal: width / 20),
child: Row(
children: [
Text(
"#${index + 1}",
style: TextStyle(
fontSize: 25,
color: getMedalColor(index),
),
),
const SizedBox(width: 10),
MihCircleAvatar(
key: UniqueKey(),
imageFile:
mineSweeperProvider.leaderboardUserPictures.isNotEmpty
? mineSweeperProvider.leaderboardUserPictures[index]
: null,
width: 80,
editable: false,
fileNameController: null,
userSelectedfile: null,
frameColor: getMedalColor(index),
backgroundColor: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
onChange: () {},
),
const SizedBox(width: 10),
Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"${mineSweeperProvider.leaderboard![index].username}${profileProvider.user!.username == mineSweeperProvider.leaderboard![index].username ? " (You)" : ""}",
textAlign: TextAlign.left,
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
color: getMedalColor(index),
),
),
Text(
"Score: ${mineSweeperProvider.leaderboard![index].game_score}\nTime: ${mineSweeperProvider.leaderboard![index].game_time}",
textAlign: TextAlign.left,
style: TextStyle(
fontSize: 18,
// fontWeight: FontWeight.bold,
color: getMedalColor(index),
),
),
],
)
],
),
);
},
);
},
);
}
}

View File

@@ -0,0 +1,96 @@
import 'package:flutter/material.dart';
import 'package:mzansi_innovation_hub/main.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_providers/mih_mine_sweeper_provider.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_providers/mzansi_profile_provider.dart';
import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart';
import 'package:provider/provider.dart';
class BuildMyScoreBoardList extends StatefulWidget {
const BuildMyScoreBoardList({super.key});
@override
State<BuildMyScoreBoardList> createState() =>
_BuildMinesweeperLeaderboardListState();
}
class _BuildMinesweeperLeaderboardListState
extends State<BuildMyScoreBoardList> {
Color getMedalColor(int index) {
switch (index) {
case (0):
return MihColors.getGoldColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark");
case (1):
return MihColors.getSilverColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark");
case (2):
return MihColors.getBronze(
MzansiInnovationHub.of(context)!.theme.mode == "Dark");
default:
return MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark");
}
}
@override
Widget build(BuildContext context) {
final double width = MediaQuery.sizeOf(context).width;
return Consumer2<MzansiProfileProvider, MihMineSweeperProvider>(
builder: (BuildContext context, MzansiProfileProvider profileProvider,
MihMineSweeperProvider mineSweeperProvider, Widget? child) {
return ListView.separated(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
separatorBuilder: (BuildContext context, index) {
return Divider(
color: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
);
},
itemCount: mineSweeperProvider.myScoreboard!.length,
itemBuilder: (context, index) {
return Padding(
padding: EdgeInsets.symmetric(horizontal: width / 20),
child: Row(
children: [
Text(
"#${index + 1}",
style: TextStyle(
fontSize: 25,
color: getMedalColor(index),
),
),
const SizedBox(width: 10),
Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"Score: ${mineSweeperProvider.myScoreboard![index].game_score}",
textAlign: TextAlign.left,
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
color: getMedalColor(index),
),
),
Text(
"Time: ${mineSweeperProvider.myScoreboard![index].game_time}",
textAlign: TextAlign.left,
style: TextStyle(
fontSize: 18,
// fontWeight: FontWeight.bold,
color: getMedalColor(index),
),
),
],
)
],
),
);
},
);
},
);
}
}

View File

@@ -0,0 +1,13 @@
class BoardSquare {
bool hasBomb;
int bombsAround;
bool isOpened;
bool isFlagged;
BoardSquare({
this.hasBomb = false,
this.bombsAround = 0,
this.isOpened = false,
this.isFlagged = false,
});
}

View File

@@ -0,0 +1,85 @@
import 'package:flutter/material.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_circle_avatar.dart';
import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart';
import 'package:redacted/redacted.dart';
class LeaderboardUserRanking extends StatelessWidget {
final int index;
final String proPicUrl;
final String username;
final dynamic gameScore;
final String gameTime;
final bool isCurrentUser;
final Future<ImageProvider<Object>?> Function(String) getUserPicture;
const LeaderboardUserRanking({
super.key,
required this.index,
required this.proPicUrl,
required this.username,
required this.gameScore,
required this.gameTime,
required this.isCurrentUser,
required this.getUserPicture,
});
@override
Widget build(BuildContext context) {
return FutureBuilder(
future: getUserPicture(proPicUrl),
builder: (context, asyncSnapshot) {
bool isLoading =
asyncSnapshot.connectionState == ConnectionState.waiting;
KenLogger.success("URL: ${asyncSnapshot.data.toString()}");
return ListTile(
leading: Row(
mainAxisSize: MainAxisSize.min,
children: [
Text(
"#${index + 1}",
style: const TextStyle(
fontSize: 25,
),
),
const SizedBox(width: 10),
MihCircleAvatar(
key: ValueKey(asyncSnapshot.data
.toString()), // Use ValueKey for stable identity
imageFile: asyncSnapshot.data,
width: 60,
editable: false,
fileNameController: null,
userSelectedfile: null,
frameColor: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
backgroundColor: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
onChange: () {},
),
],
),
title: Text(
"$username${isCurrentUser ? " (You)" : ""}",
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
color: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
),
).redacted(context: context, redact: isLoading),
subtitle: Text(
"Score: $gameScore\nTime: $gameTime",
style: TextStyle(
fontSize: 18,
color: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
),
).redacted(context: context, redact: isLoading),
);
},
);
}
}

View File

@@ -0,0 +1,174 @@
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_dropdwn_field.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_window.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_providers/mih_mine_sweeper_provider.dart';
import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart';
import 'package:provider/provider.dart';
class MihMineSweeperStartGameWindow extends StatefulWidget {
final void Function()? onPressed;
const MihMineSweeperStartGameWindow({
super.key,
required this.onPressed,
});
@override
State<MihMineSweeperStartGameWindow> createState() =>
_MihMineSweeperStartGameWindowState();
}
class _MihMineSweeperStartGameWindowState
extends State<MihMineSweeperStartGameWindow> {
TextEditingController modeController = TextEditingController();
final _formKey = GlobalKey<FormState>();
void applyGameSettings(MihMineSweeperProvider mihMineSweeperProvider) {
mihMineSweeperProvider.setDifficulty(modeController.text);
switch (mihMineSweeperProvider.difficulty) {
case ("Very Easy"):
mihMineSweeperProvider.setRowCount(6);
mihMineSweeperProvider.setCoulmnCount(6);
mihMineSweeperProvider.setTotalMines(5);
// mihMineSweeperProvider.setRowCount(5);
// mihMineSweeperProvider.setCoulmnCount(5);
// mihMineSweeperProvider.setTotalMines(3);
break;
case ("Easy"):
mihMineSweeperProvider.setRowCount(8);
mihMineSweeperProvider.setCoulmnCount(8);
mihMineSweeperProvider.setTotalMines(10);
// mihMineSweeperProvider.setRowCount(10);
// mihMineSweeperProvider.setCoulmnCount(10);
// mihMineSweeperProvider.setTotalMines(15);
break;
case ("Intermediate"):
mihMineSweeperProvider.setRowCount(10);
mihMineSweeperProvider.setCoulmnCount(10);
mihMineSweeperProvider.setTotalMines(18);
// mihMineSweeperProvider.setRowCount(15);
// mihMineSweeperProvider.setCoulmnCount(10);
// mihMineSweeperProvider.setTotalMines(23);
break;
case ("Hard"):
mihMineSweeperProvider.setRowCount(12);
mihMineSweeperProvider.setCoulmnCount(10);
mihMineSweeperProvider.setTotalMines(30);
// mihMineSweeperProvider.setRowCount(20);
// mihMineSweeperProvider.setCoulmnCount(10);
// mihMineSweeperProvider.setTotalMines(30);
break;
default:
break;
}
}
String getModeConfig() {
switch (modeController.text) {
case ("Very Easy"):
return "Columns: 6\nRows: 6\nBombs: 5";
case ("Easy"):
return "Columns: 8\nRows: 8\nBombs: 10";
case ("Intermediate"):
return "Columns: 10\nRows: 10\nBombs: 18";
case ("Hard"):
return "Columns: 10\nRows: 12\nBombs: 30";
default:
return "Error";
}
}
void _onModeChanged() {
setState(() {});
}
@override
void dispose() {
modeController.removeListener(_onModeChanged);
modeController.dispose();
super.dispose();
}
@override
void initState() {
super.initState();
modeController.text = context.read<MihMineSweeperProvider>().difficulty;
modeController.addListener(_onModeChanged);
}
@override
Widget build(BuildContext context) {
return MihPackageWindow(
fullscreen: false,
windowTitle: "New Game Settings",
onWindowTapClose: () {
context.pop();
},
windowBody: Consumer<MihMineSweeperProvider>(
builder: (BuildContext context,
MihMineSweeperProvider mihMineSweeperProvider, Widget? child) {
return Column(
children: [
MihForm(
formKey: _formKey,
formFields: [
MihDropdownField(
controller: modeController,
hintText: "Difficulty",
dropdownOptions: [
"Very Easy",
"Easy",
"Intermediate",
"Hard"
],
requiredText: true,
editable: true,
enableSearch: false,
),
const SizedBox(height: 10),
Text(
getModeConfig(),
style: TextStyle(
color: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 25),
Center(
child: MihButton(
onPressed: () {
applyGameSettings(mihMineSweeperProvider);
context.pop();
widget.onPressed?.call();
},
buttonColor: MihColors.getGreenColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
width: 300,
child: Text(
"Start Game",
style: TextStyle(
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
),
),
],
),
],
);
},
),
);
}
}

View File

@@ -0,0 +1,112 @@
import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.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_config/mih_colors.dart';
import 'package:mzansi_innovation_hub/mih_packages/mine_sweeper/components/board_square.dart';
class MineTile extends StatelessWidget {
final BoardSquare square;
final VoidCallback onTap;
final VoidCallback onLongPress;
const MineTile({
super.key,
required this.square,
required this.onTap,
required this.onLongPress,
});
Widget _getTileContent(BuildContext context) {
if (square.isFlagged) {
return Icon(
Icons.flag,
color: MihColors.getRedColor(
MzansiInnovationHub.of(context)!.theme.mode != "Dark",
),
);
}
if (square.isOpened) {
if (square.hasBomb) {
return const Icon(FontAwesomeIcons.bomb, color: Colors.black);
} else if (square.bombsAround > 0) {
// Display bomb count
return Center(
child: Text(
'${square.bombsAround}',
style: TextStyle(
fontSize: 25,
fontWeight: FontWeight.bold,
color: _getTileColor(square.bombsAround, context),
),
),
);
} else {
// Opened, but no bomb count (empty square)
return const SizedBox.shrink();
}
}
// Default: Unopened tile
return const SizedBox.shrink();
}
Color _getTileColor(int bombsAround, BuildContext context) {
// Choose colors based on standard Minesweeper appearance
switch (bombsAround) {
case 1:
return MihColors.getBluishPurpleColor(
MzansiInnovationHub.of(context)!.theme.mode != "Dark",
);
// return Colors.blue;
case 2:
return MihColors.getGreenColor(
MzansiInnovationHub.of(context)!.theme.mode != "Dark",
);
// return Colors.green;
case 3:
return MihColors.getRedColor(
MzansiInnovationHub.of(context)!.theme.mode != "Dark",
);
// return Colors.red;
case 4:
return MihColors.getPurpleColor(
MzansiInnovationHub.of(context)!.theme.mode != "Dark",
);
// return Colors.purple;
case 5:
return MihColors.getOrangeColor(
MzansiInnovationHub.of(context)!.theme.mode != "Dark",
);
// return Colors.brown;
default:
// return MihColors.getBluishPurpleColor(
// MzansiInnovationHub.of(context)!.theme.mode == "Dark",
// );
return Colors.black;
}
}
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(1.0),
child: MihButton(
onPressed: onTap,
onLongPressed: onLongPress,
buttonColor: square.isOpened
? MihColors.getGreyColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark",
)
: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark",
),
width: 50,
height: 50,
borderRadius: 3,
child: _getTileContent(context),
),
);
}
}

View File

@@ -0,0 +1,101 @@
import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.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_components/mih_providers/mih_banner_ad_provider.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_providers/mih_mine_sweeper_provider.dart';
import 'package:mzansi_innovation_hub/mih_packages/mine_sweeper/package_tools/mih_mine_sweeper_leader_board.dart';
import 'package:mzansi_innovation_hub/mih_packages/mine_sweeper/package_tools/mine_sweeper_game.dart';
import 'package:mzansi_innovation_hub/mih_packages/mine_sweeper/package_tools/mine_sweeper_quick_start_guide.dart';
import 'package:mzansi_innovation_hub/mih_packages/mine_sweeper/package_tools/my_score_board.dart';
import 'package:provider/provider.dart';
class MihMineSweeper extends StatefulWidget {
const MihMineSweeper({super.key});
@override
State<MihMineSweeper> createState() => _MihMineSweeperState();
}
class _MihMineSweeperState extends State<MihMineSweeper> {
@override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) async {
context.read<MihBannerAdProvider>().loadBannerAd();
});
}
@override
Widget build(BuildContext context) {
return MihPackage(
appActionButton: getAction(),
appTools: getTools(),
appToolTitles: getToolTitle(),
appBody: getToolBody(),
selectedbodyIndex: context.watch<MihMineSweeperProvider>().toolIndex,
onIndexChange: (newIndex) {
context.read<MihMineSweeperProvider>().setToolIndex(newIndex);
},
);
}
MihPackageAction getAction() {
return MihPackageAction(
icon: const Icon(Icons.arrow_back),
iconSize: 35,
onTap: () {
MihMineSweeperProvider mineSweeperProvider =
context.read<MihMineSweeperProvider>();
mineSweeperProvider.setToolIndex(0);
mineSweeperProvider.setDifficulty("Easy");
context.goNamed(
'mihHome',
);
FocusScope.of(context).unfocus();
},
);
}
MihPackageTools getTools() {
Map<Widget, void Function()?> temp = {};
temp[const Icon(FontAwesomeIcons.bomb)] = () {
context.read<MihMineSweeperProvider>().setToolIndex(0);
};
temp[const Icon(Icons.leaderboard_rounded)] = () {
context.read<MihMineSweeperProvider>().setToolIndex(1);
};
temp[const Icon(Icons.perm_identity_rounded)] = () {
context.read<MihMineSweeperProvider>().setToolIndex(2);
};
temp[const Icon(Icons.rule_rounded)] = () {
context.read<MihMineSweeperProvider>().setToolIndex(3);
};
return MihPackageTools(
tools: temp,
selcetedIndex: context.watch<MihMineSweeperProvider>().toolIndex,
);
}
List<String> getToolTitle() {
List<String> toolTitles = [
"Minesweeper",
"Leader Board",
"My Scores",
"Guide",
];
return toolTitles;
}
List<Widget> getToolBody() {
List<Widget> toolBodies = [
const MineSweeperGame(),
const MihMineSweeperLeaderBoard(),
const MyScoreBoard(),
const MineSweeperQuickStartGuide(),
];
return toolBodies;
}
}

View File

@@ -1,43 +1,35 @@
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart'; import 'package:go_router/go_router.dart';
import 'package:mzansi_innovation_hub/main.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'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_icons.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_objects/arguments.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_tile.dart';
import 'package:flutter/material.dart';
import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart'; import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart';
class PatientProfileTile extends StatefulWidget { class MihMineSweeperTile extends StatefulWidget {
final PatientViewArguments arguments; final bool personalSelected;
final double packageSize; final double packageSize;
const MihMineSweeperTile({
const PatientProfileTile({
super.key, super.key,
required this.arguments, required this.personalSelected,
required this.packageSize, required this.packageSize,
}); });
@override @override
State<PatientProfileTile> createState() => _PatientProfileTileState(); State<MihMineSweeperTile> createState() => _MihMineSweeperTileState();
} }
class _PatientProfileTileState extends State<PatientProfileTile> { class _MihMineSweeperTileState extends State<MihMineSweeperTile> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return MihPackageTile( return MihPackageTile(
authenticateUser: true,
onTap: () { onTap: () {
context.goNamed( context.goNamed(
'patientProfile', "mihMinesweeper",
extra: widget.arguments,
); );
// Navigator.of(context).pushNamed(
// '/patient-profile',
// arguments: widget.arguments,
// );
}, },
appName: "Patient Profile", appName: "Minesweeper",
appIcon: Icon( appIcon: Icon(
MihIcons.patientProfile, MihIcons.mineSweeper,
color: MihColors.getSecondaryColor( color: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"), MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
// size: widget.packageSize, // size: widget.packageSize,

View File

@@ -0,0 +1,198 @@
import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.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_dropdwn_field.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_pop_up_messages/mih_loading_circle.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_providers/mih_mine_sweeper_provider.dart';
import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart';
import 'package:mzansi_innovation_hub/mih_packages/mine_sweeper/builders/build_minesweeper_leaderboard_list.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_file_services.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_minesweeper_services.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_validation_services.dart';
import 'package:provider/provider.dart';
class MihMineSweeperLeaderBoard extends StatefulWidget {
const MihMineSweeperLeaderBoard({super.key});
@override
State<MihMineSweeperLeaderBoard> createState() =>
_MihMineSweeperLeaderBoardState();
}
class _MihMineSweeperLeaderBoardState extends State<MihMineSweeperLeaderBoard> {
TextEditingController filterController = TextEditingController();
Future<void> initialiseLeaderboard() async {
MihMineSweeperProvider mineSweeperProvider =
context.read<MihMineSweeperProvider>();
filterController.text = mineSweeperProvider.difficulty;
KenLogger.success("getting data");
await MihMinesweeperServices().getTop20Leaderboard(mineSweeperProvider);
List<ImageProvider<Object>?> userPictures = [];
String userPicUrl = "";
for (final ranking in mineSweeperProvider.leaderboard!) {
userPicUrl = await MihFileApi.getMinioFileUrl(ranking.proPicUrl, context);
userPictures.add(NetworkImage(userPicUrl));
}
mineSweeperProvider.setLeaderboardUserPictures(
leaderboardUserPictures: userPictures);
}
void refreshLeaderBoard(
MihMineSweeperProvider mineSweeperProvider, String difficulty) {
mineSweeperProvider.setDifficulty(difficulty);
mineSweeperProvider.setLeaderboard(leaderboard: null);
mineSweeperProvider.setMyScoreboard(myScoreboard: null);
initialiseLeaderboard();
}
@override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) async {
await initialiseLeaderboard();
});
}
@override
Widget build(BuildContext context) {
final double width = MediaQuery.sizeOf(context).width;
return Consumer<MihMineSweeperProvider>(
builder: (BuildContext context,
MihMineSweeperProvider mineSweeperProvider, Widget? child) {
return RefreshIndicator(
onRefresh: () async {
refreshLeaderBoard(mineSweeperProvider, filterController.text);
},
child: MihPackageToolBody(
borderOn: false,
bodyItem: getBody(width),
),
);
},
);
}
Widget getBody(double width) {
return Consumer<MihMineSweeperProvider>(
builder: (BuildContext context,
MihMineSweeperProvider mineSweeperProvider, Widget? child) {
if (mineSweeperProvider.leaderboard == null) {
return Center(
child: Mihloadingcircle(),
);
} else {
return SingleChildScrollView(
physics: const AlwaysScrollableScrollPhysics(),
child: Column(
children: [
Padding(
padding: EdgeInsets.symmetric(horizontal: width / 20),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.end,
mainAxisSize: MainAxisSize.max,
children: [
Flexible(
child: MihDropdownField(
controller: filterController,
hintText: "Leaderboards",
dropdownOptions: const [
"Very Easy",
"Easy",
"Intermediate",
"Hard",
],
requiredText: true,
editable: true,
enableSearch: false,
validator: (value) {
return MihValidationServices().isEmpty(value);
},
onSelected: (selection) {
refreshLeaderBoard(mineSweeperProvider, selection!);
},
),
),
],
),
),
const SizedBox(height: 10),
mineSweeperProvider.leaderboard!.isEmpty
? Padding(
padding: const EdgeInsets.symmetric(horizontal: 10.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
const SizedBox(height: 50),
Icon(
MihIcons.mineSweeper,
size: 165,
color: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
),
const SizedBox(height: 10),
Text(
"Be the first on the leaderboard.",
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),
Center(
child: RichText(
textAlign: TextAlign.center,
text: TextSpan(
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.normal,
color: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!
.theme
.mode ==
"Dark"),
),
children: [
TextSpan(text: "Press "),
WidgetSpan(
alignment: PlaceholderAlignment.middle,
child: Icon(
FontAwesomeIcons.bomb,
size: 20,
color: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!
.theme
.mode ==
"Dark"),
),
),
TextSpan(text: " and start a new game"),
],
),
),
),
],
),
)
: BuildMinesweeperLeaderboardList(),
],
),
);
}
},
);
}
}

View File

@@ -0,0 +1,795 @@
import 'dart:async';
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:flutter_speed_dial/flutter_speed_dial.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.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_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_package_tool_body.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_components/mih_providers/mih_mine_sweeper_provider.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_providers/mzansi_profile_provider.dart';
import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart';
import 'package:mzansi_innovation_hub/mih_packages/mine_sweeper/components/board_square.dart';
import 'package:mzansi_innovation_hub/mih_packages/mine_sweeper/components/mih_mine_sweeper_start_game_window.dart';
import 'package:mzansi_innovation_hub/mih_packages/mine_sweeper/components/mine_tile.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_minesweeper_services.dart';
import 'package:provider/provider.dart';
class MineSweeperGame extends StatefulWidget {
const MineSweeperGame({super.key});
@override
State<MineSweeperGame> createState() => _MineSweeperGameState();
}
class _MineSweeperGameState extends State<MineSweeperGame> {
List<List<BoardSquare>> board = [];
bool isGameOver = false;
bool isGameWon = false;
int squaresLeft = -1;
Timer? _timer;
int _milliseconds = 0;
bool _isRunning = false;
static const int millisecondsPerUpdate = 100;
double timeStringToTotalSeconds(String timeString) {
try {
List<String> parts = timeString.split(':');
if (parts.length != 4) {
return 0.0;
}
double hours = double.parse(parts[0]);
double minutes = double.parse(parts[1]);
double seconds = double.parse(parts[2]);
double milliseconds = double.parse(parts[3]);
double totalSeconds =
(hours * 3600) + (minutes * 60) + seconds + (milliseconds / 100);
return totalSeconds;
} catch (e) {
print("Error parsing time string: $e");
return 0.0;
}
}
double calculateGameScore(MihMineSweeperProvider mihMineSweeperProvider) {
int scoreConst = 10000;
double dificusltyMultiplier;
switch (mihMineSweeperProvider.difficulty) {
case ("Very Easy"):
dificusltyMultiplier = 0.5;
break;
case ("Easy"):
dificusltyMultiplier = 1.0;
break;
case ("Intermediate"):
dificusltyMultiplier = 2.5;
break;
case ("Hard"):
dificusltyMultiplier = 5.0;
break;
default:
dificusltyMultiplier = 0.0;
break;
}
double rawScore = (scoreConst * dificusltyMultiplier) /
timeStringToTotalSeconds(_formatTime());
String scoreString = rawScore.toStringAsFixed(5);
return double.parse(scoreString);
}
void startTimer() {
if (_isRunning) return;
_isRunning = true;
_timer = Timer.periodic(const Duration(milliseconds: millisecondsPerUpdate),
(timer) {
setState(() {
_milliseconds += millisecondsPerUpdate; // Increment by the interval
});
});
}
void stopTimer() {
_timer?.cancel();
setState(() {
_isRunning = false;
});
}
void resetTimer() {
stopTimer(); // Stop the timer first
setState(() {
_milliseconds = 0; // Reset the time to zero
});
}
String _formatTime() {
Duration duration = Duration(milliseconds: _milliseconds);
final int hours = duration.inHours;
final int minutes = duration.inMinutes.remainder(60);
final int seconds = duration.inSeconds.remainder(60);
final int centiseconds = (duration.inMilliseconds.remainder(1000)) ~/ 10;
String hoursStr = hours.toString().padLeft(2, '0');
String minutesStr = minutes.toString().padLeft(2, '0');
String secondsStr = seconds.toString().padLeft(2, '0');
String centiStr = centiseconds.toString().padLeft(2, '0');
return '$hoursStr:$minutesStr:$secondsStr:$centiStr';
}
void showStartGameWindow(
MihMineSweeperProvider mihMineSweeperProvider,
) {
// easy - 10 * 10 & 15 bombs
// Intermediate - 10 * 15 & 23 bombs
// Hard - 10 * 20 & 30 bombs
showDialog(
context: context,
builder: (context) {
return MihMineSweeperStartGameWindow(
onPressed: () {
resetTimer();
mihMineSweeperProvider
.setDifficulty(mihMineSweeperProvider.difficulty);
setState(() => initializeBoard(mihMineSweeperProvider));
},
);
});
}
// --- GAME INITIALIZATION LOGIC ---
void initializeBoard(MihMineSweeperProvider mihMineSweeperProvider) {
// 1. Create a board of empty squares
board = List.generate(
mihMineSweeperProvider.rowCount,
(i) => List.generate(
mihMineSweeperProvider.columnCount,
(j) => BoardSquare(),
),
);
// 2. Place bombs randomly
placeBombs(mihMineSweeperProvider);
// 3. Calculate the number of bombs around each non-mine square
calculateBombsAround(mihMineSweeperProvider);
// Reset state variables
squaresLeft =
mihMineSweeperProvider.rowCount * mihMineSweeperProvider.columnCount;
isGameOver = false;
isGameWon = false;
// You'd typically add a call to setState here, but it's in initState.
startTimer();
}
void placeBombs(MihMineSweeperProvider mihMineSweeperProvider) {
final Random random = Random();
int bombsPlaced = 0;
while (bombsPlaced < mihMineSweeperProvider.totalMines) {
int r = random.nextInt(mihMineSweeperProvider.rowCount);
int c = random.nextInt(mihMineSweeperProvider.columnCount);
if (!board[r][c].hasBomb) {
board[r][c].hasBomb = true;
bombsPlaced++;
}
}
}
void calculateBombsAround(MihMineSweeperProvider mihMineSweeperProvider) {
for (int r = 0; r < mihMineSweeperProvider.rowCount; r++) {
for (int c = 0; c < mihMineSweeperProvider.columnCount; c++) {
if (!board[r][c].hasBomb) {
int count = 0;
// Check the 8 neighbors
for (int i = -1; i <= 1; i++) {
for (int j = -1; j <= 1; j++) {
if (i == 0 && j == 0) continue; // Skip the current square
int neighborR = r + i;
int neighborC = c + j;
// Check if neighbor is within bounds
if (neighborR >= 0 &&
neighborR < mihMineSweeperProvider.rowCount &&
neighborC >= 0 &&
neighborC < mihMineSweeperProvider.columnCount) {
if (board[neighborR][neighborC].hasBomb) {
count++;
}
}
}
}
board[r][c].bombsAround = count;
}
}
}
}
// Handles recursive opening of zero-squares
void _expandZeros(
MihMineSweeperProvider mihMineSweeperProvider, int r, int c) {
if (r < 0 ||
r >= mihMineSweeperProvider.rowCount ||
c < 0 ||
c >= mihMineSweeperProvider.columnCount ||
board[r][c].isOpened) {
return;
}
BoardSquare square = board[r][c];
// Open the current square
square.isOpened = true;
squaresLeft--;
// If it's a zero square, recursively call for neighbors
if (square.bombsAround == 0) {
// Check all 8 neighbors (not just 4 sides, for standard Minesweeper expansion)
for (int i = -1; i <= 1; i++) {
for (int j = -1; j <= 1; j++) {
_expandZeros(mihMineSweeperProvider, r + i, c + j);
}
}
}
}
Future<void> handleTap(MzansiProfileProvider profileProvider,
MihMineSweeperProvider mihMineSweeperProvider, int r, int c) async {
if (isGameOver || board[r][c].isOpened || board[r][c].isFlagged) {
return;
}
// 1. Check for bomb (LOSS)
if (board[r][c].hasBomb) {
stopTimer();
setState(() {
board[r][c].isOpened = true;
isGameOver = true;
// lose alert
showDialog(
context: context,
builder: (context) {
return MihPackageAlert(
alertIcon: Padding(
padding: const EdgeInsets.all(8.0),
child: Icon(
FontAwesomeIcons.bomb,
color: MihColors.getRedColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
size: 100,
),
),
alertTitle: "Better Luck Next Time",
alertBody: Column(
children: [
Text(
"Your lost this game of MIH Minesweeper!!!",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 20,
color: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
),
),
const SizedBox(height: 10),
Text(
"Please feel free to start a New Game or check out the Leader Board to find out who's the best in Mzansi.",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 18,
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: () {
context.pop();
showStartGameWindow(mihMineSweeperProvider);
},
buttonColor: MihColors.getGreenColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
width: 300,
child: Text(
"New Game",
style: TextStyle(
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
),
MihButton(
onPressed: () {
context.pop();
mihMineSweeperProvider.setToolIndex(1);
},
buttonColor: MihColors.getOrangeColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
width: 300,
child: Text(
"Leader Board",
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"),
);
},
);
});
return;
}
// 2. Open square and handle expansion (RECURSION)
if (board[r][c].bombsAround == 0) {
// Start recursive expansion
_expandZeros(mihMineSweeperProvider, r, c);
} else {
// Just open the single square
board[r][c].isOpened = true;
squaresLeft--;
}
// 3. Check for win
_checkWinCondition(profileProvider, mihMineSweeperProvider);
// Update the UI
setState(() {});
}
void handleLongPress(int r, int c) {
if (isGameOver || board[r][c].isOpened) {
return;
}
setState(() {
// Toggle the flag status
board[r][c].isFlagged = !board[r][c].isFlagged;
});
}
// --- GAME ACTION LOGIC ---
Future<void> _checkWinCondition(
MzansiProfileProvider profileProvider,
MihMineSweeperProvider mihMineSweeperProvider,
) async {
// Game is won if all non-mine squares are opened.
if (squaresLeft <= mihMineSweeperProvider.totalMines) {
stopTimer();
isGameWon = true;
isGameOver = true;
// win alert
showDialog(
context: context,
builder: (context) {
return MihPackageAlert(
alertIcon: Icon(
Icons.celebration,
color: MihColors.getGreenColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
size: 100,
),
alertTitle: "Congratulations",
alertBody: Column(
children: [
Text(
"Your won this game of MIH Minesweeper!!!",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 20,
color: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
),
),
const SizedBox(height: 10),
// Text(
// "You took ${_formatTime()} to complete the game on ${mihMineSweeperProvider.difficulty} mode.",
// style: TextStyle(
// fontSize: 15,
// color: MihColors.getSecondaryColor(
// MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
// ),
// ),
// const SizedBox(height: 10),
Text(
"Time Taken: ${_formatTime().replaceAll("00:", "")}",
style: TextStyle(
fontSize: 20,
color: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
),
),
const SizedBox(height: 10),
Text(
"Score: ${calculateGameScore(mihMineSweeperProvider)}",
style: TextStyle(
fontSize: 20,
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: () {
context.pop();
showStartGameWindow(mihMineSweeperProvider);
},
buttonColor: MihColors.getGreenColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
width: 300,
child: Text(
"New Game",
style: TextStyle(
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
),
MihButton(
onPressed: () {
context.pop();
mihMineSweeperProvider.setToolIndex(1);
},
buttonColor: MihColors.getOrangeColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
width: 300,
child: Text(
"Leader Board",
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"),
);
},
);
showDialog(
context: context,
builder: (context) {
return Mihloadingcircle(
message: "Uploading your score",
);
});
await MihMinesweeperServices().addPlayerScore(
profileProvider,
mihMineSweeperProvider,
_formatTime().replaceAll("00:", ""),
calculateGameScore(mihMineSweeperProvider),
);
context.pop();
}
}
Color? getDifficultyColor(MihMineSweeperProvider mihMineSweeperProvider) {
String mode = mihMineSweeperProvider.difficulty;
switch (mode) {
case "Very Easy":
return MihColors.getGreenColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark",
);
case "Easy":
return MihColors.getGreenColor(
MzansiInnovationHub.of(context)!.theme.mode != "Dark",
);
case "Intermediate":
return MihColors.getOrangeColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark",
);
case "Hard":
return MihColors.getRedColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark",
);
default:
return null;
}
}
@override
void dispose() {
_timer?.cancel();
super.dispose();
}
@override
void initState() {
// UBongani was here during the MIH Live
super.initState();
}
@override
Widget build(BuildContext context) {
return MihPackageToolBody(
borderOn: false,
bodyItem: getBody(),
);
}
Widget getBody() {
return Consumer2<MzansiProfileProvider, MihMineSweeperProvider>(
builder: (BuildContext context, MzansiProfileProvider profileProvider,
MihMineSweeperProvider mihMineSweeperProvider, Widget? child) {
return Column(
children: [
Expanded(
child: Stack(
alignment: Alignment.topCenter,
children: [
MihSingleChildScroll(
child: board.isEmpty && squaresLeft < 0
// Start Up Message before setting up game
? Padding(
padding:
const EdgeInsets.symmetric(horizontal: 10.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
const SizedBox(height: 50),
Icon(
MihIcons.mineSweeper,
size: 165,
color: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!
.theme
.mode ==
"Dark"),
),
const SizedBox(height: 10),
Text(
"Welcom to Minesweeper, the first game of MIH.",
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),
Center(
child: RichText(
textAlign: TextAlign.center,
text: TextSpan(
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.normal,
color: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!
.theme
.mode ==
"Dark"),
),
children: [
TextSpan(text: "Press "),
WidgetSpan(
alignment:
PlaceholderAlignment.middle,
child: Icon(
Icons.menu,
size: 20,
color: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!
.theme
.mode ==
"Dark"),
),
),
TextSpan(
text:
" to start a new game or learn how to play the minesweeper."),
],
),
),
),
],
),
)
// Display Game Board when game started
: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
// Display game status
Row(
mainAxisAlignment:
MainAxisAlignment.spaceEvenly,
children: [
Expanded(
child: Padding(
padding: const EdgeInsets.symmetric(
horizontal: 10.0),
child: Text(
'Mines: ${mihMineSweeperProvider.totalMines}',
textAlign: TextAlign.left,
style: const TextStyle(
fontSize: 24,
fontWeight: FontWeight.bold),
),
),
),
Expanded(
child: Padding(
padding: const EdgeInsets.symmetric(
horizontal: 10.0),
child: Text(
_formatTime().replaceAll("00:", ""),
textAlign: TextAlign.right,
style: const TextStyle(
fontSize: 24,
fontWeight: FontWeight.bold),
),
),
),
],
),
Text(
mihMineSweeperProvider.difficulty,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 24,
fontWeight: FontWeight.bold,
color: getDifficultyColor(
mihMineSweeperProvider),
),
),
// const SizedBox(
// height: 30,
// ),
// The Board Grid
SizedBox(
width: mihMineSweeperProvider.columnCount *
40.0, // Control size based on columns
height: mihMineSweeperProvider.rowCount *
40.0, // Control size based on rows
child: GridView.builder(
physics:
const NeverScrollableScrollPhysics(), // Prevent scrolling
gridDelegate:
SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount:
mihMineSweeperProvider.columnCount,
crossAxisSpacing: 0,
mainAxisSpacing: 0,
),
itemCount: mihMineSweeperProvider.rowCount *
mihMineSweeperProvider.columnCount,
itemBuilder: (context, index) {
int r = index ~/
mihMineSweeperProvider
.columnCount; // Integer division for row
int c = index %
mihMineSweeperProvider
.columnCount; // Remainder for column
return MineTile(
square: board[r][c],
onTap: () => handleTap(profileProvider,
mihMineSweeperProvider, r, c),
onLongPress: () => handleLongPress(r, c),
);
},
),
),
SizedBox(height: 30),
// const SizedBox(height: 100),
],
),
),
Positioned(
right: 10,
bottom: 10,
child: MihFloatingMenu(
animatedIcon: AnimatedIcons.menu_close,
children: [
SpeedDialChild(
child: Icon(
Icons.rule_rounded,
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
),
label: "Learn how to play",
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: () {
mihMineSweeperProvider.setToolIndex(3);
},
),
SpeedDialChild(
child: Icon(
Icons.add,
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
),
label: "Start New Game",
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: () {
showStartGameWindow(mihMineSweeperProvider);
},
),
]),
)
],
),
),
_timer != null ? MihBannerAd() : SizedBox(),
SizedBox(height: 15),
],
);
},
);
}
}

View File

@@ -0,0 +1,880 @@
import 'package:flutter/material.dart';
import 'package:mzansi_innovation_hub/main.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_single_child_scroll.dart';
import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart';
class MineSweeperQuickStartGuide extends StatefulWidget {
const MineSweeperQuickStartGuide({super.key});
@override
State<MineSweeperQuickStartGuide> createState() =>
_MineSweeperQuickStartGuideState();
}
class _MineSweeperQuickStartGuideState
extends State<MineSweeperQuickStartGuide> {
double titleSize = 22.0;
double subtitleSize = 20.0;
double pointsSize = 18.0;
Widget sectionOne() {
return Container(
decoration: BoxDecoration(
color: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode != "Darl"),
borderRadius: BorderRadius.circular(15),
),
child: Padding(
padding: const EdgeInsets.all(15.0),
child: Column(
children: [
// Title
Text(
"1. Two Main Actions\n(Your Controls)",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: titleSize,
fontWeight: FontWeight.bold,
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
),
),
const SizedBox(height: 8),
//Part One
RichText(
text: TextSpan(
children: <TextSpan>[
TextSpan(
text: 'Quick Tap (or Click): This is the Dig action.',
style: TextStyle(
color: MihColors.getGreenColor(
MzansiInnovationHub.of(context)!.theme.mode !=
"Dark"),
fontWeight: FontWeight.bold,
fontSize: subtitleSize,
),
),
],
),
),
const SizedBox(height: 8),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 10.0),
child: Align(
alignment: Alignment.topLeft,
child: RichText(
text: TextSpan(
children: <TextSpan>[
TextSpan(
text: '• Goal:',
style: TextStyle(
color: MihColors.getGreenColor(
MzansiInnovationHub.of(context)!.theme.mode !=
"Dark"),
fontWeight: FontWeight.bold,
fontSize: pointsSize,
),
),
TextSpan(
text: ' To uncover a square and see a number clue.',
style: TextStyle(
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
fontWeight: FontWeight.normal,
fontSize: pointsSize,
),
),
],
),
),
),
),
const SizedBox(height: 8),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 10.0),
child: Align(
alignment: Alignment.centerLeft,
child: RichText(
text: TextSpan(
children: <TextSpan>[
TextSpan(
text: '• Risk:',
style: TextStyle(
color: MihColors.getRedColor(
MzansiInnovationHub.of(context)!.theme.mode !=
"Dark"),
fontWeight: FontWeight.bold,
fontSize: pointsSize,
),
),
TextSpan(
text: ' If you click a mine, the game ends!',
style: TextStyle(
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
fontWeight: FontWeight.normal,
fontSize: pointsSize,
),
),
],
),
),
),
),
const SizedBox(height: 8),
//Part Two
RichText(
text: TextSpan(
children: <TextSpan>[
TextSpan(
text:
'Tap and Hold (or Long Press): This is the Flag action (🚩).',
style: TextStyle(
color: MihColors.getRedColor(
MzansiInnovationHub.of(context)!.theme.mode !=
"Dark"),
fontWeight: FontWeight.bold,
fontSize: subtitleSize,
),
),
],
),
),
const SizedBox(height: 8),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 10.0),
child: Align(
alignment: Alignment.topLeft,
child: RichText(
text: TextSpan(
children: <TextSpan>[
TextSpan(
text: '• Goal:',
style: TextStyle(
color: MihColors.getGreenColor(
MzansiInnovationHub.of(context)!.theme.mode !=
"Dark"),
fontWeight: FontWeight.bold,
fontSize: pointsSize,
),
),
TextSpan(
text: ' To safely mark a square that you are',
style: TextStyle(
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
fontWeight: FontWeight.normal,
fontSize: pointsSize,
),
),
TextSpan(
text: ' certain',
style: TextStyle(
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
fontWeight: FontWeight.bold,
fontSize: pointsSize,
),
),
TextSpan(
text: ' is a mine.',
style: TextStyle(
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
fontWeight: FontWeight.normal,
fontSize: pointsSize,
),
),
],
),
),
),
),
const SizedBox(height: 8),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 10.0),
child: Align(
alignment: Alignment.centerLeft,
child: RichText(
text: TextSpan(
children: <TextSpan>[
TextSpan(
text: '• Risk:',
style: TextStyle(
color: MihColors.getRedColor(
MzansiInnovationHub.of(context)!.theme.mode !=
"Dark"),
fontWeight: FontWeight.bold,
fontSize: pointsSize,
),
),
TextSpan(
text:
' Accidental placement of flags will cause confusion.',
style: TextStyle(
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
fontWeight: FontWeight.normal,
fontSize: pointsSize,
),
),
],
),
),
),
),
const SizedBox(height: 8),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 10.0),
child: Align(
alignment: Alignment.centerLeft,
child: RichText(
text: TextSpan(
children: <TextSpan>[
TextSpan(
text: '• Benefit:',
style: TextStyle(
color: MihColors.getGreenColor(
MzansiInnovationHub.of(context)!.theme.mode !=
"Dark"),
fontWeight: FontWeight.bold,
fontSize: pointsSize,
),
),
TextSpan(
text:
' You cannot accidentally click a square that is flagged.',
style: TextStyle(
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
fontWeight: FontWeight.normal,
fontSize: pointsSize,
),
),
],
),
),
),
),
],
),
),
);
}
Widget sectionTwo() {
return Container(
decoration: BoxDecoration(
color: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode != "Darl"),
borderRadius: BorderRadius.circular(15),
),
child: Padding(
padding: const EdgeInsets.all(15.0),
child: Column(
children: [
// Title
Text(
"2. The Golden Rule\n(Reading the Numbers)",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: titleSize,
fontWeight: FontWeight.bold,
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
),
),
const SizedBox(height: 8),
//Part One
RichText(
text: TextSpan(
children: <TextSpan>[
TextSpan(
text:
'The number tells you exactly how many mines are touching that square (including sides and corners).',
style: TextStyle(
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
fontWeight: FontWeight.normal,
fontSize: subtitleSize,
),
),
],
),
),
const SizedBox(height: 8),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 10.0),
child: Align(
alignment: Alignment.topLeft,
child: RichText(
text: TextSpan(
children: <TextSpan>[
TextSpan(
text: "• If you see a Blank Space (a '0'):",
style: TextStyle(
color: MihColors.getOrangeColor(
MzansiInnovationHub.of(context)!.theme.mode !=
"Dark"),
fontWeight: FontWeight.bold,
fontSize: pointsSize,
),
),
TextSpan(
text: " Zero (0) ",
style: TextStyle(
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
fontWeight: FontWeight.bold,
fontSize: pointsSize,
),
),
TextSpan(
text:
' mines are touching it. All surrounding squares are safe, and the game will open them for you automatically.',
style: TextStyle(
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
fontWeight: FontWeight.normal,
fontSize: pointsSize,
),
),
],
),
),
),
),
const SizedBox(height: 8),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 10.0),
child: Align(
alignment: Alignment.centerLeft,
child: RichText(
text: TextSpan(
children: <TextSpan>[
TextSpan(
text: "• If you see a '1':",
style: TextStyle(
color: MihColors.getOrangeColor(
MzansiInnovationHub.of(context)!.theme.mode !=
"Dark"),
fontWeight: FontWeight.bold,
fontSize: pointsSize,
),
),
TextSpan(
text: ' Only ',
style: TextStyle(
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
fontWeight: FontWeight.normal,
fontSize: pointsSize,
),
),
TextSpan(
text: 'one',
style: TextStyle(
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
fontWeight: FontWeight.bold,
fontSize: pointsSize,
),
),
TextSpan(
text:
' mine is touching this square. You must find and flag that single mine.',
style: TextStyle(
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
fontWeight: FontWeight.normal,
fontSize: pointsSize,
),
),
],
),
),
),
),
const SizedBox(height: 8),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 10.0),
child: Align(
alignment: Alignment.topLeft,
child: RichText(
text: TextSpan(
children: <TextSpan>[
TextSpan(
text: "• If you see a '3':",
style: TextStyle(
color: MihColors.getOrangeColor(
MzansiInnovationHub.of(context)!.theme.mode !=
"Dark"),
fontWeight: FontWeight.bold,
fontSize: pointsSize,
),
),
TextSpan(
text: " Three ",
style: TextStyle(
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
fontWeight: FontWeight.bold,
fontSize: pointsSize,
),
),
TextSpan(
text:
'mines are touching this square. You must find and flag all three.',
style: TextStyle(
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
fontWeight: FontWeight.normal,
fontSize: pointsSize,
),
),
],
),
),
),
),
],
),
),
);
}
Widget sectionThree() {
return Container(
decoration: BoxDecoration(
color: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode != "Darl"),
borderRadius: BorderRadius.circular(15),
),
child: Padding(
padding: const EdgeInsets.all(15.0),
child: Column(
children: [
// Title
Text(
"3. The Winning Strategy\n(The Deduction Loop)",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: titleSize,
fontWeight: FontWeight.bold,
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
),
),
const SizedBox(height: 8),
//Part One
RichText(
text: TextSpan(
children: <TextSpan>[
TextSpan(
text:
'The game is won by uncovering every single safe square and correctly flagging all the mines. Use this two-step loop to clear the board:',
style: TextStyle(
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
fontWeight: FontWeight.normal,
fontSize: subtitleSize,
),
),
],
),
),
const SizedBox(height: 8),
RichText(
text: TextSpan(
children: <TextSpan>[
TextSpan(
text: 'A. Find the Mines (Where to Flag 🚩)',
style: TextStyle(
color: MihColors.getPurpleColor(
MzansiInnovationHub.of(context)!.theme.mode !=
"Dark"),
fontWeight: FontWeight.bold,
fontSize: subtitleSize,
),
),
],
),
),
const SizedBox(height: 8),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 10.0),
child: Align(
alignment: Alignment.topLeft,
child: RichText(
text: TextSpan(
children: <TextSpan>[
TextSpan(
text: '• Goal:',
style: TextStyle(
color: MihColors.getGreenColor(
MzansiInnovationHub.of(context)!.theme.mode !=
"Dark"),
fontWeight: FontWeight.bold,
fontSize: pointsSize,
),
),
TextSpan(
text:
' Look for a number that only has one choice for a mine. e.g. If a \'1\' is touching only one hidden square, that hidden square',
style: TextStyle(
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
fontWeight: FontWeight.normal,
fontSize: pointsSize,
),
),
TextSpan(
text: ' must ',
style: TextStyle(
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
fontWeight: FontWeight.bold,
fontSize: pointsSize,
),
),
TextSpan(
text: 'be the mine.',
style: TextStyle(
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
fontWeight: FontWeight.normal,
fontSize: pointsSize,
),
),
],
),
),
),
),
const SizedBox(height: 8),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 10.0),
child: Align(
alignment: Alignment.centerLeft,
child: RichText(
text: TextSpan(
children: <TextSpan>[
TextSpan(
text: '• Action:',
style: TextStyle(
color: MihColors.getRedColor(
MzansiInnovationHub.of(context)!.theme.mode !=
"Dark"),
fontWeight: FontWeight.bold,
fontSize: pointsSize,
),
),
TextSpan(
text: ' Tap and Hold to place a',
style: TextStyle(
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
fontWeight: FontWeight.normal,
fontSize: pointsSize,
),
),
TextSpan(
text: ' Flag ',
style: TextStyle(
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
fontWeight: FontWeight.bold,
fontSize: pointsSize,
),
),
TextSpan(
text: 'on the square you are sure is a mine.',
style: TextStyle(
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
fontWeight: FontWeight.normal,
fontSize: pointsSize,
),
),
],
),
),
),
),
const SizedBox(height: 8),
//Part Two
RichText(
text: TextSpan(
children: <TextSpan>[
TextSpan(
text: 'B. Find the Safe Squares (Where to Dig)',
style: TextStyle(
color: MihColors.getPurpleColor(
MzansiInnovationHub.of(context)!.theme.mode !=
"Dark"),
fontWeight: FontWeight.bold,
fontSize: subtitleSize,
),
),
],
),
),
const SizedBox(height: 8),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 10.0),
child: Align(
alignment: Alignment.topLeft,
child: RichText(
text: TextSpan(
children: <TextSpan>[
TextSpan(
text: '• Goal:',
style: TextStyle(
color: MihColors.getGreenColor(
MzansiInnovationHub.of(context)!.theme.mode !=
"Dark"),
fontWeight: FontWeight.bold,
fontSize: pointsSize,
),
),
TextSpan(
text:
' Look for a number that has been \'satisfied\' by your flags. e.g. You see a \'2\' and you have already placed two 🚩 flags touching it. The \'2\' is satisfied.',
style: TextStyle(
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
fontWeight: FontWeight.normal,
fontSize: pointsSize,
),
),
],
),
),
),
),
const SizedBox(height: 8),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 10.0),
child: Align(
alignment: Alignment.centerLeft,
child: RichText(
text: TextSpan(
children: <TextSpan>[
TextSpan(
text: '• Action:',
style: TextStyle(
color: MihColors.getRedColor(
MzansiInnovationHub.of(context)!.theme.mode !=
"Dark"),
fontWeight: FontWeight.bold,
fontSize: pointsSize,
),
),
TextSpan(
text:
' Quick Tap any of the remaining hidden squares touching that \'satisfied\' number. They',
style: TextStyle(
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
fontWeight: FontWeight.normal,
fontSize: pointsSize,
),
),
TextSpan(
text: ' must be safe ',
style: TextStyle(
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
fontWeight: FontWeight.bold,
fontSize: pointsSize,
),
),
TextSpan(
text:
'because the mine requirement has already been met.',
style: TextStyle(
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
fontWeight: FontWeight.normal,
fontSize: pointsSize,
),
),
],
),
),
),
),
],
),
),
);
}
Widget sectionFour() {
return Container(
decoration: BoxDecoration(
color: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode != "Darl"),
borderRadius: BorderRadius.circular(15),
),
child: Padding(
padding: const EdgeInsets.all(15.0),
child: Column(
children: [
// Title
Text(
"✨ Key Beginner Tips",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: titleSize,
fontWeight: FontWeight.bold,
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
),
),
const SizedBox(height: 8),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 10.0),
child: Align(
alignment: Alignment.topLeft,
child: RichText(
text: TextSpan(
children: <TextSpan>[
TextSpan(
text: "• Start on the Edges and Corners: ",
style: TextStyle(
color: MihColors.getBronze(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
fontWeight: FontWeight.bold,
fontSize: pointsSize,
),
),
TextSpan(
text:
'Numbers on the edge or corner of the board are easier to solve because they have fewer surrounding squares to check.',
style: TextStyle(
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
fontWeight: FontWeight.normal,
fontSize: pointsSize,
),
),
],
),
),
),
),
const SizedBox(height: 8),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 10.0),
child: Align(
alignment: Alignment.topLeft,
child: RichText(
text: TextSpan(
children: <TextSpan>[
TextSpan(
text: "• Don't Guess: ",
style: TextStyle(
color: MihColors.getBronze(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
fontWeight: FontWeight.bold,
fontSize: pointsSize,
),
),
TextSpan(
text:
'If you are down to two squares and either one could be the mine, look somewhere else on the board for a guaranteed, safe move.',
style: TextStyle(
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
fontWeight: FontWeight.normal,
fontSize: pointsSize,
),
),
],
),
),
),
),
],
),
),
);
}
@override
Widget build(BuildContext context) {
final Size size = MediaQuery.sizeOf(context);
final double width = size.width;
return MihPackageToolBody(
borderOn: false,
bodyItem: getBody(width),
);
}
Widget getBody(double width) {
return MihSingleChildScroll(
child: Padding(
padding: EdgeInsets.symmetric(horizontal: width / 20),
child: Column(
children: [
const Text(
'Simple Rules and Strategy',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 30,
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 8),
const Text(
'Minesweeper is a puzzle game where you use numbers to figure out where the hidden bombs (mines) are located.',
style: TextStyle(fontSize: 18),
),
// const Divider(height: 30),
const SizedBox(height: 15),
sectionOne(),
const SizedBox(height: 15),
sectionTwo(),
const SizedBox(height: 15),
sectionThree(),
const SizedBox(height: 15),
sectionFour(),
const SizedBox(height: 15),
],
),
),
);
}
}

View File

@@ -0,0 +1,209 @@
import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.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_circle_avatar.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_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_pop_up_messages/mih_loading_circle.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_providers/mih_mine_sweeper_provider.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_providers/mzansi_profile_provider.dart';
import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart';
import 'package:mzansi_innovation_hub/mih_packages/mine_sweeper/builders/build_my_scoreboard_list.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_minesweeper_services.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_validation_services.dart';
import 'package:provider/provider.dart';
class MyScoreBoard extends StatefulWidget {
const MyScoreBoard({super.key});
@override
State<MyScoreBoard> createState() => _MihMineSweeperLeaderBoardState();
}
class _MihMineSweeperLeaderBoardState extends State<MyScoreBoard> {
TextEditingController filterController = TextEditingController();
Future<void> initialiseLeaderboard() async {
MzansiProfileProvider profileProvider =
context.read<MzansiProfileProvider>();
MihMineSweeperProvider mineSweeperProvider =
context.read<MihMineSweeperProvider>();
filterController.text = mineSweeperProvider.difficulty;
KenLogger.success("getting data");
await MihMinesweeperServices()
.getMyScoreboard(profileProvider, mineSweeperProvider);
KenLogger.success("${mineSweeperProvider.myScoreboard}");
}
void refreshLeaderBoard(
MihMineSweeperProvider mineSweeperProvider, String difficulty) {
mineSweeperProvider.setDifficulty(difficulty);
mineSweeperProvider.setLeaderboard(leaderboard: null);
mineSweeperProvider.setMyScoreboard(myScoreboard: null);
initialiseLeaderboard();
}
@override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) async {
await initialiseLeaderboard();
});
}
@override
Widget build(BuildContext context) {
final double width = MediaQuery.sizeOf(context).width;
return Consumer<MihMineSweeperProvider>(
builder: (BuildContext context,
MihMineSweeperProvider mineSweeperProvider, Widget? child) {
return RefreshIndicator(
onRefresh: () async {
refreshLeaderBoard(mineSweeperProvider, filterController.text);
},
child: MihPackageToolBody(
borderOn: false,
bodyItem: getBody(width),
),
);
},
);
}
Widget getBody(double width) {
return Consumer2<MzansiProfileProvider, MihMineSweeperProvider>(
builder: (BuildContext context, MzansiProfileProvider profileProvider,
MihMineSweeperProvider mineSweeperProvider, Widget? child) {
if (mineSweeperProvider.myScoreboard == null) {
return Center(
child: Mihloadingcircle(),
);
} else {
return SingleChildScrollView(
physics: const AlwaysScrollableScrollPhysics(),
child: Column(
children: [
Center(
child: MihCircleAvatar(
imageFile: profileProvider.userProfilePicture,
width: 150,
editable: false,
fileNameController: null,
userSelectedfile: null,
frameColor: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
backgroundColor: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
onChange: (selectedImage) {},
key: ValueKey(profileProvider.userProfilePicUrl),
),
),
Padding(
padding: EdgeInsets.symmetric(horizontal: width / 20),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.end,
mainAxisSize: MainAxisSize.max,
children: [
Flexible(
child: MihDropdownField(
controller: filterController,
hintText: "Scoreboards",
dropdownOptions: const [
"Very Easy",
"Easy",
"Intermediate",
"Hard",
],
requiredText: true,
editable: true,
enableSearch: false,
validator: (value) {
return MihValidationServices().isEmpty(value);
},
onSelected: (selection) {
refreshLeaderBoard(mineSweeperProvider, selection!);
},
),
),
],
),
),
const SizedBox(height: 10),
mineSweeperProvider.myScoreboard!.isEmpty
? Padding(
padding: const EdgeInsets.symmetric(horizontal: 10.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
const SizedBox(height: 50),
Icon(
MihIcons.mineSweeper,
size: 165,
color: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
),
const SizedBox(height: 10),
Text(
"You have played and ${mineSweeperProvider.difficulty} yet.",
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),
Center(
child: RichText(
textAlign: TextAlign.center,
text: TextSpan(
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.normal,
color: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!
.theme
.mode ==
"Dark"),
),
children: [
TextSpan(text: "Press "),
WidgetSpan(
alignment: PlaceholderAlignment.middle,
child: Icon(
FontAwesomeIcons.bomb,
size: 20,
color: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!
.theme
.mode ==
"Dark"),
),
),
TextSpan(text: " and start a new game"),
],
),
),
),
],
),
)
: BuildMyScoreBoardList(),
],
),
);
}
},
);
}
}

View File

@@ -2,19 +2,14 @@ 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.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_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_package_tools.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_objects/arguments.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_providers/mzansi_ai_provider.dart';
import 'package:mzansi_innovation_hub/mih_packages/mzansi_ai/package_tools/ai_chat.dart'; import 'package:mzansi_innovation_hub/mih_packages/mzansi_ai/package_tools/ai_chat.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class MzansiAi extends StatefulWidget { class MzansiAi extends StatefulWidget {
// final AppUser signedInUser;
// final String? startUpQuestion;
final MzansiAiArguments arguments;
const MzansiAi({ const MzansiAi({
super.key, super.key,
required this.arguments,
// required this.signedInUser,
// this.startUpQuestion,
}); });
@override @override
@@ -22,16 +17,14 @@ class MzansiAi extends StatefulWidget {
} }
class _MzansiAiState extends State<MzansiAi> { class _MzansiAiState extends State<MzansiAi> {
int _selcetedIndex = 0;
MihPackageAction getAction() { MihPackageAction getAction() {
return MihPackageAction( return MihPackageAction(
icon: const Icon(Icons.arrow_back), icon: const Icon(Icons.arrow_back),
iconSize: 35, iconSize: 35,
onTap: () { onTap: () {
context.read<MzansiAiProvider>().setStartUpQuestion(null);
context.goNamed( context.goNamed(
'mihHome', 'mihHome',
extra: widget.arguments.personalSelected,
); );
FocusScope.of(context).unfocus(); FocusScope.of(context).unfocus();
}, },
@@ -41,23 +34,18 @@ class _MzansiAiState extends State<MzansiAi> {
MihPackageTools getTools() { MihPackageTools getTools() {
Map<Widget, void Function()?> temp = {}; Map<Widget, void Function()?> temp = {};
temp[const Icon(Icons.chat)] = () { temp[const Icon(Icons.chat)] = () {
setState(() { context.read<MzansiAiProvider>().setToolIndex(0);
_selcetedIndex = 0;
});
}; };
return MihPackageTools( return MihPackageTools(
tools: temp, tools: temp,
selcetedIndex: _selcetedIndex, selcetedIndex: context.watch<MzansiAiProvider>().toolIndex,
); );
} }
List<Widget> getToolBody() { List<Widget> getToolBody() {
List<Widget> toolBodies = [ List<Widget> toolBodies = [
AiChat( AiChat(),
signedInUser: widget.arguments.signedInUser,
startUpQuestion: widget.arguments.startUpQuestion,
),
]; ];
return toolBodies; return toolBodies;
} }
@@ -81,12 +69,9 @@ class _MzansiAiState extends State<MzansiAi> {
appTools: getTools(), appTools: getTools(),
appBody: getToolBody(), appBody: getToolBody(),
appToolTitles: getToolTitle(), appToolTitles: getToolTitle(),
selectedbodyIndex: _selcetedIndex, selectedbodyIndex: context.watch<MzansiAiProvider>().toolIndex,
onIndexChange: (newValue) { onIndexChange: (newValue) {
setState(() { context.read<MzansiAiProvider>().setToolIndex(newValue);
_selcetedIndex = newValue;
});
print("Index: $_selcetedIndex");
}, },
); );
} }

View File

@@ -3,16 +3,13 @@ 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_package_tile.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_icons.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_objects/arguments.dart';
import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart'; import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart';
class MzansiAiTile extends StatefulWidget { class MzansiAiTile extends StatefulWidget {
final MzansiAiArguments arguments;
final double packageSize; final double packageSize;
const MzansiAiTile({ const MzansiAiTile({
super.key, super.key,
required this.arguments,
required this.packageSize, required this.packageSize,
}); });
@@ -27,7 +24,6 @@ class _MzansiAiTileState extends State<MzansiAiTile> {
onTap: () { onTap: () {
context.goNamed( context.goNamed(
'mzansiAi', 'mzansiAi',
extra: widget.arguments,
); );
// Navigator.of(context).pushNamed( // Navigator.of(context).pushNamed(
// '/mzansi-ai', // '/mzansi-ai',

View File

@@ -4,6 +4,8 @@ import 'package:flutter_speed_dial/flutter_speed_dial.dart';
import 'package:gpt_markdown/gpt_markdown.dart'; import 'package:gpt_markdown/gpt_markdown.dart';
import 'package:mzansi_innovation_hub/main.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_icons.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_providers/mzansi_ai_provider.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_providers/mzansi_profile_provider.dart';
import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart'; import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_validation_services.dart'; import 'package:mzansi_innovation_hub/mih_services/mih_validation_services.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_dropdwn_field.dart';
@@ -14,22 +16,18 @@ import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_radio_options.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_radio_options.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_loading_circle.dart';
import 'package:mzansi_innovation_hub/mih_config/mih_env.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:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_chat_ui/flutter_chat_ui.dart'; import 'package:flutter_chat_ui/flutter_chat_ui.dart';
import 'package:flutter_chat_types/flutter_chat_types.dart' as types; import 'package:flutter_chat_types/flutter_chat_types.dart' as types;
import 'package:flutter/services.dart' show rootBundle; import 'package:flutter/services.dart' show rootBundle;
import 'package:flutter_tts/flutter_tts.dart'; import 'package:flutter_tts/flutter_tts.dart';
import 'package:ollama_dart/ollama_dart.dart' as ollama; import 'package:ollama_dart/ollama_dart.dart' as ollama;
import 'package:provider/provider.dart';
import 'package:uuid/uuid.dart'; import 'package:uuid/uuid.dart';
class AiChat extends StatefulWidget { class AiChat extends StatefulWidget {
final AppUser signedInUser;
final String? startUpQuestion;
const AiChat({ const AiChat({
super.key, super.key,
required this.signedInUser,
this.startUpQuestion,
}); });
@override @override
@@ -95,6 +93,8 @@ class _AiChatState extends State<AiChat> {
temp += temp +=
"- Calculator: Simple calculator with tip and forex calculation functionality.\n"; "- Calculator: Simple calculator with tip and forex calculation functionality.\n";
temp += "- MIH Access: Manage and view profile access security.\n"; temp += "- MIH Access: Manage and view profile access security.\n";
temp +=
"- MIH Minesweeper: The first game from MIH! It's the classic brain-teaser ready to entertain you no matter where you are.\n";
temp += "**Core Rules and Guidelines:**\n"; temp += "**Core Rules and Guidelines:**\n";
temp += temp +=
"- **Accuracy First:** Always prioritize providing correct information.\n"; "- **Accuracy First:** Always prioritize providing correct information.\n";
@@ -615,9 +615,13 @@ class _AiChatState extends State<AiChat> {
@override @override
void initState() { void initState() {
super.initState(); super.initState();
MzansiAiProvider mzansiAiProvider = context.read<MzansiAiProvider>();
MzansiProfileProvider mzansiProfileProvider =
context.read<MzansiProfileProvider>();
_user = types.User( _user = types.User(
firstName: widget.signedInUser.fname, firstName: mzansiProfileProvider.user!.fname,
id: widget.signedInUser.app_id, //'82091008-a484-4a89-ae75-a22bf8d6f3ac', id: mzansiProfileProvider
.user!.app_id, //'82091008-a484-4a89-ae75-a22bf8d6f3ac',
); );
_mihAI = types.User( _mihAI = types.User(
firstName: "Mzansi AI", firstName: "Mzansi AI",
@@ -634,8 +638,10 @@ class _AiChatState extends State<AiChat> {
); );
initTTS(); initTTS();
_ttsVoiceController.addListener(voiceSelected); _ttsVoiceController.addListener(voiceSelected);
if (widget.startUpQuestion != null && widget.startUpQuestion!.isNotEmpty) { if (mzansiAiProvider.startUpQuestion != null &&
final partialText = types.PartialText(text: widget.startUpQuestion!); mzansiAiProvider.startUpQuestion!.isNotEmpty) {
final partialText =
types.PartialText(text: mzansiAiProvider.startUpQuestion!);
WidgetsBinding.instance.addPostFrameCallback((_) { WidgetsBinding.instance.addPostFrameCallback((_) {
_handleSendPressed(partialText); _handleSendPressed(partialText);
}); });

View File

@@ -1,20 +1,17 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart'; import 'package:go_router/go_router.dart';
import 'package:mzansi_innovation_hub/main.dart'; import 'package:mzansi_innovation_hub/main.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_objects/arguments.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_objects/business.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_objects/business.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_business_profile_preview.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_business_profile_preview.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_providers/mzansi_directory_provider.dart';
import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart'; import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart';
import 'package:provider/provider.dart';
class BuildBusinessSearchResultsList extends StatefulWidget { class BuildBusinessSearchResultsList extends StatefulWidget {
final List<Business> businessList; final List<Business> businessList;
final String myLocation;
final String? startUpSearch;
const BuildBusinessSearchResultsList({ const BuildBusinessSearchResultsList({
super.key, super.key,
required this.businessList, required this.businessList,
required this.myLocation,
required this.startUpSearch,
}); });
@override @override
@@ -26,6 +23,9 @@ class _BuildBusinessSearchResultsListState
extends State<BuildBusinessSearchResultsList> { extends State<BuildBusinessSearchResultsList> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Consumer<MzansiDirectoryProvider>(
builder: (BuildContext context, MzansiDirectoryProvider directoryProvider,
Widget? child) {
return ListView.separated( return ListView.separated(
shrinkWrap: true, shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(), physics: const NeverScrollableScrollPhysics(),
@@ -42,20 +42,12 @@ class _BuildBusinessSearchResultsListState
MzansiInnovationHub.of(context)!.theme.mode == "Dark"), MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
child: InkWell( child: InkWell(
onTap: () { onTap: () {
context.goNamed( directoryProvider.setSelectedBusiness(
'businessProfileView', business: widget.businessList[index],
extra: BusinessViewArguments( );
widget.businessList[index], context.pushNamed(
widget.businessList[index].Name, 'businessProfileView',
),
); );
// // Navigator.of(context).pushNamed(
// // '/business-profile/view',
// // arguments: BusinessViewArguments(
// // widget.businessList[index],
// // widget.businessList[index].Name,
// // ),
// );
}, },
splashColor: MihColors.getSecondaryColor( splashColor: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark") MzansiInnovationHub.of(context)!.theme.mode == "Dark")
@@ -68,12 +60,13 @@ class _BuildBusinessSearchResultsListState
), ),
child: MihBusinessProfilePreview( child: MihBusinessProfilePreview(
business: widget.businessList[index], business: widget.businessList[index],
myLocation: widget.myLocation,
), ),
), ),
), ),
); );
}, },
); );
},
);
} }
} }

View File

@@ -1,18 +1,17 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart'; import 'package:go_router/go_router.dart';
import 'package:mzansi_innovation_hub/main.dart'; import 'package:mzansi_innovation_hub/main.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_objects/arguments.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_objects/business.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_objects/business.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_business_profile_preview.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_business_profile_preview.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_providers/mzansi_directory_provider.dart';
import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart'; import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart';
import 'package:provider/provider.dart';
class BuildFavouriteBusinessesList extends StatefulWidget { class BuildFavouriteBusinessesList extends StatefulWidget {
final List<Business?> favouriteBusinesses; final List<Business?> favouriteBusinesses;
final String? myLocation;
const BuildFavouriteBusinessesList({ const BuildFavouriteBusinessesList({
super.key, super.key,
required this.favouriteBusinesses, required this.favouriteBusinesses,
required this.myLocation,
}); });
@override @override
@@ -24,6 +23,9 @@ class _BuildFavouriteBusinessesListState
extends State<BuildFavouriteBusinessesList> { extends State<BuildFavouriteBusinessesList> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Consumer<MzansiDirectoryProvider>(
builder: (BuildContext context, MzansiDirectoryProvider directoryProvider,
Widget? child) {
return ListView.separated( return ListView.separated(
shrinkWrap: true, shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(), physics: const NeverScrollableScrollPhysics(),
@@ -34,31 +36,20 @@ class _BuildFavouriteBusinessesListState
); );
}, },
itemBuilder: (context, index) { itemBuilder: (context, index) {
final Business? business = widget.favouriteBusinesses[index]; if (widget.favouriteBusinesses[index] == null) {
if (business == null) {
return const SizedBox(); // Or a placeholder if a business couldn't be loaded return const SizedBox(); // Or a placeholder if a business couldn't be loaded
} }
return Material( return Material(
color: MihColors.getPrimaryColor( color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"), MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
child: InkWell( child: InkWell(
onTap: () { onTap: () {
context.goNamed( directoryProvider.setSelectedBusiness(
'businessProfileView', business: widget.favouriteBusinesses[index]!,
extra: BusinessViewArguments( );
widget.favouriteBusinesses[index]!, context.pushNamed(
widget.favouriteBusinesses[index]!.Name, 'businessProfileView',
),
); );
// Navigator.of(context).pushNamed(
// '/business-profile/view',
// arguments: BusinessViewArguments(
// business,
// business.Name,
// ),
// );
}, },
splashColor: MihColors.getSecondaryColor( splashColor: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark") MzansiInnovationHub.of(context)!.theme.mode == "Dark")
@@ -69,11 +60,14 @@ class _BuildFavouriteBusinessesListState
horizontal: 25, horizontal: 25,
), ),
child: MihBusinessProfilePreview( child: MihBusinessProfilePreview(
business: business, myLocation: widget.myLocation), business: widget.favouriteBusinesses[index]!,
),
), ),
), ),
); );
}, },
); );
},
);
} }
} }

View File

@@ -3,7 +3,9 @@ import 'package:go_router/go_router.dart';
import 'package:mzansi_innovation_hub/main.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/app_user.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_personal_profile_preview.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_personal_profile_preview.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_providers/mzansi_directory_provider.dart';
import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart'; import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart';
import 'package:provider/provider.dart';
class BuildUserSearchResultsList extends StatefulWidget { class BuildUserSearchResultsList extends StatefulWidget {
final List<AppUser> userList; final List<AppUser> userList;
@@ -21,6 +23,9 @@ class _BuildUserSearchResultsListState
extends State<BuildUserSearchResultsList> { extends State<BuildUserSearchResultsList> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Consumer<MzansiDirectoryProvider>(
builder: (BuildContext context, MzansiDirectoryProvider directoryProvider,
Widget? child) {
return ListView.separated( return ListView.separated(
shrinkWrap: true, shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(), physics: const NeverScrollableScrollPhysics(),
@@ -37,14 +42,11 @@ class _BuildUserSearchResultsListState
MzansiInnovationHub.of(context)!.theme.mode == "Dark"), MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
child: InkWell( child: InkWell(
onTap: () { onTap: () {
context.goNamed( directoryProvider.setSelectedUser(
user: widget.userList[index]);
context.pushNamed(
'mzansiProfileView', 'mzansiProfileView',
extra: widget.userList[index],
); );
// Navigator.of(context).pushNamed(
// '/mzansi-profile/view',
// arguments: widget.userList[index],
// );
}, },
splashColor: MihColors.getSecondaryColor( splashColor: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark") MzansiInnovationHub.of(context)!.theme.mode == "Dark")
@@ -55,13 +57,14 @@ class _BuildUserSearchResultsListState
// vertical: 5, // vertical: 5,
horizontal: 25, horizontal: 25,
), ),
child: MihPersonalProfilePreview( child:
user: widget.userList[index], MihPersonalProfilePreview(user: widget.userList[index]),
),
), ),
), ),
); );
}, },
); );
},
);
} }
} }

View File

@@ -1,19 +1,23 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:geolocator/geolocator.dart'; import 'package:geolocator/geolocator.dart';
import 'package:go_router/go_router.dart'; import 'package:go_router/go_router.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_objects/arguments.dart'; import 'package:ken_logger/ken_logger.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.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_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_package_tools.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_providers/mzansi_directory_provider.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_providers/mzansi_profile_provider.dart';
import 'package:mzansi_innovation_hub/mih_packages/mzansi_directory/package_tools/mih_favourite_businesses.dart'; import 'package:mzansi_innovation_hub/mih_packages/mzansi_directory/package_tools/mih_favourite_businesses.dart';
import 'package:mzansi_innovation_hub/mih_packages/mzansi_directory/package_tools/mih_search_mzansi.dart'; import 'package:mzansi_innovation_hub/mih_packages/mzansi_directory/package_tools/mih_search_mzansi.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_business_details_services.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_location_services.dart'; import 'package:mzansi_innovation_hub/mih_services/mih_location_services.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_mzansi_directory_services.dart';
import 'package:provider/provider.dart';
class MzansiDirectory extends StatefulWidget { class MzansiDirectory extends StatefulWidget {
final MzansiDirectoryArguments arguments;
const MzansiDirectory({ const MzansiDirectory({
super.key, super.key,
required this.arguments,
}); });
@override @override
@@ -21,75 +25,78 @@ class MzansiDirectory extends StatefulWidget {
} }
class _MzansiDirectoryState extends State<MzansiDirectory> { class _MzansiDirectoryState extends State<MzansiDirectory> {
int _selcetedIndex = 0;
late Future<Position?> futurePosition = late Future<Position?> futurePosition =
MIHLocationAPI().getGPSPosition(context); MIHLocationAPI().getGPSPosition(context);
Future<void> initialiseGPSLocation() async {
MzansiDirectoryProvider directoryProvider =
context.read<MzansiDirectoryProvider>();
MIHLocationAPI().getGPSPosition(context).then((position) {
directoryProvider.setUserPosition(position);
});
}
Future<void> getFavouriteBusinesses() async {
MzansiDirectoryProvider directoryProvider =
context.read<MzansiDirectoryProvider>();
MzansiProfileProvider profileProvider =
context.read<MzansiProfileProvider>();
await MihMzansiDirectoryServices().getAllUserBookmarkedBusiness(
profileProvider.user!.app_id,
directoryProvider,
);
List<Business> favBus = [];
for (var bus in directoryProvider.bookmarkedBusinesses) {
await MihBusinessDetailsServices()
.getBusinessDetailsByBusinessId(bus.business_id)
.then((business) {
favBus.add(business!);
});
}
KenLogger.success(favBus);
directoryProvider.setFavouriteBusinesses(businesses: favBus);
}
@override @override
void initState() { void initState() {
super.initState(); super.initState();
if (widget.arguments.packageIndex == null) { WidgetsBinding.instance.addPostFrameCallback((_) async {
_selcetedIndex = 0; initialiseGPSLocation();
} else { getFavouriteBusinesses();
_selcetedIndex = widget.arguments.packageIndex!; });
}
} }
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
print('MzansiDirectory build method called!');
return MihPackage( return MihPackage(
appActionButton: getAction(), appActionButton: getAction(),
appTools: getTools(), appTools: getTools(),
appBody: getToolBody(), appBody: getToolBody(),
appToolTitles: getToolTitle(), appToolTitles: getToolTitle(),
selectedbodyIndex: _selcetedIndex, selectedbodyIndex: context.watch<MzansiDirectoryProvider>().toolIndex,
onIndexChange: (newValue) { onIndexChange: (newValue) {
setState(() { context.read<MzansiDirectoryProvider>().setToolIndex(newValue);
_selcetedIndex = newValue;
});
}, },
); );
} }
List<Widget> getToolBody() { List<Widget> getToolBody() {
List<Widget> toolBodies = [ List<Widget> toolBodies = [];
FutureBuilder( // String myLocation = "Getting Your GPS Location Ready";
future: futurePosition, // if (directoryProvider.userPosition != null) {
builder: (context, asyncSnapshot) { // myLocation = directoryProvider.userPosition
String myLocation = ""; // .toString()
if (asyncSnapshot.connectionState == ConnectionState.waiting) { // .replaceAll("Latitude: ", "")
myLocation = "Getting Your GPS Location Ready"; // .replaceAll("Longitude: ", "");
} else { // }
myLocation = asyncSnapshot.data toolBodies.addAll([
.toString() MihSearchMzansi(
.replaceAll("Latitude: ", "") // personalSearch: directoryProvider.personalSearch,
.replaceAll("Longitude: ", ""); // startSearchText: "",
} ),
return MihSearchMzansi(
personalSearch: widget.arguments.personalSearch,
myLocation: myLocation,
startSearchText: widget.arguments.startSearchText,
);
}),
// MihContacts(), // MihContacts(),
FutureBuilder( MihFavouriteBusinesses(),
future: futurePosition, ]);
builder: (context, asyncSnapshot) {
String myLocation = "";
if (asyncSnapshot.connectionState == ConnectionState.waiting) {
myLocation = "Getting Your GPS Location Ready";
} else {
myLocation = asyncSnapshot.data
.toString()
.replaceAll("Latitude: ", "")
.replaceAll("Longitude: ", "");
}
return MihFavouriteBusinesses(
myLocation: myLocation,
);
}),
];
return toolBodies; return toolBodies;
} }
@@ -98,10 +105,13 @@ class _MzansiDirectoryState extends State<MzansiDirectory> {
icon: const Icon(Icons.arrow_back), icon: const Icon(Icons.arrow_back),
iconSize: 35, iconSize: 35,
onTap: () { onTap: () {
MzansiDirectoryProvider directoryProvider =
context.read<MzansiDirectoryProvider>();
context.goNamed( context.goNamed(
'mihHome', 'mihHome',
extra: widget.arguments.personalSearch,
); );
directoryProvider.setToolIndex(0);
directoryProvider.setPersonalSearch(true);
FocusScope.of(context).unfocus(); FocusScope.of(context).unfocus();
}, },
); );
@@ -110,23 +120,14 @@ class _MzansiDirectoryState extends State<MzansiDirectory> {
MihPackageTools getTools() { MihPackageTools getTools() {
Map<Widget, void Function()?> temp = {}; Map<Widget, void Function()?> temp = {};
temp[const Icon(Icons.search)] = () { temp[const Icon(Icons.search)] = () {
setState(() { context.read<MzansiDirectoryProvider>().setToolIndex(0);
_selcetedIndex = 0;
});
}; };
// temp[const Icon(Icons.person)] = () {
// setState(() {
// _selcetedIndex = 1;
// });
// };
temp[const Icon(Icons.business_center)] = () { temp[const Icon(Icons.business_center)] = () {
setState(() { context.read<MzansiDirectoryProvider>().setToolIndex(1);
_selcetedIndex = 1;
});
}; };
return MihPackageTools( return MihPackageTools(
tools: temp, tools: temp,
selcetedIndex: _selcetedIndex, selcetedIndex: context.watch<MzansiDirectoryProvider>().toolIndex,
); );
} }
@@ -134,7 +135,7 @@ class _MzansiDirectoryState extends State<MzansiDirectory> {
List<String> toolTitles = [ List<String> toolTitles = [
"Mzansi Search", "Mzansi Search",
"Favourite Businesses", "Favourite Businesses",
"Contacts", // "Contacts",
]; ];
return toolTitles; return toolTitles;
} }

View File

@@ -1,18 +1,15 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart'; import 'package:go_router/go_router.dart';
import 'package:mzansi_innovation_hub/main.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'; 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_tile.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'; import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart';
class MzansiDirectoryTile extends StatefulWidget { class MzansiDirectoryTile extends StatefulWidget {
final double packageSize; final double packageSize;
final bool personalSelected;
const MzansiDirectoryTile({ const MzansiDirectoryTile({
super.key, super.key,
required this.packageSize, required this.packageSize,
required this.personalSelected,
}); });
@override @override
@@ -26,10 +23,6 @@ class _MzansiDirectoryTileState extends State<MzansiDirectoryTile> {
onTap: () { onTap: () {
context.goNamed( context.goNamed(
"mzansiDirectory", "mzansiDirectory",
extra: MzansiDirectoryArguments(
personalSearch: widget.personalSelected,
startSearchText: null,
),
); );
// Navigator.of(context).pushNamed( // Navigator.of(context).pushNamed(
// '/mzansi-directory', // '/mzansi-directory',

View File

@@ -1,24 +1,21 @@
import 'dart:async'; import 'dart:async';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:ken_logger/ken_logger.dart';
import 'package:mzansi_innovation_hub/main.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.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_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_tool_body.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_search_bar.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_search_bar.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_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_components/mih_pop_up_messages/mih_loading_circle.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_providers/mzansi_directory_provider.dart';
import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart'; import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart';
import 'package:mzansi_innovation_hub/mih_packages/mzansi_directory/builders/build_favourite_businesses_list.dart'; import 'package:mzansi_innovation_hub/mih_packages/mzansi_directory/builders/build_favourite_businesses_list.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_business_details_services.dart'; import 'package:provider/provider.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_mzansi_directory_services.dart';
import 'package:supertokens_flutter/supertokens.dart';
class MihFavouriteBusinesses extends StatefulWidget { class MihFavouriteBusinesses extends StatefulWidget {
final String? myLocation;
const MihFavouriteBusinesses({ const MihFavouriteBusinesses({
super.key, super.key,
required this.myLocation,
}); });
@override @override
@@ -29,42 +26,17 @@ class _MihFavouriteBusinessesState extends State<MihFavouriteBusinesses> {
final TextEditingController businessSearchController = final TextEditingController businessSearchController =
TextEditingController(); TextEditingController();
final FocusNode searchFocusNode = FocusNode(); final FocusNode searchFocusNode = FocusNode();
late Future<List<BookmarkedBusiness>> boookmarkedBusinessListFuture;
List<BookmarkedBusiness> listBookmarkedBusinesses = [];
final ValueNotifier<List<Business?>> searchBookmarkedBusinesses = final ValueNotifier<List<Business?>> searchBookmarkedBusinesses =
ValueNotifier([]); ValueNotifier([]);
late Future<Map<String, Business?>> businessDetailsMapFuture;
Map<String, Business?> _businessDetailsMap = {};
Timer? _debounce; Timer? _debounce;
Future<Map<String, Business?>> void _filterAndSetBusinesses(MzansiDirectoryProvider directoryProvider) {
getAndMapAllBusinessDetailsForBookmarkedBusinesses() async {
String user_id = await SuperTokens.getUserId();
List<BookmarkedBusiness> bookmarked = await MihMzansiDirectoryServices()
.getAllUserBookmarkedBusiness(user_id);
listBookmarkedBusinesses = bookmarked;
Map<String, Business?> businessMap = {};
List<Future<Business?>> detailFutures = [];
for (var item in bookmarked) {
detailFutures.add(MihBusinessDetailsServices()
.getBusinessDetailsByBusinessId(item.business_id));
}
List<Business?> details = await Future.wait(detailFutures);
for (int i = 0; i < bookmarked.length; i++) {
businessMap[bookmarked[i].business_id] = details[i];
}
_businessDetailsMap = businessMap;
_filterAndSetBusinesses();
return businessMap;
}
void _filterAndSetBusinesses() {
List<Business?> businessesToDisplay = []; List<Business?> businessesToDisplay = [];
String query = businessSearchController.text.toLowerCase(); String query = businessSearchController.text.toLowerCase();
for (var bookmarked in listBookmarkedBusinesses) { if (directoryProvider.favouriteBusinessesList != null) {
if (bookmarked.business_name.toLowerCase().contains(query)) { for (var bus in directoryProvider.favouriteBusinessesList!) {
if (_businessDetailsMap.containsKey(bookmarked.business_id)) { if (bus.Name.toLowerCase().contains(query)) {
businessesToDisplay.add(_businessDetailsMap[bookmarked.business_id]); businessesToDisplay.add(bus);
} }
} }
} }
@@ -82,14 +54,19 @@ class _MihFavouriteBusinessesState extends State<MihFavouriteBusinesses> {
@override @override
void initState() { void initState() {
super.initState(); super.initState();
businessDetailsMapFuture = MzansiDirectoryProvider directoryProvider =
getAndMapAllBusinessDetailsForBookmarkedBusinesses(); context.read<MzansiDirectoryProvider>();
// getAndMapAllBusinessDetailsForBookmarkedBusinesses(
// mzansiProfileProvider,
// directoryProvider,
// );
_filterAndSetBusinesses(directoryProvider);
businessSearchController.addListener(() { businessSearchController.addListener(() {
if (_debounce?.isActive ?? false) { if (_debounce?.isActive ?? false) {
_debounce!.cancel(); _debounce!.cancel();
} }
_debounce = Timer(const Duration(milliseconds: 200), () { _debounce = Timer(const Duration(milliseconds: 200), () {
_filterAndSetBusinesses(); _filterAndSetBusinesses(directoryProvider);
}); });
}); });
} }
@@ -105,6 +82,14 @@ class _MihFavouriteBusinessesState extends State<MihFavouriteBusinesses> {
} }
Widget getBody(double width) { Widget getBody(double width) {
return Consumer<MzansiDirectoryProvider>(
builder: (BuildContext context, MzansiDirectoryProvider directoryProvider,
Widget? child) {
if (directoryProvider.favouriteBusinessesList == null) {
return Center(
child: Mihloadingcircle(),
);
}
return MihSingleChildScroll( return MihSingleChildScroll(
child: Column( child: Column(
children: [ children: [
@@ -123,23 +108,10 @@ class _MihFavouriteBusinessesState extends State<MihFavouriteBusinesses> {
), ),
), ),
const SizedBox(height: 10), const SizedBox(height: 10),
FutureBuilder<Map<String, Business?>>( ValueListenableBuilder<List<Business?>>(
future: businessDetailsMapFuture, valueListenable: searchBookmarkedBusinesses,
builder: (context, snapshot) { builder: (context, filteredBusinesses, child) {
if (snapshot.connectionState == ConnectionState.waiting) { if (filteredBusinesses.isEmpty &&
return Mihloadingcircle(
message: "Getting your favourites",
);
} else if (snapshot.connectionState == ConnectionState.done) {
if (snapshot.hasData && snapshot.data!.isNotEmpty) {
// No need to re-filter here, _filterAndSetBusinesses is called in initState
// and by the text controller listener.
return ValueListenableBuilder<List<Business?>>(
valueListenable:
searchBookmarkedBusinesses, // Listen to changes in this
builder: (context, businesses, child) {
// Display message if no results after search
if (businesses.isEmpty &&
businessSearchController.text.isNotEmpty) { businessSearchController.text.isNotEmpty) {
return Column( return Column(
children: [ children: [
@@ -148,9 +120,7 @@ class _MihFavouriteBusinessesState extends State<MihFavouriteBusinesses> {
MihIcons.iDontKnow, MihIcons.iDontKnow,
size: 165, size: 165,
color: MihColors.getSecondaryColor( color: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)! MzansiInnovationHub.of(context)!.theme.mode ==
.theme
.mode ==
"Dark"), "Dark"),
), ),
const SizedBox(height: 10), const SizedBox(height: 10),
@@ -162,25 +132,14 @@ class _MihFavouriteBusinessesState extends State<MihFavouriteBusinesses> {
fontSize: 25, fontSize: 25,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
color: MihColors.getSecondaryColor( color: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)! MzansiInnovationHub.of(context)!.theme.mode ==
.theme
.mode ==
"Dark"), "Dark"),
), ),
), ),
], ],
); );
} } else if (filteredBusinesses.isEmpty &&
return BuildFavouriteBusinessesList( businessSearchController.text.isEmpty) {
favouriteBusinesses:
businesses, // Pass the filtered list from ValueNotifier
myLocation: widget.myLocation,
);
},
);
} else {
// This block handles the case where there are no bookmarked businesses initially
return Padding( return Padding(
padding: const EdgeInsets.symmetric(horizontal: 10.0), padding: const EdgeInsets.symmetric(horizontal: 10.0),
child: Column( child: Column(
@@ -204,7 +163,9 @@ class _MihFavouriteBusinessesState extends State<MihFavouriteBusinesses> {
fontSize: 25, fontSize: 25,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
color: MihColors.getSecondaryColor( color: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == MzansiInnovationHub.of(context)!
.theme
.mode ==
"Dark"), "Dark"),
), ),
), ),
@@ -224,18 +185,6 @@ class _MihFavouriteBusinessesState extends State<MihFavouriteBusinesses> {
), ),
children: [ children: [
TextSpan(text: "Use the mzansi search"), TextSpan(text: "Use the mzansi search"),
// WidgetSpan(
// alignment:
// PlaceholderAlignment.middle,
// child: Icon(
// Icons.search,
// size: 20,
// color:
// MzansiInnovationHub.of(context)!
// .theme
// .secondaryColor(),
// ),
// ),
TextSpan( TextSpan(
text: text:
" to find your favourite businesses of mzansi"), " to find your favourite businesses of mzansi"),
@@ -247,20 +196,15 @@ class _MihFavouriteBusinessesState extends State<MihFavouriteBusinesses> {
), ),
); );
} }
} else if (snapshot.hasError) { KenLogger.success(filteredBusinesses);
return Center( return BuildFavouriteBusinessesList(
child: Text( favouriteBusinesses: filteredBusinesses,
"Error loading bookmarked businesses: ${snapshot.error}"), // Show specific error
); );
} else {
// Fallback for unexpected states
return Center(
child: Text("An unknown error occurred."),
);
}
}), }),
], ],
), ),
); );
},
);
} }
} }

View File

@@ -1,4 +1,5 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:ken_logger/ken_logger.dart';
import 'package:mzansi_innovation_hub/main.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/app_user.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_objects/business.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_objects/business.dart';
@@ -9,22 +10,19 @@ import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_search_bar.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_search_bar.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_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_components/mih_pop_up_messages/mih_loading_circle.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_providers/mzansi_directory_provider.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_providers/mzansi_profile_provider.dart';
import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart'; import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart';
import 'package:mzansi_innovation_hub/mih_packages/mzansi_directory/builders/build_business_search_resultsList.dart'; import 'package:mzansi_innovation_hub/mih_packages/mzansi_directory/builders/build_business_search_resultsList.dart';
import 'package:mzansi_innovation_hub/mih_packages/mzansi_directory/builders/build_user_search_results_list.dart'; import 'package:mzansi_innovation_hub/mih_packages/mzansi_directory/builders/build_user_search_results_list.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_alert_services.dart'; import 'package:mzansi_innovation_hub/mih_services/mih_alert_services.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_business_details_services.dart'; import 'package:mzansi_innovation_hub/mih_services/mih_business_details_services.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_user_services.dart'; import 'package:mzansi_innovation_hub/mih_services/mih_user_services.dart';
import 'package:provider/provider.dart';
class MihSearchMzansi extends StatefulWidget { class MihSearchMzansi extends StatefulWidget {
final bool personalSearch;
final String? myLocation;
final String? startSearchText;
const MihSearchMzansi({ const MihSearchMzansi({
super.key, super.key,
required this.personalSearch,
required this.myLocation,
required this.startSearchText,
}); });
@override @override
@@ -35,80 +33,89 @@ class _MihSearchMzansiState extends State<MihSearchMzansi> {
final TextEditingController mzansiSearchController = TextEditingController(); final TextEditingController mzansiSearchController = TextEditingController();
final TextEditingController businessTypeController = TextEditingController(); final TextEditingController businessTypeController = TextEditingController();
final FocusNode searchFocusNode = FocusNode(); final FocusNode searchFocusNode = FocusNode();
late bool userSearch; // late bool userSearch;
Future<List<AppUser>?> futureUserSearchResults = Future.value(); // Future<List<AppUser>?> futureUserSearchResults = Future.value();
Future<List<Business>?> futureBusinessSearchResults = Future.value();
List<AppUser> userSearchResults = []; List<AppUser> userSearchResults = [];
List<Business> businessSearchResults = []; List<Business> businessSearchResults = [];
late Future<List<String>> availableBusinessTypes; late Future<List<String>> availableBusinessTypes;
bool filterOn = false; bool filterOn = false;
bool loadingSearchResults = false;
void swapPressed() { Future<void> swapPressed(MzansiProfileProvider profileProvider,
MzansiDirectoryProvider directoryProvider) async {
directoryProvider.setPersonalSearch(!directoryProvider.personalSearch);
setState(() { setState(() {
userSearch = !userSearch;
if (filterOn) { if (filterOn) {
filterOn = !filterOn; filterOn = !filterOn;
} }
}); });
if (businessTypeController.text.isNotEmpty) { if (businessTypeController.text.isNotEmpty) {
setState(() { setState(() {
futureBusinessSearchResults = Future.value();
businessTypeController.clear(); businessTypeController.clear();
}); });
} }
searchPressed(); await searchPressed(profileProvider, directoryProvider);
} }
void clearAll() { void clearAll(MzansiDirectoryProvider directoryProvider) {
directoryProvider.setSearchedBusinesses(searchedBusinesses: []);
directoryProvider.setSearchedUsers(searchedUsers: []);
directoryProvider.setSearchTerm(searchTerm: "");
setState(() { setState(() {
futureUserSearchResults = Future.value();
futureBusinessSearchResults = Future.value();
mzansiSearchController.clear(); mzansiSearchController.clear();
businessTypeController.clear(); businessTypeController.clear();
}); });
} }
void searchPressed() { Future<void> searchPressed(MzansiProfileProvider profileProvider,
MzansiDirectoryProvider directoryProvider) async {
setState(() { setState(() {
// userSearch = !userSearch; loadingSearchResults = true;
if (userSearch && mzansiSearchController.text.isNotEmpty) { });
futureUserSearchResults = directoryProvider.setSearchTerm(searchTerm: mzansiSearchController.text);
MihUserServices().searchUsers(mzansiSearchController.text, context); directoryProvider.setBusinessTypeFilter(
businessTypeFilter: businessTypeController.text);
if (directoryProvider.personalSearch &&
directoryProvider.searchTerm.isNotEmpty) {
final userResults = await MihUserServices()
.searchUsers(profileProvider, directoryProvider.searchTerm, context);
directoryProvider.setSearchedUsers(searchedUsers: userResults);
} else { } else {
if ( List<Business>? businessSearchResults = [];
// mzansiSearchController.text.isNotEmpty && if (directoryProvider.businessTypeFilter.isNotEmpty) {
businessTypeController.text.isNotEmpty) { businessSearchResults = await MihBusinessDetailsServices()
futureBusinessSearchResults = MihBusinessDetailsServices() .searchBusinesses(directoryProvider.searchTerm,
.searchBusinesses(mzansiSearchController.text, directoryProvider.businessTypeFilter, context);
businessTypeController.text, context); } else if (directoryProvider.searchTerm.isNotEmpty) {
} else if (mzansiSearchController.text.isNotEmpty) { businessSearchResults = await MihBusinessDetailsServices()
futureBusinessSearchResults = MihBusinessDetailsServices() .searchBusinesses(directoryProvider.searchTerm,
.searchBusinesses(mzansiSearchController.text, directoryProvider.businessTypeFilter, context);
businessTypeController.text, context);
} }
directoryProvider.setSearchedBusinesses(
searchedBusinesses: businessSearchResults);
} }
setState(() {
loadingSearchResults = false;
}); });
} }
@override @override
void dispose() { void dispose() {
super.dispose(); super.dispose();
businessTypeController.dispose();
mzansiSearchController.dispose(); mzansiSearchController.dispose();
} }
@override @override
void initState() { void initState() {
super.initState(); super.initState();
setState(() { MzansiDirectoryProvider directoryProvider =
userSearch = widget.personalSearch; context.read<MzansiDirectoryProvider>();
availableBusinessTypes = availableBusinessTypes =
MihBusinessDetailsServices().fetchAllBusinessTypes(); MihBusinessDetailsServices().fetchAllBusinessTypes();
if (widget.startSearchText != null) {
mzansiSearchController.text = widget.startSearchText!;
searchPressed();
} else {
mzansiSearchController.text = ""; mzansiSearchController.text = "";
} WidgetsBinding.instance.addPostFrameCallback((_) async {
directoryProvider.setSearchedUsers(searchedUsers: []);
}); });
} }
@@ -123,6 +130,9 @@ class _MihSearchMzansiState extends State<MihSearchMzansi> {
} }
Widget getBody(double width) { Widget getBody(double width) {
return Consumer2<MzansiProfileProvider, MzansiDirectoryProvider>(
builder: (BuildContext context, MzansiProfileProvider profileProvider,
MzansiDirectoryProvider directoryProvider, Widget? child) {
return MihSingleChildScroll( return MihSingleChildScroll(
child: Column( child: Column(
children: [ children: [
@@ -136,11 +146,13 @@ class _MihSearchMzansiState extends State<MihSearchMzansi> {
controller: mzansiSearchController, controller: mzansiSearchController,
hintText: "Search Mzansi", hintText: "Search Mzansi",
prefixIcon: Icons.search, prefixIcon: Icons.search,
prefixAltIcon: userSearch ? Icons.person : Icons.business, prefixAltIcon: directoryProvider.personalSearch
? Icons.person
: Icons.business,
suffixTools: [ suffixTools: [
IconButton( IconButton(
onPressed: () { onPressed: () {
swapPressed(); swapPressed(profileProvider, directoryProvider);
}, },
icon: Icon( icon: Icon(
Icons.swap_horiz_rounded, Icons.swap_horiz_rounded,
@@ -152,28 +164,30 @@ class _MihSearchMzansiState extends State<MihSearchMzansi> {
), ),
], ],
fillColor: MihColors.getSecondaryColor( fillColor: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"), MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
hintColor: MihColors.getPrimaryColor( hintColor: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"), MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
onPrefixIconTap: () { onPrefixIconTap: () {
searchPressed(); searchPressed(profileProvider, directoryProvider);
}, },
onClearIconTap: () { onClearIconTap: () {
clearAll(); clearAll(directoryProvider);
}, },
searchFocusNode: searchFocusNode, searchFocusNode: searchFocusNode,
), ),
), ),
Visibility( Visibility(
visible: !userSearch, visible: !directoryProvider.personalSearch,
child: const SizedBox(width: 10), child: const SizedBox(width: 10),
), ),
Visibility( Visibility(
visible: !userSearch, visible: !directoryProvider.personalSearch,
child: IconButton( child: IconButton(
onPressed: () { onPressed: () {
if (filterOn) { if (filterOn) {
clearAll(); clearAll(directoryProvider);
} }
setState(() { setState(() {
filterOn = !filterOn; filterOn = !filterOn;
@@ -223,7 +237,8 @@ class _MihSearchMzansiState extends State<MihSearchMzansi> {
MihButton( MihButton(
onPressed: () { onPressed: () {
if (businessTypeController.text.isNotEmpty) { if (businessTypeController.text.isNotEmpty) {
searchPressed(); searchPressed(
profileProvider, directoryProvider);
} else { } else {
MihAlertServices().errorAlert( MihAlertServices().errorAlert(
"Business Type Not Selected", "Business Type Not Selected",
@@ -240,7 +255,9 @@ class _MihSearchMzansiState extends State<MihSearchMzansi> {
"Search", "Search",
style: TextStyle( style: TextStyle(
color: MihColors.getPrimaryColor( color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode == MzansiInnovationHub.of(context)!
.theme
.mode ==
"Dark"), "Dark"),
fontSize: 20, fontSize: 20,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
@@ -253,171 +270,26 @@ class _MihSearchMzansiState extends State<MihSearchMzansi> {
); );
}), }),
const SizedBox(height: 10), const SizedBox(height: 10),
displaySearchResults(userSearch, widget.myLocation ?? ""), displaySearchResults(directoryProvider),
], ],
), ),
); );
},
);
} }
Widget displaySearchResults(bool userSearch, String myLocation) { Widget displayBusinessSearchResults(
if (userSearch) { MzansiDirectoryProvider directoryProvider) {
return FutureBuilder( KenLogger.success(
future: futureUserSearchResults, "Searched Businesses: ${directoryProvider.searchedBusinesses}");
builder: (context, snapshot) { if (directoryProvider.searchedBusinesses == null || loadingSearchResults) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const Mihloadingcircle();
} else if (snapshot.connectionState == ConnectionState.done &&
snapshot.hasData &&
snapshot.requireData!.isNotEmpty) {
// return Text("Pulled Data successfully");
snapshot.requireData!
.sort((a, b) => a.username.compareTo(b.username));
return Column(
children: [
Text(
"People of Mzansi",
style: TextStyle(fontSize: 25, fontWeight: FontWeight.bold),
),
const SizedBox(height: 10),
BuildUserSearchResultsList(userList: snapshot.requireData!),
],
);
} else if (!snapshot.hasData) {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 10.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
const SizedBox(height: 50),
Icon(
MihIcons.personalProfile,
size: 165,
color: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
),
const SizedBox(height: 10),
Text(
"Search for people of Mzansi!",
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),
Center(
child: RichText(
textAlign: TextAlign.center,
text: TextSpan(
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.normal,
color: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
),
children: [
TextSpan(text: "Press "),
WidgetSpan(
alignment: PlaceholderAlignment.middle,
child: Icon(
Icons.swap_horiz_rounded,
size: 20,
color: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
),
),
TextSpan(text: " to search for businesses of Mzansi"),
],
),
),
),
],
),
);
// return Column(
// mainAxisAlignment: MainAxisAlignment.center,
// crossAxisAlignment: CrossAxisAlignment.center,
// children: [
// const SizedBox(height: 50),
// Icon(
// MihIcons.personalProfile,
// size: 165,
// color:
// MihColors.getSecondaryColor(MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
// ),
// const SizedBox(height: 10),
// Text(
// "People Of Mzansi!",
// textAlign: TextAlign.center,
// overflow: TextOverflow.visible,
// style: TextStyle(
// fontSize: 25,
// fontWeight: FontWeight.bold,
// color:
// MihColors.getSecondaryColor(MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
// ),
// ),
// ],
// );
} else if (snapshot.connectionState == ConnectionState.done &&
snapshot.hasData &&
snapshot.requireData!.isEmpty) {
// return Text("Pulled Data successfully");
return Column(
children: [
const SizedBox(height: 50),
Icon(
MihIcons.iDontKnow,
size: 165,
color: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
),
const SizedBox(height: 10),
Text(
"Let's try refining your search",
textAlign: TextAlign.center,
overflow: TextOverflow.visible,
style: TextStyle(
fontSize: 25,
fontWeight: FontWeight.bold,
color: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
),
),
],
);
} else {
return Center( return Center(
child: Text( child: const Mihloadingcircle(),
"Error pulling Patients Data\n/users/search/${mzansiSearchController.text}",
style: TextStyle(
fontSize: 25,
color: MihColors.getRedColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark")),
textAlign: TextAlign.center,
),
); );
} } else if (directoryProvider.searchedBusinesses!.isNotEmpty) {
},
);
} else {
return FutureBuilder(
future: futureBusinessSearchResults,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const Mihloadingcircle();
} else if (snapshot.connectionState == ConnectionState.done &&
snapshot.hasData &&
snapshot.requireData!.isNotEmpty) {
// return Text("Pulled Data successfully"); // return Text("Pulled Data successfully");
snapshot.requireData!.sort((a, b) => a.Name.compareTo(b.Name)); directoryProvider.searchedBusinesses!
.sort((a, b) => a.Name.compareTo(b.Name));
return Column( return Column(
children: [ children: [
Text( Text(
@@ -426,15 +298,12 @@ class _MihSearchMzansiState extends State<MihSearchMzansi> {
), ),
const SizedBox(height: 10), const SizedBox(height: 10),
BuildBusinessSearchResultsList( BuildBusinessSearchResultsList(
businessList: snapshot.requireData!, businessList: directoryProvider.searchedBusinesses!,
myLocation: myLocation,
startUpSearch: mzansiSearchController.text,
), ),
], ],
); );
} else if (snapshot.connectionState == ConnectionState.done && } else if (directoryProvider.searchedBusinesses!.isEmpty &&
snapshot.hasData && directoryProvider.searchTerm.isNotEmpty) {
snapshot.requireData!.isEmpty) {
// return Text("Pulled Data successfully"); // return Text("Pulled Data successfully");
return Column( return Column(
children: [ children: [
@@ -459,7 +328,8 @@ class _MihSearchMzansiState extends State<MihSearchMzansi> {
), ),
], ],
); );
} else if (!snapshot.hasData) { } else if (directoryProvider.searchedBusinesses!.isEmpty &&
directoryProvider.searchTerm.isEmpty) {
return Padding( return Padding(
padding: const EdgeInsets.symmetric(horizontal: 10.0), padding: const EdgeInsets.symmetric(horizontal: 10.0),
child: Column( child: Column(
@@ -482,8 +352,7 @@ class _MihSearchMzansiState extends State<MihSearchMzansi> {
fontSize: 25, fontSize: 25,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
color: MihColors.getSecondaryColor( color: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
"Dark"),
), ),
), ),
const SizedBox(height: 25), const SizedBox(height: 25),
@@ -495,8 +364,7 @@ class _MihSearchMzansiState extends State<MihSearchMzansi> {
fontSize: 20, fontSize: 20,
fontWeight: FontWeight.normal, fontWeight: FontWeight.normal,
color: MihColors.getSecondaryColor( color: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
"Dark"),
), ),
children: [ children: [
TextSpan(text: "Press "), TextSpan(text: "Press "),
@@ -524,8 +392,7 @@ class _MihSearchMzansiState extends State<MihSearchMzansi> {
fontSize: 20, fontSize: 20,
fontWeight: FontWeight.normal, fontWeight: FontWeight.normal,
color: MihColors.getSecondaryColor( color: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
"Dark"),
), ),
children: [ children: [
TextSpan(text: "Press "), TextSpan(text: "Press "),
@@ -550,7 +417,7 @@ class _MihSearchMzansiState extends State<MihSearchMzansi> {
} else { } else {
return Center( return Center(
child: Text( child: Text(
"Error pulling Patients Data\n/users/search/${mzansiSearchController.text}", "Error pulling Patients Data\n/users/search/${directoryProvider.searchTerm}",
style: TextStyle( style: TextStyle(
fontSize: 25, fontSize: 25,
color: MihColors.getRedColor( color: MihColors.getRedColor(
@@ -559,8 +426,131 @@ class _MihSearchMzansiState extends State<MihSearchMzansi> {
), ),
); );
} }
}, }
Widget displayPersonalSearchResults(
MzansiDirectoryProvider directoryProvider) {
if (directoryProvider.searchedUsers == null || loadingSearchResults) {
return Center(
child: const Mihloadingcircle(),
);
} else if (directoryProvider.searchedUsers!.isNotEmpty) {
// return Text("Pulled Data successfully");
directoryProvider.searchedUsers!
.sort((a, b) => a.username.compareTo(b.username));
return Column(
children: [
Text(
"People of Mzansi",
style: TextStyle(fontSize: 25, fontWeight: FontWeight.bold),
),
const SizedBox(height: 10),
BuildUserSearchResultsList(
userList: directoryProvider.searchedUsers!),
],
);
} else if (directoryProvider.searchedUsers!.isEmpty &&
directoryProvider.searchTerm.isEmpty) {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 10.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
const SizedBox(height: 50),
Icon(
MihIcons.personalProfile,
size: 165,
color: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
),
const SizedBox(height: 10),
Text(
"Search for people of Mzansi!",
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),
Center(
child: RichText(
textAlign: TextAlign.center,
text: TextSpan(
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.normal,
color: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
),
children: [
TextSpan(text: "Press "),
WidgetSpan(
alignment: PlaceholderAlignment.middle,
child: Icon(
Icons.swap_horiz_rounded,
size: 20,
color: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
),
),
TextSpan(text: " to search for businesses of Mzansi"),
],
),
),
),
],
),
);
} else if (directoryProvider.searchedUsers!.isEmpty &&
directoryProvider.searchTerm.isNotEmpty) {
return Column(
children: [
const SizedBox(height: 50),
Icon(
MihIcons.iDontKnow,
size: 165,
color: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
),
const SizedBox(height: 10),
Text(
"Let's try refining your search",
textAlign: TextAlign.center,
overflow: TextOverflow.visible,
style: TextStyle(
fontSize: 25,
fontWeight: FontWeight.bold,
color: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
),
),
],
);
} else {
return Center(
child: Text(
"Error pulling Patients Data\n/users/search/${directoryProvider.searchTerm}",
style: TextStyle(
fontSize: 25,
color: MihColors.getRedColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark")),
textAlign: TextAlign.center,
),
); );
} }
} }
Widget displaySearchResults(MzansiDirectoryProvider directoryProvider) {
if (directoryProvider.personalSearch) {
return displayPersonalSearchResults(directoryProvider);
} else {
return displayBusinessSearchResults(directoryProvider);
}
}
} }

View File

@@ -1,34 +1,15 @@
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/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';
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_button.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_form.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_text_form_field.dart';
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_config/mih_env.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_objects/arguments.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_objects/business_employee.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_objects/business_employee.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_providers/mzansi_profile_provider.dart';
import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart';
import 'package:mzansi_innovation_hub/mih_packages/mzansi_profile/business_profile/components/mih_edit_employee_details_window.dart';
import 'package:mzansi_innovation_hub/mih_config/mih_env.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:supertokens_flutter/http.dart' as http; import 'package:provider/provider.dart';
class BuildEmployeeList extends StatefulWidget { class BuildEmployeeList extends StatefulWidget {
final List<BusinessEmployee> employees;
final BusinessArguments arguments;
const BuildEmployeeList({ const BuildEmployeeList({
super.key, super.key,
required this.employees,
required this.arguments,
}); });
@override @override
@@ -36,339 +17,23 @@ class BuildEmployeeList extends StatefulWidget {
} }
class _BuildEmployeeListState extends State<BuildEmployeeList> { class _BuildEmployeeListState extends State<BuildEmployeeList> {
TextEditingController accessController = TextEditingController();
TextEditingController typeController = TextEditingController();
TextEditingController fnameController = TextEditingController();
TextEditingController lnameController = TextEditingController();
final _formKey = GlobalKey<FormState>();
final baseAPI = AppEnviroment.baseApiUrl; final baseAPI = AppEnviroment.baseApiUrl;
Future<void> updateEmployeeAPICall(int index) async { void updateEmployeePopUp(BusinessEmployee employee) {
showDialog(
context: context,
builder: (context) {
return const Mihloadingcircle();
},
);
var response = await http.put(
Uri.parse("$baseAPI/business-user/employees/update/"),
headers: <String, String>{
"Content-Type": "application/json; charset=UTF-8"
},
body: jsonEncode(<String, dynamic>{
"business_id": widget.employees[index].business_id,
"app_id": widget.employees[index].app_id,
"title": typeController.text,
"access": accessController.text,
}),
);
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,
// ),
// );
String message = "Your employees details have been updated.";
successPopUp(message, false);
} else {
internetConnectionPopUp();
}
}
Future<void> deleteNoteApiCall(int index) async {
var response = await http.delete(
Uri.parse("$baseAPI/business-user/employees/delete/"),
headers: <String, String>{
"Content-Type": "application/json; charset=UTF-8"
},
body: jsonEncode(<String, dynamic>{
"business_id": widget.employees[index].business_id,
"app_id": widget.employees[index].app_id,
}),
);
//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,
// ),
// );
String message =
"The employee has been deleted successfully. This means they will no longer have access to your business profile";
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,
builder: (context) {
return const MIHErrorMessage(errorType: "Internet Connection");
},
);
}
bool isRequiredFieldsCaptured() {
if (accessController.text.isEmpty || typeController.text.isEmpty) {
return false;
} else {
return true;
}
}
void updateEmployeePopUp(int index, double width) {
setState(() {
accessController.text = widget.employees[index].access;
typeController.text = widget.employees[index].title;
fnameController.text = widget.employees[index].fname;
lnameController.text = widget.employees[index].lname;
});
showDialog( showDialog(
context: context, context: context,
barrierDismissible: false, barrierDismissible: false,
builder: (context) => MihPackageWindow( builder: (context) => MihEditEmployeeDetailsWindow(
fullscreen: false, employee: employee,
windowTitle: "Employee Details",
menuOptions: [
SpeedDialChild(
child: Icon(
Icons.delete,
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
),
label: "Delete Employee",
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: () {
showDeleteWarning(index);
},
),
],
onWindowTapClose: () {
Navigator.pop(context);
},
windowBody: Padding(
padding:
MzansiInnovationHub.of(context)!.theme.screenType == "desktop"
? EdgeInsets.symmetric(horizontal: width * 0.05)
: const EdgeInsets.symmetric(horizontal: 0),
child: Column(
children: [
MihForm(
formKey: _formKey,
formFields: [
MihTextFormField(
fillColor: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
inputColor: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
controller: fnameController,
multiLineInput: false,
requiredText: true,
readOnly: true,
hintText: "First Name",
),
const SizedBox(height: 10.0),
MihTextFormField(
fillColor: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
inputColor: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
controller: lnameController,
multiLineInput: false,
requiredText: true,
readOnly: true,
hintText: "Surname",
),
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",
dropdownOptions: const ["Full", "Partial"],
editable: true,
enableSearch: true,
validator: (value) {
return MihValidationServices().isEmpty(value);
},
requiredText: true,
),
const SizedBox(height: 20.0),
Center(
child: MihButton(
onPressed: () {
if (_formKey.currentState!.validate()) {
if (isRequiredFieldsCaptured()) {
updateEmployeeAPICall(index);
} else {
showDialog(
context: context,
builder: (context) {
return const MIHErrorMessage(
errorType: "Input Error");
},
);
}
} else {
MihAlertServices().formNotFilledCompletely(context);
}
},
buttonColor: MihColors.getGreenColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
width: 300,
child: Text(
"Update",
style: TextStyle(
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
),
),
],
),
],
),
),
), ),
); );
} }
void showDeleteWarning(int index) {
showDialog(
context: context,
barrierDismissible: false,
builder: (context) => MIHDeleteMessage(
deleteType: "Employee",
onTap: () {
deleteNoteApiCall(index);
}));
}
@override
void dispose() {
accessController.dispose();
typeController.dispose();
fnameController.dispose();
lnameController.dispose();
super.dispose();
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
double screenWidth = MediaQuery.of(context).size.width; return Consumer<MzansiProfileProvider>(
builder: (BuildContext context,
MzansiProfileProvider mzansiProfileProvider, Widget? child) {
return ListView.separated( return ListView.separated(
shrinkWrap: true, shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(), physics: const NeverScrollableScrollPhysics(),
@@ -378,27 +43,31 @@ class _BuildEmployeeListState extends State<BuildEmployeeList> {
MzansiInnovationHub.of(context)!.theme.mode == "Dark"), MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
); );
}, },
itemCount: widget.employees.length, itemCount: mzansiProfileProvider.employeeList!.length,
itemBuilder: (context, index) { itemBuilder: (context, index) {
//final patient = widget.patients[index].id_no.contains(widget.searchString); //final patient = widget.patients[index].id_no.contains(widget.searchString);
//print(index); //print(index);
var isMe = ""; BusinessEmployee employee =
if (widget.arguments.signedInUser.app_id == mzansiProfileProvider.employeeList![index];
widget.employees[index].app_id) { String isMe = "";
if (mzansiProfileProvider.user!.app_id ==
mzansiProfileProvider.employeeList![index].app_id) {
isMe = "(You)"; isMe = "(You)";
} }
return ListTile( return ListTile(
title: Text( title: Text(
"${widget.employees[index].fname} ${widget.employees[index].lname} - ${widget.employees[index].title} $isMe"), "${mzansiProfileProvider.employeeList![index].fname} ${mzansiProfileProvider.employeeList![index].lname} - ${mzansiProfileProvider.employeeList![index].title} $isMe"),
subtitle: Text( subtitle: Text(
"${widget.employees[index].username}\n${widget.employees[index].email}\nAccess: ${widget.employees[index].access}", "${mzansiProfileProvider.employeeList![index].username}\n${mzansiProfileProvider.employeeList![index].email}\nAccess: ${mzansiProfileProvider.employeeList![index].access}",
style: TextStyle( style: TextStyle(
color: MihColors.getSecondaryColor( color: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"), MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
), ),
), ),
onTap: () { onTap: () {
updateEmployeePopUp(index, screenWidth); updateEmployeePopUp(employee);
},
);
}, },
); );
}, },

View File

@@ -1,32 +1,14 @@
import 'dart:convert';
import 'package:go_router/go_router.dart';
import 'package:mzansi_innovation_hub/main.dart'; import 'package:mzansi_innovation_hub/main.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_alert.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_providers/mzansi_profile_provider.dart';
import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart'; import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_alert_services.dart'; import 'package:mzansi_innovation_hub/mih_packages/mzansi_profile/business_profile/components/mih_add_employee_window.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_dropdwn_field.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_window.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_env.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/material.dart';
import 'package:supertokens_flutter/http.dart' as http; import 'package:provider/provider.dart';
class BuildUserList extends StatefulWidget { class BuildUserList extends StatefulWidget {
final List<AppUser> users;
final BusinessArguments arguments;
const BuildUserList({ const BuildUserList({
super.key, super.key,
required this.users,
required this.arguments,
}); });
@override @override
@@ -34,287 +16,31 @@ class BuildUserList extends StatefulWidget {
} }
class _BuildUserListState extends State<BuildUserList> { class _BuildUserListState extends State<BuildUserList> {
TextEditingController accessController = TextEditingController();
TextEditingController typeController = TextEditingController();
TextEditingController usernameController = TextEditingController();
TextEditingController emailController = TextEditingController();
final _formKey = GlobalKey<FormState>();
final baseAPI = AppEnviroment.baseApiUrl; final baseAPI = AppEnviroment.baseApiUrl;
Future<void> createBusinessUserAPICall(int index) async {
showDialog(
context: context,
builder: (context) {
return const Mihloadingcircle();
},
);
var response = await http.post(
Uri.parse("$baseAPI/business-user/insert/"),
headers: <String, String>{
"Content-Type": "application/json; charset=UTF-8"
},
body: jsonEncode(<String, dynamic>{
"business_id": widget.arguments.business!.business_id,
"app_id": widget.users[index].app_id,
"signature": "",
"sig_path": "",
"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,
// ),
// );
String message =
"${widget.users[index].username} is now apart of your team with ${accessController.text} access to ${widget.arguments.business!.Name}";
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) {
return false;
} else {
return true;
}
}
void internetConnectionPopUp() {
showDialog(
context: context,
builder: (context) {
return const MIHErrorMessage(errorType: "Internet Connection");
},
);
}
String hideEmail(String email) { String hideEmail(String email) {
var firstLetter = email[0]; var firstLetter = email[0];
var end = email.split("@")[1]; var end = email.split("@")[1];
return "$firstLetter********@$end"; return "$firstLetter********@$end";
} }
void addEmployeePopUp(int index, double width) { void addEmployeePopUp(
setState(() { MzansiProfileProvider profileProvider, int index, double width) {
//accessController.text = widget.users[index].access;
//typeController.text = widget.users[index].title;
// var fnameInitial = widget.users[index].fname[0];
// var lnameInitial = widget.users[index].lname[0];
usernameController.text = widget.users[index].username;
emailController.text = hideEmail(widget.users[index].email);
});
showDialog( showDialog(
context: context, context: context,
barrierDismissible: false, barrierDismissible: false,
builder: (context) => MihPackageWindow( builder: (context) => MihAddEmployeeWindow(
fullscreen: false, user: profileProvider.userSearchResults[index],
windowTitle: "Add Employee",
windowBody: Padding(
padding:
MzansiInnovationHub.of(context)!.theme.screenType == "desktop"
? EdgeInsets.symmetric(horizontal: width * 0.05)
: const EdgeInsets.symmetric(horizontal: 0),
child: Column(
children: [
MihForm(
formKey: _formKey,
formFields: [
MihTextFormField(
fillColor: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
inputColor: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
controller: usernameController,
multiLineInput: false,
requiredText: true,
readOnly: true,
hintText: "Username",
), ),
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: emailController,
multiLineInput: false,
requiredText: true,
readOnly: true,
hintText: "Email",
),
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",
dropdownOptions: const ["Full", "Partial"],
editable: true,
enableSearch: true,
validator: (value) {
return MihValidationServices().isEmpty(value);
},
requiredText: true,
),
const SizedBox(height: 15.0),
Center(
child: MihButton(
onPressed: () {
if (_formKey.currentState!.validate()) {
if (isRequiredFieldsCaptured()) {
createBusinessUserAPICall(index);
} else {
showDialog(
context: context,
builder: (context) {
return const MIHErrorMessage(
errorType: "Input Error");
},
); );
} }
} else {
MihAlertServices()
.formNotFilledCompletely(context);
}
},
buttonColor: MihColors.getGreenColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
width: 300,
child: Text(
"Add",
style: TextStyle(
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
),
),
],
),
],
),
),
onWindowTapClose: () {
Navigator.pop(context);
}));
}
@override
void dispose() {
accessController.dispose();
typeController.dispose();
usernameController.dispose();
emailController.dispose();
super.dispose();
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
double screenWidth = MediaQuery.of(context).size.width; double screenWidth = MediaQuery.of(context).size.width;
return Consumer<MzansiProfileProvider>(
builder: (BuildContext context, MzansiProfileProvider profileProvider,
Widget? child) {
return ListView.separated( return ListView.separated(
shrinkWrap: true, shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(), physics: const NeverScrollableScrollPhysics(),
@@ -324,24 +50,27 @@ class _BuildUserListState extends State<BuildUserList> {
MzansiInnovationHub.of(context)!.theme.mode == "Dark"), MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
); );
}, },
itemCount: widget.users.length, itemCount: profileProvider.userSearchResults.length,
itemBuilder: (context, index) { itemBuilder: (context, index) {
var isYou = ""; var isYou = "";
if (widget.arguments.signedInUser.app_id == if (profileProvider.user!.app_id ==
widget.users[index].app_id) { profileProvider.userSearchResults[index].app_id) {
isYou = "(You)"; isYou = "(You)";
} }
return ListTile( return ListTile(
title: Text("@${widget.users[index].username} $isYou"), title: Text(
"@${profileProvider.userSearchResults[index].username} $isYou"),
subtitle: Text( subtitle: Text(
"Email: ${hideEmail(widget.users[index].email)}", "Email: ${hideEmail(profileProvider.userSearchResults[index].email)}",
style: TextStyle( style: TextStyle(
color: MihColors.getSecondaryColor( color: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"), MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
), ),
), ),
onTap: () { onTap: () {
addEmployeePopUp(index, screenWidth); addEmployeePopUp(profileProvider, index, screenWidth);
},
);
}, },
); );
}, },

View File

@@ -0,0 +1,115 @@
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_components/mih_providers/mzansi_profile_provider.dart';
import 'package:mzansi_innovation_hub/mih_packages/mzansi_profile/business_profile/package_tools/mih_business_details.dart';
import 'package:mzansi_innovation_hub/mih_packages/mzansi_profile/business_profile/package_tools/mih_business_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_packages/mzansi_profile/business_profile/package_tools/mih_business_user_search.dart';
import 'package:mzansi_innovation_hub/mih_packages/mzansi_profile/business_profile/package_tools/mih_my_business_team.dart';
import 'package:mzansi_innovation_hub/mih_packages/mzansi_profile/business_profile/package_tools/mih_my_business_user.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_business_employee_services.dart';
import 'package:provider/provider.dart';
class BusinesProfile extends StatefulWidget {
const BusinesProfile({super.key});
@override
State<BusinesProfile> createState() => _BusinesProfileState();
}
class _BusinesProfileState extends State<BusinesProfile> {
Future<void> initialiseBusinessData() async {
MzansiProfileProvider profileProvider =
context.read<MzansiProfileProvider>();
await MihBusinessEmployeeServices()
.fetchEmployees(profileProvider, context);
}
@override
void initState() {
super.initState();
initialiseBusinessData();
}
@override
Widget build(BuildContext context) {
return MihPackage(
appActionButton: getAction(),
appTools: getTools(),
appBody: getToolBody(),
selectedbodyIndex: context.watch<MzansiProfileProvider>().businessIndex,
onIndexChange: (newIndex) {
context.read<MzansiProfileProvider>().setBusinessIndex(newIndex);
},
);
}
MihPackageAction getAction() {
return MihPackageAction(
icon: const Icon(Icons.arrow_back),
iconSize: 35,
onTap: () {
context.goNamed(
'mihHome',
);
FocusScope.of(context).unfocus();
},
);
}
MihPackageTools getTools() {
Map<Widget, void Function()?> temp = {};
temp[const Icon(Icons.business)] = () {
context.read<MzansiProfileProvider>().setBusinessIndex(0);
};
temp[const Icon(Icons.person)] = () {
context.read<MzansiProfileProvider>().setBusinessIndex(1);
};
temp[const Icon(Icons.people)] = () {
context.read<MzansiProfileProvider>().setBusinessIndex(2);
};
temp[const Icon(Icons.add)] = () {
context
.read<MzansiProfileProvider>()
.setUserearchResults(userSearchResults: []);
context.read<MzansiProfileProvider>().setBusinessIndex(3);
};
temp[const Icon(Icons.star_rate_rounded)] = () {
context.read<MzansiProfileProvider>().setBusinessIndex(4);
};
temp[const Icon(Icons.qr_code_rounded)] = () {
context.read<MzansiProfileProvider>().setBusinessIndex(5);
};
return MihPackageTools(
tools: temp,
selcetedIndex: context.watch<MzansiProfileProvider>().businessIndex,
);
}
List<String> getToolTitle() {
List<String> toolTitles = [
"Profile",
"User",
"Team",
"Add",
"Reviews",
"Share",
];
return toolTitles;
}
List<Widget> getToolBody() {
List<Widget> toolBodies = [
MihBusinessDetails(),
MihMyBusinessUser(),
MihMyBusinessTeam(),
MihBusinessUserSearch(),
MihBusinessReviews(business: null),
MihBusinessQrCode(business: null),
];
return toolBodies;
}
}

View File

@@ -1,21 +1,23 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart'; import 'package:go_router/go_router.dart';
import 'package:mzansi_innovation_hub/main.dart'; import 'package:mzansi_innovation_hub/main.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_objects/arguments.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_objects/business.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_objects/business.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_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_alert.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_loading_circle.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_providers/mzansi_profile_provider.dart';
import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart'; import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_alert_services.dart'; import 'package:mzansi_innovation_hub/mih_services/mih_alert_services.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_mzansi_directory_services.dart'; import 'package:mzansi_innovation_hub/mih_services/mih_mzansi_directory_services.dart';
import 'package:supertokens_flutter/supertokens.dart'; import 'package:provider/provider.dart';
class MihAddBookmarkAlert extends StatefulWidget { class MihAddBookmarkAlert extends StatefulWidget {
final Business business; final Business business;
final void Function()? onSuccessDismissPressed;
const MihAddBookmarkAlert({ const MihAddBookmarkAlert({
super.key, super.key,
required this.business, required this.business,
required this.onSuccessDismissPressed,
}); });
@override @override
@@ -23,16 +25,16 @@ class MihAddBookmarkAlert extends StatefulWidget {
} }
class _MihAddBookmarkAlertState extends State<MihAddBookmarkAlert> { class _MihAddBookmarkAlertState extends State<MihAddBookmarkAlert> {
Future<void> addBookmark(String business_id) async { Future<void> addBookmark(
MzansiProfileProvider profileProvider, String business_id) async {
showDialog( showDialog(
context: context, context: context,
builder: (context) { builder: (context) {
return const Mihloadingcircle(); return const Mihloadingcircle();
}, },
); );
String user_id = await SuperTokens.getUserId();
await MihMzansiDirectoryServices() await MihMzansiDirectoryServices()
.addBookmarkedBusiness(user_id, business_id) .addBookmarkedBusiness(profileProvider.user!.app_id, business_id)
.then((statusCode) { .then((statusCode) {
context.pop(); context.pop();
if (statusCode == 201) { if (statusCode == 201) {
@@ -77,14 +79,9 @@ class _MihAddBookmarkAlertState extends State<MihAddBookmarkAlert> {
Center( Center(
child: MihButton( child: MihButton(
onPressed: () { onPressed: () {
context.goNamed( widget.onSuccessDismissPressed!.call();
"mzansiDirectory", context.pop();
extra: MzansiDirectoryArguments( context.pop();
personalSearch: false,
startSearchText: widget.business.Name,
packageIndex: 1,
),
);
}, },
buttonColor: MihColors.getGreenColor( buttonColor: MihColors.getGreenColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"), MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
@@ -117,6 +114,9 @@ class _MihAddBookmarkAlertState extends State<MihAddBookmarkAlert> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Consumer<MzansiProfileProvider>(
builder: (BuildContext context, MzansiProfileProvider profileProvider,
Widget? child) {
return MihPackageAlert( return MihPackageAlert(
alertColour: MihColors.getSecondaryColor( alertColour: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"), MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
@@ -153,7 +153,8 @@ class _MihAddBookmarkAlertState extends State<MihAddBookmarkAlert> {
"Cancel", "Cancel",
style: TextStyle( style: TextStyle(
color: MihColors.getPrimaryColor( color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"), MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
fontSize: 20, fontSize: 20,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
), ),
@@ -162,7 +163,7 @@ class _MihAddBookmarkAlertState extends State<MihAddBookmarkAlert> {
MihButton( MihButton(
width: 300, width: 300,
onPressed: () { onPressed: () {
addBookmark(widget.business.business_id); addBookmark(profileProvider, widget.business.business_id);
}, },
buttonColor: MihColors.getGreenColor( buttonColor: MihColors.getGreenColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"), MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
@@ -170,7 +171,8 @@ class _MihAddBookmarkAlertState extends State<MihAddBookmarkAlert> {
"Bookmark Business", "Bookmark Business",
style: TextStyle( style: TextStyle(
color: MihColors.getPrimaryColor( color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"), MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
fontSize: 20, fontSize: 20,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
), ),
@@ -181,5 +183,7 @@ class _MihAddBookmarkAlertState extends State<MihAddBookmarkAlert> {
], ],
), ),
); );
},
);
} }
} }

View File

@@ -0,0 +1,250 @@
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_button.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_form.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_alert.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_window.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_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_providers/mzansi_profile_provider.dart';
import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_alert_services.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_business_employee_services.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_validation_services.dart';
import 'package:provider/provider.dart';
class MihAddEmployeeWindow extends StatefulWidget {
final AppUser user;
const MihAddEmployeeWindow({
super.key,
required this.user,
});
@override
State<MihAddEmployeeWindow> createState() => _MihAddEmployeeWindowState();
}
class _MihAddEmployeeWindowState extends State<MihAddEmployeeWindow> {
TextEditingController accessController = TextEditingController();
TextEditingController usernameController = TextEditingController();
TextEditingController emailController = TextEditingController();
final _formKey = GlobalKey<FormState>();
Future<void> createBusinessUserAPICall(
MzansiProfileProvider mzansiProfileProvider) async {
int statusCode = await MihBusinessEmployeeServices().addEmployee(
mzansiProfileProvider,
widget.user,
accessController.text,
context,
);
if (statusCode == 201) {
String message =
"${widget.user.username} is now apart of your team with ${accessController.text} access to ${mzansiProfileProvider.business!.Name}";
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.pop();
context.pop();
},
buttonColor: MihColors.getGreenColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
elevation: 10,
width: 300,
child: Text(
"Dismiss",
style: TextStyle(
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
),
)
],
),
alertColour: MihColors.getGreenColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
);
// return MIHSuccessMessage(
// successType: "Success",
// successMessage: message,
// );
},
);
}
void internetConnectionPopUp() {
showDialog(
context: context,
builder: (context) {
return const MIHErrorMessage(errorType: "Internet Connection");
},
);
}
bool isRequiredFieldsCaptured() {
if (accessController.text.isEmpty) {
return false;
} else {
return true;
}
}
@override
void dispose() {
super.dispose();
accessController.dispose();
usernameController.dispose();
emailController.dispose();
}
@override
void initState() {
super.initState();
usernameController.text = widget.user.username;
emailController.text = widget.user.email;
}
@override
Widget build(BuildContext context) {
double screenWidth = MediaQuery.of(context).size.width;
return Consumer<MzansiProfileProvider>(
builder: (BuildContext context,
MzansiProfileProvider mzansiProfileProvider, Widget? child) {
return MihPackageWindow(
fullscreen: false,
windowTitle: "Add Employee",
windowBody: Padding(
padding:
MzansiInnovationHub.of(context)!.theme.screenType == "desktop"
? EdgeInsets.symmetric(horizontal: screenWidth * 0.05)
: const EdgeInsets.symmetric(horizontal: 0),
child: Column(
children: [
MihForm(
formKey: _formKey,
formFields: [
MihTextFormField(
fillColor: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
inputColor: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
controller: usernameController,
multiLineInput: false,
requiredText: true,
readOnly: true,
hintText: "Username",
),
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: emailController,
multiLineInput: false,
requiredText: true,
readOnly: true,
hintText: "Email",
),
const SizedBox(height: 10.0),
MihDropdownField(
controller: accessController,
hintText: "Access Type",
dropdownOptions: const ["Full", "Partial"],
editable: true,
enableSearch: true,
validator: (value) {
return MihValidationServices().isEmpty(value);
},
requiredText: true,
),
const SizedBox(height: 15.0),
Center(
child: MihButton(
onPressed: () {
if (_formKey.currentState!.validate()) {
if (isRequiredFieldsCaptured()) {
createBusinessUserAPICall(mzansiProfileProvider);
} else {
showDialog(
context: context,
builder: (context) {
return const MIHErrorMessage(
errorType: "Input Error");
},
);
}
} else {
MihAlertServices().formNotFilledCompletely(context);
}
},
buttonColor: MihColors.getGreenColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
width: 300,
child: Text(
"Add",
style: TextStyle(
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
),
),
],
),
],
),
),
onWindowTapClose: () {
Navigator.pop(context);
},
);
},
);
}
}

View File

@@ -7,23 +7,24 @@ import 'package:mzansi_innovation_hub/mih_components/mih_objects/business_review
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_button.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_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_package_alert.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_providers/mzansi_directory_provider.dart';
import 'package:mzansi_innovation_hub/mih_config/mih_colors.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'; import 'package:mzansi_innovation_hub/mih_packages/mzansi_profile/business_profile/components/mih_add_bookmark_alert.dart';
import 'package:mzansi_innovation_hub/mih_packages/mzansi_profile/business_profile/components/mih_delete_bookmark_alert.dart'; import 'package:mzansi_innovation_hub/mih_packages/mzansi_profile/business_profile/components/mih_delete_bookmark_alert.dart';
import 'package:mzansi_innovation_hub/mih_packages/mzansi_profile/business_profile/components/mih_review_business_window.dart'; import 'package:mzansi_innovation_hub/mih_packages/mzansi_profile/business_profile/components/mih_review_business_window.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_business_details_services.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_mzansi_directory_services.dart'; import 'package:mzansi_innovation_hub/mih_services/mih_mzansi_directory_services.dart';
import 'package:provider/provider.dart';
import 'package:redacted/redacted.dart'; import 'package:redacted/redacted.dart';
import 'package:supertokens_flutter/supertokens.dart'; import 'package:supertokens_flutter/supertokens.dart';
import 'package:url_launcher/url_launcher.dart'; import 'package:url_launcher/url_launcher.dart';
class MihBusinessCard extends StatefulWidget { class MihBusinessCard extends StatefulWidget {
final Business business; final Business business;
final String? startUpSearch;
final double width; final double width;
const MihBusinessCard({ const MihBusinessCard({
super.key, super.key,
required this.business, required this.business,
required this.startUpSearch,
required this.width, required this.width,
}); });
@@ -409,6 +410,9 @@ class _MihBusinessCardState extends State<MihBusinessCard> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
// double screenWidth = MediaQuery.of(context).size.width; // double screenWidth = MediaQuery.of(context).size.width;
return Consumer<MzansiDirectoryProvider>(
builder: (BuildContext context, MzansiDirectoryProvider directoryProvider,
Widget? child) {
return Material( return Material(
color: MihColors.getSecondaryColor( color: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark") MzansiInnovationHub.of(context)!.theme.mode == "Dark")
@@ -463,14 +467,16 @@ class _MihBusinessCardState extends State<MihBusinessCard> {
children: [ children: [
Divider( Divider(
color: MihColors.getPrimaryColor( color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"), MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
), ),
_buildContactInfo( _buildContactInfo(
"Location", "Location",
"Come visit us.", "Come visit us.",
Icons.location_on, Icons.location_on,
MihColors.getOrangeColor( MihColors.getOrangeColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"), MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
false, false,
() { () {
final latitude = double.parse( final latitude = double.parse(
@@ -493,14 +499,16 @@ class _MihBusinessCardState extends State<MihBusinessCard> {
children: [ children: [
Divider( Divider(
color: MihColors.getPrimaryColor( color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"), MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
), ),
_buildContactInfo( _buildContactInfo(
"Website", "Website",
"Find out more about us.", "Find out more about us.",
Icons.vpn_lock, Icons.vpn_lock,
MihColors.getRedColor( MihColors.getRedColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"), MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
false, false,
() { () {
_launchWebsite(widget.business.website); _launchWebsite(widget.business.website);
@@ -512,12 +520,14 @@ class _MihBusinessCardState extends State<MihBusinessCard> {
FutureBuilder( FutureBuilder(
future: _businessReviewFuture, future: _businessReviewFuture,
builder: (context, asyncSnapshot) { builder: (context, asyncSnapshot) {
if (asyncSnapshot.connectionState == ConnectionState.waiting) { if (asyncSnapshot.connectionState ==
ConnectionState.waiting) {
// return const SizedBox.shrink(); // return const SizedBox.shrink();
return Column( return Column(
children: [ children: [
Padding( Padding(
padding: const EdgeInsets.symmetric(horizontal: 10.0), padding:
const EdgeInsets.symmetric(horizontal: 10.0),
child: Divider( child: Divider(
color: MihColors.getPrimaryColor( color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode == MzansiInnovationHub.of(context)!.theme.mode ==
@@ -549,7 +559,8 @@ class _MihBusinessCardState extends State<MihBusinessCard> {
return Column( return Column(
children: [ children: [
Padding( Padding(
padding: const EdgeInsets.symmetric(horizontal: 10.0), padding:
const EdgeInsets.symmetric(horizontal: 10.0),
child: Divider( child: Divider(
color: MihColors.getPrimaryColor( color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode == MzansiInnovationHub.of(context)!.theme.mode ==
@@ -565,7 +576,7 @@ class _MihBusinessCardState extends State<MihBusinessCard> {
"Dark"), "Dark"),
false, false,
() { () {
businessReviewRatingWindow( businessReviewRatingWindow(directoryProvider,
businessReview, true, widget.width); businessReview, true, widget.width);
}, },
), ),
@@ -577,12 +588,14 @@ class _MihBusinessCardState extends State<MihBusinessCard> {
FutureBuilder( FutureBuilder(
future: _bookmarkedBusinessFuture, future: _bookmarkedBusinessFuture,
builder: (context, asyncSnapshot) { builder: (context, asyncSnapshot) {
if (asyncSnapshot.connectionState == ConnectionState.waiting) { if (asyncSnapshot.connectionState ==
ConnectionState.waiting) {
// return const SizedBox.shrink(); // return const SizedBox.shrink();
return Column( return Column(
children: [ children: [
Padding( Padding(
padding: const EdgeInsets.symmetric(horizontal: 10.0), padding:
const EdgeInsets.symmetric(horizontal: 10.0),
child: Divider( child: Divider(
color: MihColors.getPrimaryColor( color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode == MzansiInnovationHub.of(context)!.theme.mode ==
@@ -614,7 +627,8 @@ class _MihBusinessCardState extends State<MihBusinessCard> {
return Column( return Column(
children: [ children: [
Padding( Padding(
padding: const EdgeInsets.symmetric(horizontal: 10.0), padding:
const EdgeInsets.symmetric(horizontal: 10.0),
child: Divider( child: Divider(
color: MihColors.getPrimaryColor( color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode == MzansiInnovationHub.of(context)!.theme.mode ==
@@ -673,10 +687,15 @@ class _MihBusinessCardState extends State<MihBusinessCard> {
), ),
), ),
); );
},
);
} }
Future<void> businessReviewRatingWindow( Future<void> businessReviewRatingWindow(
BusinessReview? myReview, bool previouslyRated, double width) async { MzansiDirectoryProvider directoryProvider,
BusinessReview? myReview,
bool previouslyRated,
double width) async {
if (_isUserSignedIn) { if (_isUserSignedIn) {
showDialog( showDialog(
context: context, context: context,
@@ -685,6 +704,17 @@ class _MihBusinessCardState extends State<MihBusinessCard> {
businessReview: myReview, businessReview: myReview,
screenWidth: width, screenWidth: width,
readOnly: false, readOnly: false,
onSuccessDismissPressed: () async {
List<Business>? businessSearchResults = [];
businessSearchResults = await MihBusinessDetailsServices()
.searchBusinesses(directoryProvider.searchTerm,
directoryProvider.businessTypeFilter, context);
directoryProvider.setSearchedBusinesses(
searchedBusinesses: businessSearchResults);
setState(() {
_businessReviewFuture = getUserReview();
});
},
), ),
); );
} else { } else {
@@ -698,6 +728,11 @@ class _MihBusinessCardState extends State<MihBusinessCard> {
context: context, context: context,
builder: (context) => MihAddBookmarkAlert( builder: (context) => MihAddBookmarkAlert(
business: widget.business, business: widget.business,
onSuccessDismissPressed: () {
setState(() {
_bookmarkedBusinessFuture = getUserBookmark();
});
},
), ),
); );
} else { } else {
@@ -712,7 +747,12 @@ class _MihBusinessCardState extends State<MihBusinessCard> {
builder: (context) => MihDeleteBookmarkAlert( builder: (context) => MihDeleteBookmarkAlert(
business: widget.business, business: widget.business,
bookmarkBusiness: bookmarkBusiness, bookmarkBusiness: bookmarkBusiness,
startUpSearch: widget.startUpSearch, onSuccessDismissPressed: () {
setState(() {
_bookmarkedBusinessFuture = getUserBookmark();
});
},
// startUpSearch: widget.startUpSearch,
)); ));
} else { } else {
showSignInRequiredAlert(); showSignInRequiredAlert();

View File

@@ -1,7 +1,6 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart'; import 'package:go_router/go_router.dart';
import 'package:mzansi_innovation_hub/main.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'; 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.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_button.dart';
@@ -14,12 +13,14 @@ import 'package:mzansi_innovation_hub/mih_services/mih_mzansi_directory_services
class MihDeleteBookmarkAlert extends StatefulWidget { class MihDeleteBookmarkAlert extends StatefulWidget {
final Business business; final Business business;
final BookmarkedBusiness? bookmarkBusiness; final BookmarkedBusiness? bookmarkBusiness;
final String? startUpSearch; final void Function()? onSuccessDismissPressed;
// final String? startUpSearch;
const MihDeleteBookmarkAlert({ const MihDeleteBookmarkAlert({
super.key, super.key,
required this.business, required this.business,
required this.bookmarkBusiness, required this.bookmarkBusiness,
required this.startUpSearch, required this.onSuccessDismissPressed,
// required this.startUpSearch,
}); });
@override @override
@@ -80,14 +81,17 @@ class _MihDeleteBookmarkAlertState extends State<MihDeleteBookmarkAlert> {
Center( Center(
child: MihButton( child: MihButton(
onPressed: () { onPressed: () {
context.goNamed( // context.goNamed(
"mzansiDirectory", // "mzansiDirectory",
extra: MzansiDirectoryArguments( // extra: MzansiDirectoryArguments(
personalSearch: false, // personalSearch: false,
startSearchText: widget.business.Name, // startSearchText: widget.business.Name,
packageIndex: 1, // packageIndex: 1,
), // ),
); // );
widget.onSuccessDismissPressed!.call();
context.pop();
context.pop();
}, },
buttonColor: MihColors.getGreenColor( buttonColor: MihColors.getGreenColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"), MzansiInnovationHub.of(context)!.theme.mode == "Dark"),

View File

@@ -0,0 +1,319 @@
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_employee.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_dropdwn_field.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_form.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_alert.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_window.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_text_form_field.dart';
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_providers/mzansi_profile_provider.dart';
import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_alert_services.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_business_employee_services.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_validation_services.dart';
import 'package:provider/provider.dart';
class MihEditEmployeeDetailsWindow extends StatefulWidget {
final BusinessEmployee employee;
const MihEditEmployeeDetailsWindow({
super.key,
required this.employee,
});
@override
State<MihEditEmployeeDetailsWindow> createState() =>
_MihEditEmployeeDetailsWindowState();
}
class _MihEditEmployeeDetailsWindowState
extends State<MihEditEmployeeDetailsWindow> {
TextEditingController accessController = TextEditingController();
TextEditingController titleController = TextEditingController();
TextEditingController fnameController = TextEditingController();
TextEditingController lnameController = TextEditingController();
final _formKey = GlobalKey<FormState>();
void updateEmployeeAPICall(
MzansiProfileProvider mzansiProfileProvider) async {
int statusCode = await MihBusinessEmployeeServices().updateEmployeeDetails(
mzansiProfileProvider,
widget.employee,
titleController.text,
accessController.text,
context);
if (statusCode == 200) {
String message = "Your employees details have been updated.";
successPopUp(message, false);
} else {
internetConnectionPopUp();
}
}
Future<void> deleteNoteApiCall() async {
int statusCode = await MihBusinessEmployeeServices().deleteEmployee(
context.read<MzansiProfileProvider>(),
widget.employee,
context,
);
if (statusCode == 200) {
String message =
"The employee has been deleted successfully. This means they will no longer have access to your business profile";
successPopUp(message, false);
} else {
internetConnectionPopUp();
}
}
void showDeleteWarning() {
showDialog(
context: context,
barrierDismissible: false,
builder: (context) => MIHDeleteMessage(
deleteType: "Employee",
onTap: () {
deleteNoteApiCall();
}));
}
void successPopUp(String message, bool stayOnPersonalSide) {
showDialog(
context: context,
builder: (context) {
return MihPackageAlert(
alertIcon: Icon(
Icons.check_circle_outline_rounded,
size: 150,
color: MihColors.getGreenColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
),
alertTitle: "Successfully Updated Profile",
alertBody: Column(
children: [
Text(
message,
style: TextStyle(
color: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
fontSize: 15,
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 25),
Center(
child: MihButton(
onPressed: () {
context.pop();
context.pop();
},
buttonColor: MihColors.getGreenColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
elevation: 10,
width: 300,
child: Text(
"Dismiss",
style: TextStyle(
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
),
)
],
),
alertColour: MihColors.getGreenColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
);
// return MIHSuccessMessage(
// successType: "Success",
// successMessage: message,
// );
},
);
}
void internetConnectionPopUp() {
showDialog(
context: context,
builder: (context) {
return const MIHErrorMessage(errorType: "Internet Connection");
},
);
}
bool isRequiredFieldsCaptured() {
if (accessController.text.isEmpty || titleController.text.isEmpty) {
return false;
} else {
return true;
}
}
@override
void dispose() {
accessController.dispose();
titleController.dispose();
fnameController.dispose();
lnameController.dispose();
super.dispose();
}
@override
void initState() {
super.initState();
fnameController.text = widget.employee.fname;
lnameController.text = widget.employee.lname;
titleController.text = widget.employee.title;
accessController.text = widget.employee.access;
}
@override
Widget build(BuildContext context) {
double screenWidth = MediaQuery.of(context).size.width;
return Consumer<MzansiProfileProvider>(
builder: (BuildContext context,
MzansiProfileProvider mzansiProfileProvider, Widget? child) {
return MihPackageWindow(
fullscreen: false,
windowTitle: "Employee Details",
menuOptions: [
SpeedDialChild(
child: Icon(
Icons.delete,
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
),
label: "Delete Employee",
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: () {
showDeleteWarning();
},
),
],
onWindowTapClose: () {
Navigator.pop(context);
},
windowBody: Padding(
padding:
MzansiInnovationHub.of(context)!.theme.screenType == "desktop"
? EdgeInsets.symmetric(horizontal: screenWidth * 0.05)
: const EdgeInsets.symmetric(horizontal: 0),
child: Column(
children: [
MihForm(
formKey: _formKey,
formFields: [
MihTextFormField(
fillColor: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
inputColor: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
controller: fnameController,
multiLineInput: false,
requiredText: true,
readOnly: true,
hintText: "First Name",
),
const SizedBox(height: 10.0),
MihTextFormField(
fillColor: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
inputColor: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
controller: lnameController,
multiLineInput: false,
requiredText: true,
readOnly: true,
hintText: "Surname",
),
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: titleController,
multiLineInput: false,
requiredText: true,
readOnly: true,
hintText: "Title",
),
const SizedBox(height: 10.0),
MihDropdownField(
controller: accessController,
hintText: "Access Type",
dropdownOptions: const ["Full", "Partial"],
editable: true,
enableSearch: true,
validator: (value) {
return MihValidationServices().isEmpty(value);
},
requiredText: true,
),
const SizedBox(height: 20.0),
Center(
child: MihButton(
onPressed: () {
if (_formKey.currentState!.validate()) {
if (isRequiredFieldsCaptured()) {
updateEmployeeAPICall(mzansiProfileProvider);
} else {
showDialog(
context: context,
builder: (context) {
return const MIHErrorMessage(
errorType: "Input Error");
},
);
}
} else {
MihAlertServices().formNotFilledCompletely(context);
}
},
buttonColor: MihColors.getGreenColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
width: 300,
child: Text(
"Update",
style: TextStyle(
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
),
),
],
),
],
),
),
);
},
);
}
}

View File

@@ -3,7 +3,6 @@ import 'package:flutter/material.dart';
import 'package:flutter_speed_dial/flutter_speed_dial.dart'; import 'package:flutter_speed_dial/flutter_speed_dial.dart';
import 'package:go_router/go_router.dart'; import 'package:go_router/go_router.dart';
import 'package:mzansi_innovation_hub/main.dart'; import 'package:mzansi_innovation_hub/main.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_objects/arguments.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_objects/business.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_objects/business.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_objects/business_review.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_button.dart';
@@ -13,23 +12,28 @@ import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_
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_single_child_scroll.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_text_form_field.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_text_form_field.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_loading_circle.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_providers/mzansi_directory_provider.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_providers/mzansi_profile_provider.dart';
import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart'; import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_alert_services.dart'; import 'package:mzansi_innovation_hub/mih_services/mih_alert_services.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_business_details_services.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_mzansi_directory_services.dart'; import 'package:mzansi_innovation_hub/mih_services/mih_mzansi_directory_services.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_validation_services.dart'; import 'package:mzansi_innovation_hub/mih_services/mih_validation_services.dart';
import 'package:supertokens_flutter/supertokens.dart'; import 'package:provider/provider.dart';
class MihReviewBusinessWindow extends StatefulWidget { class MihReviewBusinessWindow extends StatefulWidget {
final Business business; final Business business;
final BusinessReview? businessReview; final BusinessReview? businessReview;
final double screenWidth; final double screenWidth;
final bool readOnly; final bool readOnly;
final void Function()? onSuccessDismissPressed;
const MihReviewBusinessWindow({ const MihReviewBusinessWindow({
super.key, super.key,
required this.business, required this.business,
required this.businessReview, required this.businessReview,
required this.screenWidth, required this.screenWidth,
required this.readOnly, required this.readOnly,
required this.onSuccessDismissPressed,
}); });
@override @override
@@ -47,9 +51,8 @@ class _MihReviewBusinessWindowState extends State<MihReviewBusinessWindow> {
TextEditingController(); TextEditingController();
late final VoidCallback _reviewDescriptionListener; late final VoidCallback _reviewDescriptionListener;
final ValueNotifier<int> _counter = ValueNotifier<int>(0); final ValueNotifier<int> _counter = ValueNotifier<int>(0);
String userId = "";
void showDeleteReviewAlert() { void showDeleteReviewAlert(MzansiDirectoryProvider directoryProvider) {
showDialog( showDialog(
context: context, context: context,
builder: (context) => MihPackageAlert( builder: (context) => MihPackageAlert(
@@ -93,10 +96,11 @@ class _MihReviewBusinessWindowState extends State<MihReviewBusinessWindow> {
widget.businessReview!.rating_score, widget.businessReview!.rating_score,
widget.business.rating, widget.business.rating,
) )
.then((statusCode) { .then((statusCode) async {
context.pop(); //Remove loading dialog context.pop(); //Remove loading dialog
context.pop(); //Remove delete dialog context.pop(); //Remove delete dialog
if (statusCode == 200) { if (statusCode == 200) {
await refreshBusiness(directoryProvider);
context.pop(); //Remove window context.pop(); //Remove window
successPopUp( successPopUp(
"Successfully Deleted Review!", "Successfully Deleted Review!",
@@ -160,7 +164,19 @@ class _MihReviewBusinessWindowState extends State<MihReviewBusinessWindow> {
} }
} }
void submitForm() async { Future<void> refreshBusiness(
MzansiDirectoryProvider directoryProvider) async {
Business? refresedBusiness = await MihBusinessDetailsServices()
.getBusinessDetailsByBusinessId(widget.business.business_id);
if (refresedBusiness != null) {
directoryProvider.setSelectedBusiness(business: refresedBusiness);
}
}
void submitForm(
MzansiProfileProvider profileProvider,
MzansiDirectoryProvider directoryProvider,
) async {
showDialog( showDialog(
context: context, context: context,
builder: (context) { builder: (context) {
@@ -178,9 +194,10 @@ class _MihReviewBusinessWindowState extends State<MihReviewBusinessWindow> {
widget.businessReview!.rating_score, widget.businessReview!.rating_score,
widget.business.rating, widget.business.rating,
) )
.then((statusCode) { .then((statusCode) async {
context.pop(); //Remove loading dialog context.pop(); //Remove loading dialog
if (statusCode == 200) { if (statusCode == 200) {
await refreshBusiness(directoryProvider);
context.pop(); context.pop();
successPopUp( successPopUp(
"Successfully Updated Review!", "Successfully Updated Review!",
@@ -197,16 +214,17 @@ class _MihReviewBusinessWindowState extends State<MihReviewBusinessWindow> {
} else { } else {
await MihMzansiDirectoryServices() await MihMzansiDirectoryServices()
.addBusinessReview( .addBusinessReview(
userId, profileProvider.user!.app_id,
widget.business.business_id, widget.business.business_id,
_reviewTitleController.text, _reviewTitleController.text,
_reviewDescriptionController.text, _reviewDescriptionController.text,
_reviewScoreController.text, _reviewScoreController.text,
widget.business.rating.isEmpty ? "0.0" : widget.business.rating, widget.business.rating.isEmpty ? "0.0" : widget.business.rating,
) )
.then((statusCode) { .then((statusCode) async {
context.pop(); //Remove loading dialog context.pop(); //Remove loading dialog
if (statusCode == 201) { if (statusCode == 201) {
await refreshBusiness(directoryProvider);
context.pop(); context.pop();
successPopUp( successPopUp(
"Successfully Added Review!", "Successfully Added Review!",
@@ -250,13 +268,15 @@ class _MihReviewBusinessWindowState extends State<MihReviewBusinessWindow> {
Center( Center(
child: MihButton( child: MihButton(
onPressed: () { onPressed: () {
context.goNamed( // context.goNamed(
"mzansiDirectory", // "mzansiDirectory",
extra: MzansiDirectoryArguments( // extra: MzansiDirectoryArguments(
personalSearch: false, // personalSearch: false,
startSearchText: widget.business.Name, // startSearchText: widget.business.Name,
), // ),
); // );
widget.onSuccessDismissPressed!.call();
context.pop();
}, },
buttonColor: MihColors.getGreenColor( buttonColor: MihColors.getGreenColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"), MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
@@ -323,16 +343,14 @@ class _MihReviewBusinessWindowState extends State<MihReviewBusinessWindow> {
} else { } else {
_reviewScoreController.text = "1.0"; // Default score _reviewScoreController.text = "1.0"; // Default score
} }
SuperTokens.getUserId().then((value) {
setState(() {
userId = value;
});
});
} }
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
// return const Placeholder(); // return const Placeholder();
return Consumer2<MzansiProfileProvider, MzansiDirectoryProvider>(
builder: (BuildContext context, MzansiProfileProvider profileProvider,
MzansiDirectoryProvider directoryProvider, Widget? child) {
return MihPackageWindow( return MihPackageWindow(
fullscreen: false, fullscreen: false,
windowTitle: getWindowTitle(), windowTitle: getWindowTitle(),
@@ -345,28 +363,30 @@ class _MihReviewBusinessWindowState extends State<MihReviewBusinessWindow> {
child: Icon( child: Icon(
Icons.delete, Icons.delete,
color: MihColors.getPrimaryColor( color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"), MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
), ),
label: "Delete Review", label: "Delete Review",
labelBackgroundColor: MihColors.getGreenColor( labelBackgroundColor: MihColors.getGreenColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"), MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
labelStyle: TextStyle( labelStyle: TextStyle(
color: MihColors.getPrimaryColor( color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"), MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
), ),
backgroundColor: MihColors.getGreenColor( backgroundColor: MihColors.getGreenColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"), MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
onTap: () { onTap: () {
showDeleteReviewAlert(); showDeleteReviewAlert(directoryProvider);
}, },
), ),
] ]
: null, : null,
windowBody: MihSingleChildScroll( windowBody: MihSingleChildScroll(
child: Padding( child: Padding(
padding: padding: MzansiInnovationHub.of(context)!.theme.screenType ==
MzansiInnovationHub.of(context)!.theme.screenType == "desktop" "desktop"
? EdgeInsets.symmetric(horizontal: widget.screenWidth * 0.05) ? EdgeInsets.symmetric(horizontal: widget.screenWidth * 0.05)
: EdgeInsets.symmetric(horizontal: widget.screenWidth * 0), : EdgeInsets.symmetric(horizontal: widget.screenWidth * 0),
child: Column( child: Column(
@@ -478,9 +498,11 @@ class _MihReviewBusinessWindowState extends State<MihReviewBusinessWindow> {
MihTextFormField( MihTextFormField(
// width: 200, // width: 200,
fillColor: MihColors.getSecondaryColor( fillColor: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"), MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
inputColor: MihColors.getPrimaryColor( inputColor: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"), MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
controller: _reviewTitleController, controller: _reviewTitleController,
multiLineInput: false, multiLineInput: false,
requiredText: true, requiredText: true,
@@ -495,9 +517,11 @@ class _MihReviewBusinessWindowState extends State<MihReviewBusinessWindow> {
MihTextFormField( MihTextFormField(
height: 250, height: 250,
fillColor: MihColors.getSecondaryColor( fillColor: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"), MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
inputColor: MihColors.getPrimaryColor( inputColor: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"), MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
controller: _reviewDescriptionController, controller: _reviewDescriptionController,
multiLineInput: true, multiLineInput: true,
requiredText: widget.readOnly, requiredText: widget.readOnly,
@@ -518,8 +542,8 @@ class _MihReviewBusinessWindowState extends State<MihReviewBusinessWindow> {
height: 15, height: 15,
child: ValueListenableBuilder( child: ValueListenableBuilder(
valueListenable: _counter, valueListenable: _counter,
builder: builder: (BuildContext context, int value,
(BuildContext context, int value, Widget? child) { Widget? child) {
return Row( return Row(
mainAxisSize: MainAxisSize.max, mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.end, mainAxisAlignment: MainAxisAlignment.end,
@@ -552,9 +576,13 @@ class _MihReviewBusinessWindowState extends State<MihReviewBusinessWindow> {
child: MihButton( child: MihButton(
onPressed: () { onPressed: () {
if (_formKey.currentState!.validate()) { if (_formKey.currentState!.validate()) {
submitForm(); submitForm(
profileProvider,
directoryProvider,
);
} else { } else {
MihAlertServices().formNotFilledCompletely(context); MihAlertServices()
.formNotFilledCompletely(context);
} }
}, },
buttonColor: MihColors.getGreenColor( buttonColor: MihColors.getGreenColor(
@@ -567,7 +595,9 @@ class _MihReviewBusinessWindowState extends State<MihReviewBusinessWindow> {
: "Add Review", : "Add Review",
style: TextStyle( style: TextStyle(
color: MihColors.getPrimaryColor( color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode == MzansiInnovationHub.of(context)!
.theme
.mode ==
"Dark"), "Dark"),
fontSize: 20, fontSize: 20,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
@@ -583,5 +613,7 @@ class _MihReviewBusinessWindowState extends State<MihReviewBusinessWindow> {
), ),
), ),
); );
},
);
} }
} }

View File

@@ -0,0 +1,705 @@
import 'package:country_code_picker/country_code_picker.dart';
import 'package:file_picker/file_picker.dart';
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:ken_logger/ken_logger.dart';
import 'package:mzansi_innovation_hub/main.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_button.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_circle_avatar.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_form.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_alert.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_window.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_single_child_scroll.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_text_form_field.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_error_message.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_loading_circle.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_providers/mzansi_profile_provider.dart';
import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart';
import 'package:mzansi_innovation_hub/mih_config/mih_env.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_alert_services.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_business_details_services.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_file_services.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_location_services.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_validation_services.dart';
import 'package:provider/provider.dart';
class MihUpdateBusinessDetailsWindow extends StatefulWidget {
final double width;
const MihUpdateBusinessDetailsWindow({
super.key,
required this.width,
});
@override
State<MihUpdateBusinessDetailsWindow> createState() =>
_MihUpdateBusinessDetailsWindowState();
}
class _MihUpdateBusinessDetailsWindowState
extends State<MihUpdateBusinessDetailsWindow> {
final _formKey = GlobalKey<FormState>();
PlatformFile? newSelectedLogoPic;
final fileNameController = TextEditingController();
final regController = TextEditingController();
final nameController = TextEditingController();
final typeController = TextEditingController();
final practiceNoController = TextEditingController();
final vatNoController = TextEditingController();
final countryCodeController = TextEditingController();
final contactController = TextEditingController();
final emailController = TextEditingController();
final locationController = TextEditingController();
final websiteController = TextEditingController();
final ratingController = TextEditingController();
final missionVisionController = TextEditingController();
final ValueNotifier<int> _counter = ValueNotifier<int>(0);
late String env;
void setContactNumberControllers(
MzansiProfileProvider mzansiProfileProvider) {
if (mzansiProfileProvider.business!.contact_no[0] == "+") {
List<String> contactDetails =
mzansiProfileProvider.business!.contact_no.split("-");
setState(() {
countryCodeController.text = contactDetails[0];
contactController.text = contactDetails[1];
});
} else {
setState(() {
countryCodeController.text = "+27";
contactController.text = mzansiProfileProvider.business!.contact_no;
});
}
}
void setControllers() {
MzansiProfileProvider mzansiProfileProvider =
context.read<MzansiProfileProvider>();
setState(() {
fileNameController.text =
mzansiProfileProvider.business!.logo_path.split("/").last;
regController.text = mzansiProfileProvider.business!.registration_no;
nameController.text = mzansiProfileProvider.business!.Name;
typeController.text = mzansiProfileProvider.business!.type;
practiceNoController.text = mzansiProfileProvider.business!.practice_no;
vatNoController.text = mzansiProfileProvider.business!.vat_no;
emailController.text = mzansiProfileProvider.business!.bus_email;
locationController.text = mzansiProfileProvider.business!.gps_location;
websiteController.text = mzansiProfileProvider.business!.website;
ratingController.text = mzansiProfileProvider.business!.rating;
missionVisionController.text =
mzansiProfileProvider.business!.mission_vision;
});
setContactNumberControllers(mzansiProfileProvider);
if (AppEnviroment.getEnv() == "Prod") {
env = "Prod";
} else {
env = "Dev";
}
}
Color getMissionVisionLimitColor(int limit) {
if (_counter.value <= limit) {
return MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark");
} else {
return MihColors.getRedColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark");
}
}
void _updateMissionVisionCounter() {
// New function name
// No need for setState since you are using a ValueNotifier for _counter
_counter.value = missionVisionController.text.characters.length;
}
String getNumberWithCountryCode() {
String numberWithoutBeginingZero = "";
if (contactController.text[0] == "0") {
numberWithoutBeginingZero = contactController.text
.replaceAll(" ", "")
.substring(1, contactController.text.length);
} else {
numberWithoutBeginingZero = contactController.text.replaceAll("-", " ");
}
return "${countryCodeController.text}-$numberWithoutBeginingZero";
}
bool isFormFilled() {
if (typeController.text.isEmpty) {
return false;
} else {
return true;
}
}
void successPopUp(String message, bool stayOnPersonalSide) {
showDialog(
context: context,
builder: (context) {
return MihPackageAlert(
alertIcon: Icon(
Icons.check_circle_outline_rounded,
size: 150,
color: MihColors.getGreenColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
),
alertTitle: "Successfully Updated Profile",
alertBody: Column(
children: [
Text(
message,
style: TextStyle(
color: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
fontSize: 15,
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 25),
Center(
child: MihButton(
onPressed: () {
context.pop();
},
buttonColor: MihColors.getGreenColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
elevation: 10,
width: 300,
child: Text(
"Dismiss",
style: TextStyle(
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
),
)
],
),
alertColour: MihColors.getGreenColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
);
// return MIHSuccessMessage(
// successType: "Success",
// successMessage: message,
// );
},
);
}
Future<bool> uploadFile(MzansiProfileProvider mzansiProfileProvider) async {
if (newSelectedLogoPic != null) {
int uploadStatusCode = 0;
uploadStatusCode = await MihFileApi.uploadFile(
mzansiProfileProvider.business!.business_id,
env,
"business_files",
newSelectedLogoPic!,
context,
);
if (uploadStatusCode == 200) {
int deleteStatusCode = 0;
deleteStatusCode = await MihFileApi.deleteFile(
mzansiProfileProvider.business!.logo_path.split("/").first,
env,
"business_files",
mzansiProfileProvider.business!.logo_path.split("/").last,
context,
);
if (deleteStatusCode == 200) {
return true;
} else {
return false;
}
} else {
return false;
}
} else {
return true; // No file selected, so no upload needed
}
}
Future<void> submitForm(MzansiProfileProvider mzansiProfileProvider) async {
KenLogger.success("Start Submit Form");
if (isFormFilled()) {
KenLogger.success("Form Filled");
KenLogger.success("Start File Upload");
bool successfullyUploadedFile = await uploadFile(mzansiProfileProvider);
KenLogger.success(
"File Upload Complete: outcome $successfullyUploadedFile");
if (!mounted) return;
KenLogger.success("is mounted");
if (successfullyUploadedFile) {
KenLogger.success("Start Details Update");
int statusCode = 0;
statusCode = await MihBusinessDetailsServices().updateBusinessDetailsV2(
mzansiProfileProvider.business!.business_id,
nameController.text,
typeController.text,
regController.text,
practiceNoController.text,
vatNoController.text,
emailController.text,
getNumberWithCountryCode(),
// contactController.text,
locationController.text,
fileNameController.text,
websiteController.text,
ratingController.text.isEmpty ? "0" : ratingController.text,
missionVisionController.text,
mzansiProfileProvider,
context,
);
KenLogger.success("Details Update Complete: status code $statusCode");
if (!mounted) return;
KenLogger.success("is mounted");
if (statusCode == 200) {
KenLogger.success("Start Success Message");
//You left of here
String message = "Your information has been updated successfully!";
context.pop();
successPopUp(message, false);
// File uploaded successfully
} else {
context.pop();
// File upload failed
showDialog(
context: context,
builder: (context) {
return MihPackageAlert(
alertIcon: Icon(
Icons.warning_rounded,
color: MihColors.getRedColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
),
alertTitle: "Error Updating Business Details",
alertBody: Column(
children: [
Text(
"An error occurred while updating the business details. Please check internet connection and try again.",
style: TextStyle(
color: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
),
),
],
),
alertColour: MihColors.getRedColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
);
},
);
}
} else {
context.pop();
if (!mounted) return;
showDialog(
context: context,
builder: (context) {
return const MIHErrorMessage(errorType: "Internet Connection");
},
);
}
} else {
showDialog(
context: context,
builder: (context) {
return const MIHErrorMessage(errorType: "Input Error");
},
);
}
}
@override
void initState() {
super.initState();
setControllers();
missionVisionController.addListener(_updateMissionVisionCounter);
}
@override
Widget build(BuildContext context) {
return Consumer<MzansiProfileProvider>(
builder: (BuildContext context,
MzansiProfileProvider mzansiProfileProvider, Widget? child) {
return MihPackageWindow(
fullscreen: false,
windowTitle: 'Edit Profile',
onWindowTapClose: () {
context.pop();
},
windowBody: MihSingleChildScroll(
child: Padding(
padding:
MzansiInnovationHub.of(context)!.theme.screenType == "desktop"
? EdgeInsets.symmetric(horizontal: widget.width * 0.05)
: EdgeInsets.symmetric(horizontal: widget.width * 0),
child: Column(
children: [
MihForm(
formKey: _formKey,
formFields: [
Center(
child: MihCircleAvatar(
imageFile: newSelectedLogoPic != null
? MemoryImage(newSelectedLogoPic!.bytes!)
: mzansiProfileProvider.businessProfilePicture,
width: 150,
editable: true,
fileNameController: fileNameController,
userSelectedfile: newSelectedLogoPic,
frameColor: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
backgroundColor: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
onChange: (selectedfile) {
setState(() {
newSelectedLogoPic = selectedfile;
});
},
),
),
Visibility(
visible: false,
child: MihTextFormField(
fillColor: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
inputColor: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
controller: fileNameController,
multiLineInput: false,
requiredText: true,
readOnly: true,
hintText: "Selected File Name",
),
),
const SizedBox(height: 20),
MihTextFormField(
fillColor: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
inputColor: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
controller: nameController,
multiLineInput: false,
requiredText: true,
hintText: "Business Name",
validator: (value) {
return MihValidationServices().isEmpty(value);
},
),
const SizedBox(height: 10),
MihTextFormField(
fillColor: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
inputColor: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
controller: typeController,
multiLineInput: false,
requiredText: true,
hintText: "Business Type",
validator: (value) {
return MihValidationServices()
.validateNoSpecialChars(value);
},
),
const SizedBox(height: 10),
MihTextFormField(
fillColor: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
inputColor: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
controller: emailController,
multiLineInput: false,
requiredText: true,
hintText: "Business Email",
validator: (value) {
return MihValidationServices().validateEmail(value);
},
),
const SizedBox(height: 10),
Container(
width: 300,
alignment: Alignment.topLeft,
child: const Text(
"Contact Number:",
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
),
Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
CountryCodePicker(
padding: EdgeInsetsGeometry.all(0),
onChanged: (selectedCode) {
setState(() {
countryCodeController.text =
selectedCode.toString();
});
debugPrint(
"Selected Country Code: ${countryCodeController.text}");
},
initialSelection: countryCodeController.text,
showDropDownButton: false,
pickerStyle: PickerStyle.bottomSheet,
dialogBackgroundColor: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
barrierColor: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
),
Expanded(
child: MihTextFormField(
fillColor: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
inputColor: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
controller: contactController,
numberMode: true,
multiLineInput: false,
requiredText: true,
hintText: null,
validator: (value) {
return MihValidationServices().isEmpty(value);
},
),
),
],
),
const SizedBox(height: 10),
MihTextFormField(
height: 250,
fillColor: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
inputColor: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
controller: missionVisionController,
multiLineInput: true,
requiredText: true,
hintText: "Business Mission & Vision",
validator: (value) {
return MihValidationServices().validateLength(
missionVisionController.text, 256);
},
),
SizedBox(
height: 15,
child: ValueListenableBuilder(
valueListenable: _counter,
builder:
(BuildContext context, int value, Widget? child) {
return Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.end,
children: [
Text(
"$value",
style: TextStyle(
color: getMissionVisionLimitColor(256),
fontWeight: FontWeight.bold,
),
),
const SizedBox(width: 5),
Text(
"/256",
style: TextStyle(
color: getMissionVisionLimitColor(256),
fontWeight: FontWeight.bold,
),
),
],
);
},
),
),
const SizedBox(height: 10.0),
MihTextFormField(
fillColor: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
inputColor: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
controller: websiteController,
multiLineInput: false,
requiredText: false,
hintText: "Business Website",
validator: (value) {
return MihValidationServices()
.validateWebsite(value, false);
},
),
const SizedBox(height: 10),
MihTextFormField(
fillColor: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
inputColor: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
controller: regController,
multiLineInput: false,
requiredText: false,
hintText: "Registration No.",
validator: (value) {
// return MihValidationServices().isEmpty(value);
return null;
},
),
const SizedBox(height: 10),
MihTextFormField(
fillColor: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
inputColor: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
controller: practiceNoController,
multiLineInput: false,
requiredText: false,
hintText: "Practice Number",
validator: (validateValue) {
return null;
},
),
const SizedBox(height: 10),
MihTextFormField(
fillColor: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
inputColor: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
controller: vatNoController,
multiLineInput: false,
requiredText: false,
hintText: "VAT Number",
validator: (value) {
// return MihValidationServices().isEmpty(value);
return null;
},
),
const SizedBox(height: 10),
Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Flexible(
child: MihTextFormField(
fillColor: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
inputColor: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
controller: locationController,
multiLineInput: false,
requiredText: true,
readOnly: true,
hintText: "GPS Location",
),
),
const SizedBox(width: 10.0),
MihButton(
onPressed: () {
showDialog(
context: context,
builder: (context) {
return const Mihloadingcircle(
message: "Getting your location",
);
},
);
MIHLocationAPI()
.getGPSPosition(context)
.then((position) {
if (position != null) {
setState(() {
locationController.text =
"${position.latitude}, ${position.longitude}";
});
}
//Dismiss loading indicator
context.pop();
});
},
buttonColor: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
width: 100,
child: Text(
"Set",
style: TextStyle(
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!
.theme
.mode ==
"Dark"),
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
),
],
),
const SizedBox(height: 25),
Center(
child: MihButton(
onPressed: () {
if (_formKey.currentState!.validate()) {
submitForm(mzansiProfileProvider);
} else {
MihAlertServices()
.formNotFilledCompletely(context);
}
},
buttonColor: MihColors.getGreenColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
width: 300,
child: Text(
"Update",
style: TextStyle(
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
),
),
const SizedBox(height: 20),
],
),
],
),
),
),
);
},
);
}
}

View File

@@ -1,188 +0,0 @@
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';
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_action.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_tools.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_loading_circle.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_objects/arguments.dart';
import 'package:mzansi_innovation_hub/mih_packages/mzansi_profile/business_profile/package_tools/mih_business_details.dart';
import 'package:mzansi_innovation_hub/mih_packages/mzansi_profile/business_profile/package_tools/mih_business_user_search.dart';
import 'package:mzansi_innovation_hub/mih_packages/mzansi_profile/business_profile/package_tools/mih_my_business_team.dart';
import 'package:flutter/material.dart';
import 'package:mzansi_innovation_hub/mih_packages/mzansi_profile/business_profile/package_tools/mih_my_business_user.dart';
class MzansiBusinessProfile extends StatefulWidget {
final BusinessArguments arguments;
const MzansiBusinessProfile({
super.key,
required this.arguments,
});
@override
State<MzansiBusinessProfile> createState() => _MzansiBusinessProfileState();
}
class _MzansiBusinessProfileState extends State<MzansiBusinessProfile> {
int _selcetedIndex = 0;
late Future<String> futureLogoUrl;
late Future<String> futureProPicUrl;
late Future<String> futureUserSignatureUrl;
@override
void initState() {
super.initState();
futureLogoUrl = MihFileApi.getMinioFileUrl(
widget.arguments.business!.logo_path,
context,
);
futureProPicUrl = MihFileApi.getMinioFileUrl(
widget.arguments.signedInUser.pro_pic_path,
context,
);
futureUserSignatureUrl = MihFileApi.getMinioFileUrl(
widget.arguments.businessUser!.sig_path,
context,
);
}
@override
Widget build(BuildContext context) {
return MihPackage(
appActionButton: getAction(),
appTools: getTools(),
appBody: getToolBody(),
appToolTitles: getToolTitle(),
selectedbodyIndex: _selcetedIndex,
onIndexChange: (newValue) {
setState(() {
_selcetedIndex = newValue;
});
},
);
}
MihPackageAction getAction() {
return MihPackageAction(
icon: const Icon(Icons.arrow_back),
iconSize: 35,
onTap: () {
context.goNamed(
'mihHome',
extra: false,
);
FocusScope.of(context).unfocus();
},
);
}
MihPackageTools getTools() {
Map<Widget, void Function()?> temp = {};
temp[const Icon(Icons.business)] = () {
setState(() {
_selcetedIndex = 0;
});
};
temp[const Icon(Icons.person)] = () {
setState(() {
_selcetedIndex = 1;
});
};
// temp[const Icon(Icons.warning)] = () {
// setState(() {
// _selcetedIndex = 2;
// });
// };
temp[const Icon(Icons.people)] = () {
setState(() {
_selcetedIndex = 2;
});
};
temp[const Icon(Icons.add)] = () {
setState(() {
_selcetedIndex = 3;
});
};
temp[const Icon(Icons.star_rate_rounded)] = () {
setState(() {
_selcetedIndex = 4;
});
};
temp[const Icon(Icons.qr_code_rounded)] = () {
setState(() {
_selcetedIndex = 5;
});
};
return MihPackageTools(
tools: temp,
selcetedIndex: _selcetedIndex,
);
}
List<Widget> getToolBody() {
List<Widget> toolBodies = [
FutureBuilder(
future: futureLogoUrl,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const Center(child: Mihloadingcircle());
} else if (snapshot.connectionState == ConnectionState.done &&
snapshot.hasData) {
final logoUrl = snapshot.data!.isNotEmpty
? NetworkImage(snapshot.data!)
: null;
return MihBusinessDetails(
arguments: widget.arguments,
logoImage: logoUrl,
);
} else {
return Text("Error: ${snapshot.error}");
}
}),
FutureBuilder<List<String>>(
future: Future.wait([futureProPicUrl, futureUserSignatureUrl]),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const Center(child: Mihloadingcircle());
} else if (snapshot.connectionState == ConnectionState.done &&
snapshot.hasData) {
final proPicUrl = NetworkImage(snapshot.data![0]);
print("=============== Signature URL: ${snapshot.data![1]}");
final signatureUrl = snapshot.data![1].isNotEmpty
? NetworkImage(snapshot.data![1])
: null;
return MihMyBusinessUser(
arguments: widget.arguments,
userProPicImage: proPicUrl,
userSignatureImage: signatureUrl,
);
} else {
return Text("Error: ${snapshot.error}");
}
},
),
// MihBusinessProfile(arguments: widget.arguments),
MihMyBusinessTeam(arguments: widget.arguments),
MihBusinessUserSearch(arguments: widget.arguments),
MihBusinessReviews(business: widget.arguments.business!),
MihBusinessQrCode(
business: widget.arguments.business!,
startUpSearch: "",
),
];
return toolBodies;
}
List<String> getToolTitle() {
List<String> toolTitles = [
"Profile",
"User",
"Team",
"Add",
"Reviews",
"Share",
];
return toolTitles;
}
}

View File

@@ -1,23 +1,22 @@
import 'package:go_router/go_router.dart'; import 'package:go_router/go_router.dart';
import 'package:ken_logger/ken_logger.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.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_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_package_tools.dart';
import 'package:flutter/material.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_components/mih_pop_up_messages/mih_loading_circle.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_providers/mzansi_directory_provider.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_providers/mzansi_profile_provider.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_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_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_packages/mzansi_profile/business_profile/package_tools/mih_business_reviews.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_business_details_services.dart'; import 'package:mzansi_innovation_hub/mih_services/mih_business_details_services.dart';
import 'package:provider/provider.dart';
class MzansiBusinessProfileView extends StatefulWidget { class MzansiBusinessProfileView extends StatefulWidget {
final BusinessViewArguments? arguments;
final String? businessId; final String? businessId;
const MzansiBusinessProfileView({ const MzansiBusinessProfileView({
super.key, super.key,
required this.arguments,
required this.businessId, required this.businessId,
}); });
@@ -28,16 +27,10 @@ class MzansiBusinessProfileView extends StatefulWidget {
class _MzansiBusinessProfileViewState extends State<MzansiBusinessProfileView> { class _MzansiBusinessProfileViewState extends State<MzansiBusinessProfileView> {
int _selcetedIndex = 0; int _selcetedIndex = 0;
Business? business;
String startUpSearch = "";
Future<void> _fetchBusinessDetails() async { Future<void> _fetchBusinessDetails(
if (widget.arguments != null) { MzansiDirectoryProvider directoryProvider) async {
setState(() { if (widget.businessId != null) {
business = widget.arguments!.business;
startUpSearch = widget.arguments!.startUpSearch ?? "";
});
} else if (widget.businessId != null) {
final biz = await MihBusinessDetailsServices() final biz = await MihBusinessDetailsServices()
.getBusinessDetailsByBusinessId(widget.businessId!); .getBusinessDetailsByBusinessId(widget.businessId!);
if (biz == null) { if (biz == null) {
@@ -47,10 +40,7 @@ class _MzansiBusinessProfileViewState extends State<MzansiBusinessProfileView> {
); );
} else { } else {
KenLogger.success("Business found: ${biz.Name}"); KenLogger.success("Business found: ${biz.Name}");
setState(() { directoryProvider.setSelectedBusiness(business: biz);
business = biz;
startUpSearch = "";
});
} }
} }
} }
@@ -58,12 +48,17 @@ class _MzansiBusinessProfileViewState extends State<MzansiBusinessProfileView> {
@override @override
void initState() { void initState() {
super.initState(); super.initState();
_fetchBusinessDetails(); MzansiDirectoryProvider directoryProvider =
context.read<MzansiDirectoryProvider>();
_fetchBusinessDetails(directoryProvider);
} }
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
if (business == null) { return Consumer<MzansiDirectoryProvider>(
builder: (BuildContext context, MzansiDirectoryProvider directoryProvider,
Widget? child) {
if (directoryProvider.selectedBusiness == null) {
KenLogger.warning("Business is null, showing loading indicator"); KenLogger.warning("Business is null, showing loading indicator");
return Scaffold( return Scaffold(
body: const Center( body: const Center(
@@ -74,7 +69,7 @@ class _MzansiBusinessProfileViewState extends State<MzansiBusinessProfileView> {
return MihPackage( return MihPackage(
appActionButton: getAction(), appActionButton: getAction(),
appTools: getTools(), appTools: getTools(),
appBody: getToolBody(), appBody: getToolBody(directoryProvider),
appToolTitles: getToolTitle(), appToolTitles: getToolTitle(),
selectedbodyIndex: _selcetedIndex, selectedbodyIndex: _selcetedIndex,
onIndexChange: (newValue) { onIndexChange: (newValue) {
@@ -84,6 +79,8 @@ class _MzansiBusinessProfileViewState extends State<MzansiBusinessProfileView> {
}, },
); );
} }
},
);
} }
MihPackageAction getAction() { MihPackageAction getAction() {
@@ -91,13 +88,18 @@ class _MzansiBusinessProfileViewState extends State<MzansiBusinessProfileView> {
icon: const Icon(Icons.arrow_back), icon: const Icon(Icons.arrow_back),
iconSize: 35, iconSize: 35,
onTap: () { onTap: () {
MzansiProfileProvider profileProvider =
context.read<MzansiProfileProvider>();
if (profileProvider.user == null) {
context.goNamed( context.goNamed(
"mzansiDirectory", 'mihHome',
extra: MzansiDirectoryArguments(
personalSearch: false,
startSearchText: business!.Name,
),
); );
} else {
context.pop();
}
// context.goNamed(
// "mzansiDirectory",
// );
FocusScope.of(context).unfocus(); FocusScope.of(context).unfocus();
}, },
); );
@@ -126,16 +128,12 @@ class _MzansiBusinessProfileViewState extends State<MzansiBusinessProfileView> {
); );
} }
List<Widget> getToolBody() { List<Widget> getToolBody(MzansiDirectoryProvider directoryProvider) {
List<Widget> toolBodies = [ List<Widget> toolBodies = [
MihBusinessDetailsView( MihBusinessDetailsView(),
business: business!, MihBusinessReviews(business: directoryProvider.selectedBusiness!),
startUpSearch: startUpSearch,
),
MihBusinessReviews(business: business!),
MihBusinessQrCode( MihBusinessQrCode(
business: business!, business: directoryProvider.selectedBusiness!,
startUpSearch: startUpSearch,
) )
]; ];
return toolBodies; return toolBodies;

View File

@@ -0,0 +1,72 @@
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_components/mih_providers/mzansi_profile_provider.dart';
import 'package:mzansi_innovation_hub/mih_packages/mzansi_profile/business_profile/package_tools/mih_business_details_set_up.dart';
import 'package:provider/provider.dart';
class MzansiSetUpBusinessProfile extends StatefulWidget {
const MzansiSetUpBusinessProfile({super.key});
@override
State<MzansiSetUpBusinessProfile> createState() =>
_MzansiSetUpBusinessProfileState();
}
class _MzansiSetUpBusinessProfileState
extends State<MzansiSetUpBusinessProfile> {
@override
Widget build(BuildContext context) {
return MihPackage(
appActionButton: getAction(),
appTools: getTools(),
appBody: getToolBody(),
appToolTitles: getToolTitle(),
selectedbodyIndex: context.watch<MzansiProfileProvider>().businessIndex,
onIndexChange: (newIndex) {
context.read<MzansiProfileProvider>().setBusinessIndex(newIndex);
},
);
}
MihPackageAction getAction() {
return MihPackageAction(
icon: const Icon(Icons.arrow_back),
iconSize: 35,
onTap: () {
context.goNamed(
'mihHome',
);
FocusScope.of(context).unfocus();
context.read<MzansiProfileProvider>().setBusinessIndex(0);
},
);
}
MihPackageTools getTools() {
Map<Widget, void Function()?> temp = {};
temp[const Icon(Icons.business)] = () {
context.read<MzansiProfileProvider>().setBusinessIndex(0);
};
return MihPackageTools(
tools: temp,
selcetedIndex: context.watch<MzansiProfileProvider>().businessIndex,
);
}
List<String> getToolTitle() {
List<String> toolTitles = [
"Set Up Profile",
];
return toolTitles;
}
List<Widget> getToolBody() {
List<Widget> toolBodies = [
MihBusinessDetailsSetUp(),
];
return toolBodies;
}
}

View File

@@ -2,16 +2,13 @@ import 'package:go_router/go_router.dart';
import 'package:mzansi_innovation_hub/main.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_package_tile.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_icons.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_objects/arguments.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart'; import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart';
class MzansiBusinessProfileTile extends StatefulWidget { class MzansiBusinessProfileTile extends StatefulWidget {
final BusinessArguments arguments;
final double packageSize; final double packageSize;
const MzansiBusinessProfileTile({ const MzansiBusinessProfileTile({
super.key, super.key,
required this.arguments,
required this.packageSize, required this.packageSize,
}); });
@@ -27,7 +24,6 @@ class _MzansiBusinessProfileTileState extends State<MzansiBusinessProfileTile> {
onTap: () { onTap: () {
context.goNamed( context.goNamed(
"businessProfileManage", "businessProfileManage",
extra: widget.arguments,
); );
// Navigator.of(context).pushNamed( // Navigator.of(context).pushNamed(
// '/business-profile/manage', // '/business-profile/manage',

View File

@@ -2,16 +2,15 @@ import 'package:go_router/go_router.dart';
import 'package:mzansi_innovation_hub/main.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_package_tile.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_icons.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_objects/app_user.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_providers/mzansi_profile_provider.dart';
import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart'; import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart';
import 'package:provider/provider.dart';
class MzansiSetupBusinessProfileTile extends StatefulWidget { class MzansiSetupBusinessProfileTile extends StatefulWidget {
final AppUser signedInUser;
final double packageSize; final double packageSize;
const MzansiSetupBusinessProfileTile({ const MzansiSetupBusinessProfileTile({
super.key, super.key,
required this.signedInUser,
required this.packageSize, required this.packageSize,
}); });
@@ -24,11 +23,13 @@ class _MzansiSetupBusinessProfileTileState
extends State<MzansiSetupBusinessProfileTile> { extends State<MzansiSetupBusinessProfileTile> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
MzansiProfileProvider profileProvider =
context.read<MzansiProfileProvider>();
return MihPackageTile( return MihPackageTile(
onTap: () { onTap: () {
context.goNamed( context.goNamed(
'businessProfileSetup', 'businessProfileSetup',
extra: widget.signedInUser, extra: profileProvider.user,
); );
// Navigator.of(context).pushNamed( // Navigator.of(context).pushNamed(
// '/business-profile/set-up', // '/business-profile/set-up',

View File

@@ -1,35 +1,19 @@
import 'package:country_code_picker/country_code_picker.dart';
import 'package:file_picker/file_picker.dart'; import 'package:file_picker/file_picker.dart';
import 'package:flutter/material.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/main.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_window.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_providers/mzansi_profile_provider.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_colors.dart';
import 'package:mzansi_innovation_hub/mih_packages/mzansi_profile/business_profile/components/mih_business_info_card.dart'; import 'package:mzansi_innovation_hub/mih_packages/mzansi_profile/business_profile/components/mih_business_info_card.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_alert_services.dart'; import 'package:mzansi_innovation_hub/mih_packages/mzansi_profile/business_profile/components/mih_update_business_details_window.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_business_details_services.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_file_services.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_location_services.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_validation_services.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_single_child_scroll.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_single_child_scroll.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_button.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_button.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_form.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_tool_body.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_tool_body.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_alert.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_circle_avatar.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_circle_avatar.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_text_form_field.dart'; import 'package:provider/provider.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_error_message.dart';
import 'package:mzansi_innovation_hub/mih_config/mih_env.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_objects/arguments.dart';
class MihBusinessDetails extends StatefulWidget { class MihBusinessDetails extends StatefulWidget {
final BusinessArguments arguments;
final ImageProvider<Object>? logoImage;
const MihBusinessDetails({ const MihBusinessDetails({
super.key, super.key,
required this.arguments,
required this.logoImage,
}); });
@override @override
@@ -37,695 +21,25 @@ class MihBusinessDetails extends StatefulWidget {
} }
class _MihBusinessDetailsState extends State<MihBusinessDetails> { class _MihBusinessDetailsState extends State<MihBusinessDetails> {
PlatformFile? imageFile; PlatformFile? newSelectedLogoPic;
final fileNameController = TextEditingController(); final fileNameController = TextEditingController();
final regController = TextEditingController();
final nameController = TextEditingController();
final typeController = TextEditingController();
final practiceNoController = TextEditingController();
final vatNoController = TextEditingController();
final countryCodeController = TextEditingController();
final contactController = TextEditingController();
final emailController = TextEditingController();
final locationController = TextEditingController();
final websiteController = TextEditingController();
final ratingController = TextEditingController();
final missionVisionController = TextEditingController();
final _formKey = GlobalKey<FormState>();
final ValueNotifier<int> _counter = ValueNotifier<int>(0);
late String env;
void successPopUp(String message, bool stayOnPersonalSide) { void editBizProfileWindow(
MzansiProfileProvider mzansiProfileProvider, double width) {
showDialog( showDialog(
context: context, context: context,
builder: (context) { builder: (context) => MihUpdateBusinessDetailsWindow(width: width),
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<void> submitForm() async {
if (isFormFilled()) {
int statusCode = 0;
statusCode = await MihBusinessDetailsServices().updateBusinessDetailsV2(
widget.arguments.business!.business_id,
nameController.text,
typeController.text,
regController.text,
practiceNoController.text,
vatNoController.text,
emailController.text,
getNumberWithCountryCode(),
// contactController.text,
locationController.text,
fileNameController.text,
websiteController.text,
ratingController.text.isEmpty ? "0" : ratingController.text,
missionVisionController.text,
context,
);
if (statusCode == 200) {
bool successfullyUploadedFile = await uploadFile();
if (successfullyUploadedFile) {
//You left of here
String message = "Your information has been updated successfully!";
successPopUp(message, false);
// File uploaded successfully
} else {
// File upload failed
showDialog(
context: context,
builder: (context) {
return MihPackageAlert(
alertIcon: Icon(
Icons.warning_rounded,
color: MihColors.getRedColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
),
alertTitle: "Error Updating Business Details",
alertBody: Column(
children: [
Text(
"An error occurred while updating the business details. Please check internet connection and try again.",
style: TextStyle(
color: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
),
),
],
),
alertColour: MihColors.getRedColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
);
},
);
}
} else {
showDialog(
context: context,
builder: (context) {
return const MIHErrorMessage(errorType: "Internet Connection");
},
);
}
} else {
showDialog(
context: context,
builder: (context) {
return const MIHErrorMessage(errorType: "Input Error");
},
);
}
}
Future<bool> uploadFile() async {
if (imageFile != null) {
int uploadStatusCode = 0;
uploadStatusCode = await MihFileApi.uploadFile(
widget.arguments.business!.business_id,
env,
"business_files",
imageFile!,
context,
);
if (uploadStatusCode == 200) {
int deleteStatusCode = 0;
deleteStatusCode = await MihFileApi.deleteFile(
widget.arguments.business!.logo_path.split("/").first,
env,
"business_files",
widget.arguments.business!.logo_path.split("/").last,
context,
);
if (deleteStatusCode == 200) {
return true;
} else {
return false;
}
} else {
return false;
}
} else {
return true; // No file selected, so no upload needed
}
}
bool isFileSelected() {
if (imageFile != null) {
return true;
} else {
return false;
}
}
bool isEmailValid() {
String text = emailController.text;
var regex = RegExp(r'^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$');
return regex.hasMatch(text);
}
bool isFormFilled() {
if (typeController.text.isEmpty) {
return false;
} else {
return true;
}
}
void setContactNumberControllers() {
if (widget.arguments.business!.contact_no[0] == "+") {
List<String> contactDetails =
widget.arguments.business!.contact_no.split("-");
setState(() {
countryCodeController.text = contactDetails[0];
contactController.text = contactDetails[1];
});
} else {
setState(() {
countryCodeController.text = "+27";
contactController.text = widget.arguments.business!.contact_no;
});
}
}
String getNumberWithCountryCode() {
String numberWithoutBeginingZero = "";
if (contactController.text[0] == "0") {
numberWithoutBeginingZero = contactController.text
.replaceAll(" ", "")
.substring(1, contactController.text.length);
} else {
numberWithoutBeginingZero = contactController.text.replaceAll("-", " ");
}
return "${countryCodeController.text}-$numberWithoutBeginingZero";
}
void editBizProfileWindow(double width) {
showDialog(
context: context,
builder: (context) => MihPackageWindow(
fullscreen: false,
windowTitle: 'Edit Profile',
onWindowTapClose: () {
context.pop();
resetControllers();
},
windowBody: MihSingleChildScroll(
child: Padding(
padding: MzansiInnovationHub.of(context)!.theme.screenType ==
"desktop"
? EdgeInsets.symmetric(horizontal: width * 0.05)
: EdgeInsets.symmetric(horizontal: width * 0),
child: Column(
children: [
MihForm(
formKey: _formKey,
formFields: [
Center(
child: MihCircleAvatar(
imageFile: widget.logoImage,
width: 150,
editable: true,
fileNameController: fileNameController,
userSelectedfile: imageFile,
frameColor: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
backgroundColor: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
onChange: (selectedfile) {
setState(() {
imageFile = selectedfile;
});
},
),
),
Visibility(
visible: false,
child: MihTextFormField(
fillColor: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
inputColor: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
controller: fileNameController,
multiLineInput: false,
requiredText: true,
readOnly: true,
hintText: "Selected File Name",
),
),
const SizedBox(height: 20),
MihTextFormField(
fillColor: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
inputColor: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
controller: nameController,
multiLineInput: false,
requiredText: true,
hintText: "Business Name",
validator: (value) {
return MihValidationServices().isEmpty(value);
},
),
const SizedBox(height: 10),
MihTextFormField(
fillColor: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
inputColor: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
controller: typeController,
multiLineInput: false,
requiredText: true,
hintText: "Business Type",
validator: (value) {
return MihValidationServices().isEmpty(value);
},
),
const SizedBox(height: 10),
MihTextFormField(
fillColor: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
inputColor: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
controller: emailController,
multiLineInput: false,
requiredText: true,
hintText: "Business Email",
validator: (value) {
return MihValidationServices()
.validateEmail(value);
},
),
const SizedBox(height: 10),
Container(
width: 300,
alignment: Alignment.topLeft,
child: const Text(
"Contact Number:",
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
),
Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
CountryCodePicker(
padding: EdgeInsetsGeometry.all(0),
onChanged: (selectedCode) {
setState(() {
countryCodeController.text =
selectedCode.toString();
});
debugPrint(
"Selected Country Code: ${countryCodeController.text}");
},
initialSelection: countryCodeController.text,
showDropDownButton: false,
pickerStyle: PickerStyle.bottomSheet,
dialogBackgroundColor:
MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!
.theme
.mode ==
"Dark"),
barrierColor: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!
.theme
.mode ==
"Dark"),
),
Expanded(
child: MihTextFormField(
fillColor: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!
.theme
.mode ==
"Dark"),
inputColor: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!
.theme
.mode ==
"Dark"),
controller: contactController,
numberMode: true,
multiLineInput: false,
requiredText: true,
hintText: null,
validator: (value) {
return MihValidationServices()
.isEmpty(value);
},
),
),
],
),
const SizedBox(height: 10),
MihTextFormField(
height: 250,
fillColor: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
inputColor: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
controller: missionVisionController,
multiLineInput: true,
requiredText: true,
hintText: "Business Mission & Vision",
validator: (value) {
return MihValidationServices().validateLength(
missionVisionController.text, 256);
},
),
SizedBox(
height: 15,
child: ValueListenableBuilder(
valueListenable: _counter,
builder: (BuildContext context, int value,
Widget? child) {
return Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.end,
children: [
Text(
"$value",
style: TextStyle(
color: getMissionVisionLimitColor(256),
fontWeight: FontWeight.bold,
),
),
const SizedBox(width: 5),
Text(
"/256",
style: TextStyle(
color: getMissionVisionLimitColor(256),
fontWeight: FontWeight.bold,
),
),
],
);
},
),
),
const SizedBox(height: 10.0),
MihTextFormField(
fillColor: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
inputColor: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
controller: websiteController,
multiLineInput: false,
requiredText: false,
hintText: "Business Website",
validator: (value) {
return MihValidationServices()
.validateWebsite(value, false);
},
),
const SizedBox(height: 10),
MihTextFormField(
fillColor: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
inputColor: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
controller: regController,
multiLineInput: false,
requiredText: false,
hintText: "Registration No.",
validator: (value) {
// return MihValidationServices().isEmpty(value);
return null;
},
),
const SizedBox(height: 10),
MihTextFormField(
fillColor: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
inputColor: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
controller: practiceNoController,
multiLineInput: false,
requiredText: false,
hintText: "Practice Number",
validator: (validateValue) {
return null;
},
),
const SizedBox(height: 10),
MihTextFormField(
fillColor: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
inputColor: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
controller: vatNoController,
multiLineInput: false,
requiredText: false,
hintText: "VAT Number",
validator: (value) {
// return MihValidationServices().isEmpty(value);
return null;
},
),
const SizedBox(height: 10),
Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Flexible(
child: MihTextFormField(
fillColor: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!
.theme
.mode ==
"Dark"),
inputColor: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!
.theme
.mode ==
"Dark"),
controller: locationController,
multiLineInput: false,
requiredText: true,
readOnly: true,
hintText: "GPS Location",
),
),
const SizedBox(width: 10.0),
MihButton(
onPressed: () {
showDialog(
context: context,
builder: (context) {
return const Mihloadingcircle(
message: "Getting your location",
);
},
);
MIHLocationAPI()
.getGPSPosition(context)
.then((position) {
if (position != null) {
setState(() {
locationController.text =
"${position.latitude}, ${position.longitude}";
});
}
//Dismiss loading indicator
Navigator.of(context).pop();
});
},
buttonColor: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!
.theme
.mode ==
"Dark"),
width: 100,
child: Text(
"Set",
style: TextStyle(
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!
.theme
.mode ==
"Dark"),
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
),
],
),
const SizedBox(height: 25),
Center(
child: MihButton(
onPressed: () {
if (_formKey.currentState!.validate()) {
submitForm();
} else {
MihAlertServices()
.formNotFilledCompletely(context);
}
},
buttonColor: MihColors.getGreenColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
width: 300,
child: Text(
"Update",
style: TextStyle(
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!
.theme
.mode ==
"Dark"),
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
),
),
const SizedBox(height: 20),
],
),
],
),
),
),
));
}
Color getMissionVisionLimitColor(int limit) {
if (_counter.value <= limit) {
return MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark");
} else {
return MihColors.getRedColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark");
}
}
void resetControllers() {
setState(() {
fileNameController.text =
widget.arguments.business!.logo_path.split("/").last;
regController.text = widget.arguments.business!.registration_no;
nameController.text = widget.arguments.business!.Name;
typeController.text = widget.arguments.business!.type;
practiceNoController.text = widget.arguments.business!.practice_no;
vatNoController.text = widget.arguments.business!.vat_no;
emailController.text = widget.arguments.business!.bus_email;
locationController.text = widget.arguments.business!.gps_location;
websiteController.text = widget.arguments.business!.website;
ratingController.text = widget.arguments.business!.rating;
missionVisionController.text = widget.arguments.business!.mission_vision;
});
setContactNumberControllers();
if (AppEnviroment.getEnv() == "Prod") {
env = "Prod";
} else {
env = "Dev";
}
missionVisionController.addListener(() {
setState(() {
_counter.value = missionVisionController.text.characters.length;
});
});
} }
@override @override
void dispose() { void dispose() {
super.dispose(); super.dispose();
fileNameController.dispose();
regController.dispose();
nameController.dispose();
typeController.dispose();
practiceNoController.dispose();
vatNoController.dispose();
contactController.dispose();
emailController.dispose();
locationController.dispose();
websiteController.dispose();
ratingController.dispose();
missionVisionController.dispose();
imageFile = null;
} }
@override @override
void initState() { void initState() {
super.initState(); super.initState();
resetControllers();
} }
@override @override
@@ -739,37 +53,42 @@ class _MihBusinessDetailsState extends State<MihBusinessDetails> {
} }
Widget getBody(double width, BuildContext context) { Widget getBody(double width, BuildContext context) {
return Consumer<MzansiProfileProvider>(
builder: (BuildContext context,
MzansiProfileProvider mzansiProfileProvider, Widget? child) {
return Stack( return Stack(
children: [ children: [
MihSingleChildScroll( MihSingleChildScroll(
child: Padding( child: Padding(
padding: padding: MzansiInnovationHub.of(context)!.theme.screenType ==
MzansiInnovationHub.of(context)!.theme.screenType == "desktop" "desktop"
? EdgeInsets.symmetric(horizontal: width * 0.2) ? EdgeInsets.symmetric(horizontal: width * 0.2)
: EdgeInsets.symmetric(horizontal: width * 0.075), : EdgeInsets.symmetric(horizontal: width * 0.075),
child: Column( child: Column(
children: [ children: [
Center( Center(
child: MihCircleAvatar( child: MihCircleAvatar(
imageFile: widget.logoImage, imageFile: mzansiProfileProvider.businessProfilePicture,
width: 150, width: 150,
editable: false, editable: false,
fileNameController: fileNameController, fileNameController: fileNameController,
userSelectedfile: imageFile, userSelectedfile: newSelectedLogoPic,
frameColor: MihColors.getSecondaryColor( frameColor: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"), MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
backgroundColor: MihColors.getPrimaryColor( backgroundColor: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"), MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
onChange: (selectedfile) { onChange: (selectedfile) {
setState(() { setState(() {
imageFile = selectedfile; newSelectedLogoPic = selectedfile;
}); });
}, },
), ),
), ),
FittedBox( FittedBox(
child: Text( child: Text(
widget.arguments.business!.Name, mzansiProfileProvider.business!.Name,
style: TextStyle( style: TextStyle(
fontSize: 35, fontSize: 35,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
@@ -781,7 +100,7 @@ class _MihBusinessDetailsState extends State<MihBusinessDetails> {
), ),
FittedBox( FittedBox(
child: Text( child: Text(
widget.arguments.business!.type, mzansiProfileProvider.business!.type,
style: TextStyle( style: TextStyle(
fontSize: 20, fontSize: 20,
fontWeight: FontWeight.w600, fontWeight: FontWeight.w600,
@@ -792,24 +111,13 @@ class _MihBusinessDetailsState extends State<MihBusinessDetails> {
), ),
), ),
const SizedBox(height: 5), const SizedBox(height: 5),
// FittedBox(
// child: Text(
// "Mission & Vision",
// style: TextStyle(
// fontSize: 15,
// fontWeight: FontWeight.bold,
// color: MzansiInnovationHub.of(context)!
// .theme
// .secondaryColor(),
// ),
// ),
// ),
Center( Center(
child: SizedBox( child: SizedBox(
width: 700, width: 700,
child: Text( child: Text(
widget.arguments.business!.mission_vision.isNotEmpty mzansiProfileProvider
? widget.arguments.business!.mission_vision .business!.mission_vision.isNotEmpty
? mzansiProfileProvider.business!.mission_vision
: "No Mission & Vision added yet", : "No Mission & Vision added yet",
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: TextStyle( style: TextStyle(
@@ -826,17 +134,8 @@ class _MihBusinessDetailsState extends State<MihBusinessDetails> {
SizedBox( SizedBox(
width: 700, width: 700,
child: MihBusinessCard( child: MihBusinessCard(
// businessid: widget.arguments.business!.business_id, business: mzansiProfileProvider.business!,
// businessName: widget.arguments.business!.Name, // startUpSearch: null,
// cellNumber: widget.arguments.business!.contact_no,
// email: widget.arguments.business!.bus_email,
// gpsLocation: widget.arguments.business!.gps_location,
// rating: widget.arguments.business!.rating.isNotEmpty
// ? double.parse(widget.arguments.business!.rating)
// : 0,
// website: widget.arguments.business!.website,
business: widget.arguments.business!,
startUpSearch: null,
width: width, width: width,
), ),
), ),
@@ -845,10 +144,11 @@ class _MihBusinessDetailsState extends State<MihBusinessDetails> {
child: MihButton( child: MihButton(
onPressed: () { onPressed: () {
// Connect with the user // Connect with the user
editBizProfileWindow(width); editBizProfileWindow(mzansiProfileProvider, width);
}, },
buttonColor: MihColors.getGreenColor( buttonColor: MihColors.getGreenColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"), MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
width: 300, width: 300,
child: Text( child: Text(
"Edit Profile", "Edit Profile",
@@ -895,5 +195,7 @@ class _MihBusinessDetailsState extends State<MihBusinessDetails> {
// ), // ),
], ],
); );
},
);
} }
} }

View File

@@ -1,53 +1,43 @@
import 'dart:convert';
import 'package:country_code_picker/country_code_picker.dart'; import 'package:country_code_picker/country_code_picker.dart';
import 'package:file_picker/file_picker.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:go_router/go_router.dart'; import 'package:go_router/go_router.dart';
import 'package:http/http.dart'; import 'package:http/http.dart';
import 'package:mzansi_innovation_hub/main.dart'; import 'package:mzansi_innovation_hub/main.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_button.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_circle_avatar.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_form.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_image_display.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_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_components/mih_pop_up_messages/mih_loading_circle.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_providers/mzansi_profile_provider.dart';
import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart'; import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart';
import 'package:mzansi_innovation_hub/mih_config/mih_env.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_alert_services.dart'; import 'package:mzansi_innovation_hub/mih_services/mih_alert_services.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_business_details_services.dart'; import 'package:mzansi_innovation_hub/mih_services/mih_business_details_services.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_file_services.dart'; import 'package:mzansi_innovation_hub/mih_services/mih_file_services.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_location_services.dart'; import 'package:mzansi_innovation_hub/mih_services/mih_location_services.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_my_business_user_services.dart'; import 'package:mzansi_innovation_hub/mih_services/mih_my_business_user_services.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_validation_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:provider/provider.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_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_config/mih_env.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_objects/app_user.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:file_picker/file_picker.dart';
class ProfileBusinessAdd extends StatefulWidget { class MihBusinessDetailsSetUp extends StatefulWidget {
//final BusinessUserScreenArguments arguments; const MihBusinessDetailsSetUp({super.key});
final AppUser signedInUser;
const ProfileBusinessAdd({
super.key,
required this.signedInUser,
});
@override @override
State<ProfileBusinessAdd> createState() => _ProfileBusinessAddState(); State<MihBusinessDetailsSetUp> createState() =>
_MihBusinessDetailsSetUpState();
} }
class _ProfileBusinessAddState extends State<ProfileBusinessAdd> { class _MihBusinessDetailsSetUpState extends State<MihBusinessDetailsSetUp> {
final FocusNode _focusNode = FocusNode();
final baseAPI = AppEnviroment.baseApiUrl;
final nameController = TextEditingController(); final nameController = TextEditingController();
final typeController = TextEditingController(); final typeController = TextEditingController();
final regController = TextEditingController(); final regController = TextEditingController();
final addressController = TextEditingController(); final addressController = TextEditingController();
final logonameController = TextEditingController();
final fnameController = TextEditingController(); final fnameController = TextEditingController();
final lnameController = TextEditingController(); final lnameController = TextEditingController();
final titleController = TextEditingController(); final titleController = TextEditingController();
@@ -62,65 +52,33 @@ class _ProfileBusinessAddState extends State<ProfileBusinessAdd> {
final websiteController = TextEditingController(); final websiteController = TextEditingController();
final ratingController = TextEditingController(); final ratingController = TextEditingController();
final missionVisionController = TextEditingController(); final missionVisionController = TextEditingController();
final logoFileNameController = TextEditingController();
ImageProvider<Object>? logoPreview; PlatformFile? newSelectedLogoPic;
ImageProvider<Object>? signaturePreview; PlatformFile? newSelectedSignaturePic;
PlatformFile? selectedLogo; final FocusNode _focusNode = FocusNode();
PlatformFile? selectedSignature; final _formKey = GlobalKey<FormState>();
final ValueNotifier<int> _counter = ValueNotifier<int>(0); final ValueNotifier<int> _counter = ValueNotifier<int>(0);
final ValueNotifier<String> busType = ValueNotifier(""); final ValueNotifier<String> busType = ValueNotifier("");
final _formKey = GlobalKey<FormState>();
late String env; late String env;
Future<bool> uploadFile(String id, PlatformFile? selectedFile) async { void submitForm(MzansiProfileProvider mzansiProfileProvider) {
print("Inside uploud file method"); if (isFieldsFilled()) {
int uploadStatusCode = 0; createBusinessProfileAPICall(mzansiProfileProvider);
uploadStatusCode = await MihFileApi.uploadFile(
id,
env,
"business_files",
selectedFile,
context,
);
print("Status code: $uploadStatusCode");
if (uploadStatusCode == 200) {
return true;
} else { } else {
return false; showDialog(
context: context,
builder: (context) {
return const MIHErrorMessage(errorType: "Input Error");
},
);
} }
} }
Future<void> createBusinessUserAPICall(String business_id) async { Future<void> createBusinessProfileAPICall(
print("Inside create bus user method"); MzansiProfileProvider mzansiProfileProvider) async {
int statusCode = await MihMyBusinessUserServices().createBusinessUser(
business_id,
widget.signedInUser.app_id,
signtureController.text,
titleController.text,
accessController.text,
context,
);
print("Status code: $statusCode");
if (statusCode == 201) {
// 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, false);
} else {
internetConnectionPopUp();
}
}
Future<void> createBusinessProfileAPICall() async {
print("Inside create business profile method");
Response response = Response response =
await MihBusinessDetailsServices().createBusinessDetails( await MihBusinessDetailsServices().createBusinessDetails(
widget.signedInUser.app_id, mzansiProfileProvider,
nameController.text, nameController.text,
typeController.text, typeController.text,
regController.text, regController.text,
@@ -128,23 +86,87 @@ class _ProfileBusinessAddState extends State<ProfileBusinessAdd> {
vatNoController.text, vatNoController.text,
emailController.text, emailController.text,
getNumberWithCountryCode(), getNumberWithCountryCode(),
// "${countryCodeController.text}-${contactController.text}",
locationController.text, locationController.text,
logonameController.text, logoFileNameController.text,
websiteController.text, websiteController.text,
"0", "0",
missionVisionController.text, missionVisionController.text,
context, context,
); );
print(response.body);
if (response.statusCode == 201) { if (response.statusCode == 201) {
var businessResponse = jsonDecode(response.body); bool successUpload =
createBusinessUserAPICall(businessResponse['business_id']); await uploadFile(mzansiProfileProvider, newSelectedLogoPic);
if (successUpload) {
String logoUrl = await MihFileApi.getMinioFileUrl(
mzansiProfileProvider.business!.logo_path, context);
mzansiProfileProvider.setBusinessProfilePicUrl(logoUrl);
}
await createBusinessUserAPICall(mzansiProfileProvider);
} else { } else {
internetConnectionPopUp(); internetConnectionPopUp();
} }
} }
Future<void> createBusinessUserAPICall(
MzansiProfileProvider mzansiProfileProvider) async {
int statusCode = await MihMyBusinessUserServices().createBusinessUser(
mzansiProfileProvider.business!.business_id,
mzansiProfileProvider.user!.app_id,
signtureController.text,
titleController.text,
accessController.text,
mzansiProfileProvider,
context,
);
if (statusCode == 201) {
bool successUpload =
await uploadFile(mzansiProfileProvider, newSelectedSignaturePic);
if (successUpload) {
String sigUrl = await MihFileApi.getMinioFileUrl(
mzansiProfileProvider.businessUser!.sig_path, context);
mzansiProfileProvider.setBusinessUserSignatureUrl(sigUrl);
String message =
"Your business profile is now live! You can now start connecting with customers and growing your business.";
successPopUp(message, false);
} else {
internetConnectionPopUp();
}
} else {
internetConnectionPopUp();
}
}
Future<bool> uploadFile(
MzansiProfileProvider mzansiProfileProvider, PlatformFile? image) async {
if (newSelectedLogoPic != null) {
int uploadStatusCode = 0;
uploadStatusCode = await MihFileApi.uploadFile(
mzansiProfileProvider.business!.business_id,
env,
"business_files",
image,
context,
);
if (uploadStatusCode == 200) {
return true;
} else {
return false;
}
} else {
return true; // No file selected, so no upload needed
}
}
bool isFieldsFilled() {
if (typeController.text.isEmpty ||
titleController.text.isEmpty ||
accessController.text.isEmpty) {
return false;
} else {
return true;
}
}
String getNumberWithCountryCode() { String getNumberWithCountryCode() {
String numberWithoutBeginingZero = ""; String numberWithoutBeginingZero = "";
if (contactController.text[0] == "0") { if (contactController.text[0] == "0") {
@@ -157,13 +179,22 @@ class _ProfileBusinessAddState extends State<ProfileBusinessAdd> {
return "${countryCodeController.text}-$numberWithoutBeginingZero"; return "${countryCodeController.text}-$numberWithoutBeginingZero";
} }
void internetConnectionPopUp() { Color getMissionVisionLimitColor(int limit) {
showDialog( if (_counter.value <= limit) {
context: context, return MihColors.getSecondaryColor(
builder: (context) { MzansiInnovationHub.of(context)!.theme.mode == "Dark");
return const MIHErrorMessage(errorType: "Internet Connection"); } else {
}, return MihColors.getRedColor(
); MzansiInnovationHub.of(context)!.theme.mode == "Dark");
}
}
void typeSelected() {
if (typeController.text.isNotEmpty) {
busType.value = typeController.text;
} else {
busType.value = "";
}
} }
void successPopUp(String message, bool stayOnPersonalSide) { void successPopUp(String message, bool stayOnPersonalSide) {
@@ -227,110 +258,90 @@ class _ProfileBusinessAddState extends State<ProfileBusinessAdd> {
); );
} }
bool isFieldsFilled() { void internetConnectionPopUp() {
if (typeController.text.isEmpty ||
titleController.text.isEmpty ||
accessController.text.isEmpty) {
return false;
} else {
return true;
}
}
void submitForm() {
if (isFieldsFilled()) {
print("Inside submit method");
createBusinessProfileAPICall();
} else {
showDialog( showDialog(
context: context, context: context,
builder: (context) { builder: (context) {
return const MIHErrorMessage(errorType: "Input Error"); return const MIHErrorMessage(errorType: "Internet Connection");
},
);
}
}
void emailError() {
showDialog(
context: context,
builder: (context) {
return const MIHErrorMessage(errorType: "Invalid Email");
}, },
); );
} }
bool isEmailValid() { void initialiseControlers(MzansiProfileProvider mzansiProfileProvider) {
String text = emailController.text; typeController.addListener(typeSelected);
var regex = RegExp(r'^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$'); setState(() {
return regex.hasMatch(text); fnameController.text = mzansiProfileProvider.user!.fname;
} lnameController.text = mzansiProfileProvider.user!.lname;
accessController.text = "Full";
// bool validEmail() { countryCodeController.text = "+27";
// String text = emailController.text; });
// var regex = RegExp(r'^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$'); if (AppEnviroment.getEnv() == "Prod") {
// return regex.hasMatch(text); env = "Prod";
// }
void typeSelected() {
if (typeController.text.isNotEmpty) {
busType.value = typeController.text;
} else { } else {
busType.value = ""; env = "Dev";
} }
missionVisionController.addListener(() {
setState(() {
_counter.value = missionVisionController.text.characters.length;
});
});
} }
MIHAction getActionButton() { @override
return MIHAction( void dispose() {
icon: const Icon(Icons.arrow_back), typeController.removeListener(typeSelected);
iconSize: 35, nameController.dispose();
onTap: () { typeController.dispose();
// Navigator.of(context).pop(); regController.dispose();
context.goNamed( addressController.dispose();
'mihHome', fnameController.dispose();
extra: true, lnameController.dispose();
); titleController.dispose();
}, signtureController.dispose();
); accessController.dispose();
countryCodeController.dispose();
contactController.dispose();
emailController.dispose();
locationController.dispose();
practiceNoController.dispose();
vatNoController.dispose();
websiteController.dispose();
ratingController.dispose();
missionVisionController.dispose();
logoFileNameController.dispose();
busType.dispose();
_focusNode.dispose();
_counter.dispose();
super.dispose();
} }
MIHHeader getHeader() { @override
return const MIHHeader( void initState() {
headerAlignment: MainAxisAlignment.center, super.initState();
headerItems: [ initialiseControlers(context.read<MzansiProfileProvider>());
Text(
"Set Up Business Profile",
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 25,
),
),
],
);
} }
Color getMissionVisionLimitColor(int limit) { @override
if (_counter.value <= limit) { Widget build(BuildContext context) {
return MihColors.getSecondaryColor( double screenWidth = MediaQuery.of(context).size.width;
MzansiInnovationHub.of(context)!.theme.mode == "Dark"); return MihPackageToolBody(
} else {
return MihColors.getRedColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark");
}
}
MIHBody getBody(double width) {
return MIHBody(
borderOn: false, borderOn: false,
bodyItems: [ bodyItem: getBody(screenWidth),
KeyboardListener( );
}
Widget getBody(double width) {
return Consumer<MzansiProfileProvider>(
builder: (BuildContext context,
MzansiProfileProvider mzansiProfileProvider, Widget? child) {
return KeyboardListener(
focusNode: _focusNode, focusNode: _focusNode,
autofocus: true, autofocus: true,
onKeyEvent: (event) async { onKeyEvent: (event) async {
if (event is KeyDownEvent && if (event is KeyDownEvent &&
event.logicalKey == LogicalKeyboardKey.enter) { event.logicalKey == LogicalKeyboardKey.enter) {
if (_formKey.currentState!.validate()) { if (_formKey.currentState!.validate()) {
submitForm(); submitForm(mzansiProfileProvider);
} else { } else {
MihAlertServices().formNotFilledCompletely(context); MihAlertServices().formNotFilledCompletely(context);
} }
@@ -345,7 +356,7 @@ class _ProfileBusinessAddState extends State<ProfileBusinessAdd> {
child: Column( child: Column(
children: [ children: [
const Text( const Text(
"My Business Details", "Business Details",
style: TextStyle( style: TextStyle(
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
fontSize: 25, fontSize: 25,
@@ -359,6 +370,29 @@ class _ProfileBusinessAddState extends State<ProfileBusinessAdd> {
MihForm( MihForm(
formKey: _formKey, formKey: _formKey,
formFields: [ formFields: [
Center(
child: MihCircleAvatar(
imageFile: newSelectedLogoPic != null
? MemoryImage(newSelectedLogoPic!.bytes!)
: mzansiProfileProvider.businessProfilePicture,
width: 150,
editable: true,
fileNameController: logoFileNameController,
userSelectedfile: newSelectedLogoPic,
frameColor: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
backgroundColor: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
onChange: (selectedfile) {
setState(() {
newSelectedLogoPic = selectedfile;
});
},
),
),
const SizedBox(height: 20),
MihTextFormField( MihTextFormField(
fillColor: MihColors.getSecondaryColor( fillColor: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == MzansiInnovationHub.of(context)!.theme.mode ==
@@ -387,7 +421,8 @@ class _ProfileBusinessAddState extends State<ProfileBusinessAdd> {
requiredText: true, requiredText: true,
hintText: "Business Type", hintText: "Business Type",
validator: (value) { validator: (value) {
return MihValidationServices().isEmpty(value); return MihValidationServices()
.validateNoSpecialChars(value);
}, },
), ),
const SizedBox(height: 10.0), const SizedBox(height: 10.0),
@@ -643,7 +678,7 @@ class _ProfileBusinessAddState extends State<ProfileBusinessAdd> {
//const SizedBox(height: 15.0), //const SizedBox(height: 15.0),
const Center( const Center(
child: Text( child: Text(
"My Business User", "Business User",
style: TextStyle( style: TextStyle(
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
fontSize: 22, fontSize: 22,
@@ -715,7 +750,7 @@ class _ProfileBusinessAddState extends State<ProfileBusinessAdd> {
return MihValidationServices().isEmpty(value); return MihValidationServices().isEmpty(value);
}, },
), ),
const SizedBox(height: 15.0), const SizedBox(height: 10.0),
MihTextFormField( MihTextFormField(
fillColor: MihColors.getSecondaryColor( fillColor: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == MzansiInnovationHub.of(context)!.theme.mode ==
@@ -732,23 +767,41 @@ class _ProfileBusinessAddState extends State<ProfileBusinessAdd> {
return MihValidationServices().isEmpty(value); return MihValidationServices().isEmpty(value);
}, },
), ),
// MihDropdownField( const SizedBox(height: 10),
// controller: accessController, Container(
// hintText: "Access Type", width: 300,
// dropdownOptions: const ["Full", "Partial"], alignment: Alignment.topLeft,
// editable: false, child: const Text(
// enableSearch: true, "Signature:",
// validator: (value) { style: TextStyle(
// return MihValidationServices().isEmpty(value); fontSize: 18,
// }, fontWeight: FontWeight.bold,
// requiredText: true, ),
// ), ),
),
Center(
child: MihImageDisplay(
imageFile: newSelectedSignaturePic != null
? MemoryImage(newSelectedSignaturePic!.bytes!)
: mzansiProfileProvider.businessUserSignature,
width: 300,
height: 200,
editable: true,
fileNameController: signtureController,
userSelectedfile: newSelectedSignaturePic,
onChange: (selectedFile) {
setState(() {
newSelectedSignaturePic = selectedFile;
});
},
),
),
const SizedBox(height: 20.0), const SizedBox(height: 20.0),
Center( Center(
child: MihButton( child: MihButton(
onPressed: () { onPressed: () {
if (_formKey.currentState!.validate()) { if (_formKey.currentState!.validate()) {
submitForm(); submitForm(mzansiProfileProvider);
} else { } else {
MihAlertServices() MihAlertServices()
.formNotFilledCompletely(context); .formNotFilledCompletely(context);
@@ -770,72 +823,15 @@ class _ProfileBusinessAddState extends State<ProfileBusinessAdd> {
), ),
), ),
), ),
const SizedBox(height: 30),
], ],
), ),
], ],
), ),
), ),
), ),
),
],
); );
} },
@override
void dispose() {
nameController.dispose();
typeController.dispose();
regController.dispose();
logonameController.dispose();
fnameController.dispose();
lnameController.dispose();
titleController.dispose();
signtureController.dispose();
accessController.dispose();
contactController.dispose();
emailController.dispose();
locationController.dispose();
practiceNoController.dispose();
vatNoController.dispose();
_focusNode.dispose();
super.dispose();
}
@override
void initState() {
super.initState();
typeController.addListener(typeSelected);
setState(() {
fnameController.text = widget.signedInUser.fname;
lnameController.text = widget.signedInUser.lname;
accessController.text = "Full";
countryCodeController.text = "+27";
});
if (AppEnviroment.getEnv() == "Prod") {
env = "Prod";
} else {
env = "Dev";
}
missionVisionController.addListener(() {
setState(() {
_counter.value = missionVisionController.text.characters.length;
});
});
}
@override
Widget build(BuildContext context) {
double screenWidth = MediaQuery.of(context).size.width;
return MIHLayoutBuilder(
actionButton: getActionButton(),
secondaryActionButton: null,
header: getHeader(),
body: getBody(screenWidth),
actionDrawer: null,
secondaryActionDrawer: null,
bottomNavBar: null,
pullDownToRefresh: false,
onPullDown: () async {},
); );
} }
} }

Some files were not shown because too many files have changed in this diff Show More