initial offline mode, hive setup, home display, mzansi rofile display completed

This commit is contained in:
yaso 2026-06-24 11:52:53 +02:00
parent 3d5fdde322
commit f19a316be8
20 changed files with 981 additions and 304 deletions

View file

@ -0,0 +1,199 @@
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:ken_logger/ken_logger.dart';
import 'package:mih_package_toolkit/mih_package_toolkit.dart';
import 'package:mzansi_innovation_hub/mih_objects/user_consent.dart';
import 'package:mzansi_innovation_hub/mih_providers/about_mih_provider.dart';
import 'package:mzansi_innovation_hub/mih_providers/mzansi_profile_provider.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_user_consent_services.dart';
import 'package:provider/provider.dart';
class MihUserConsentWindow extends StatefulWidget {
const MihUserConsentWindow({super.key});
@override
State<MihUserConsentWindow> createState() => _MihUserConsentWindowState();
}
class _MihUserConsentWindowState extends State<MihUserConsentWindow> {
void createOrUpdateAccpetance(MzansiProfileProvider mzansiProfileProvider) {
UserConsent? userConsent = mzansiProfileProvider.userConsent;
userConsent != null
? MihUserConsentServices()
.updateUserConsentStatus(
DateTime.now().toIso8601String(),
DateTime.now().toIso8601String(),
mzansiProfileProvider,
context,
)
.then((value) {
if (!mounted) return;
if (value == 200) {
context.goNamed("mihHome");
ScaffoldMessenger.of(context).showSnackBar(
MihSnackBar(
child: Text("Thank you for accepting our Policies"),
),
);
} else {
ScaffoldMessenger.of(context).showSnackBar(
MihSnackBar(
child: Text("There was an error, please try again later"),
),
);
}
})
: MihUserConsentServices()
.insertUserConsentStatus(
DateTime.now().toIso8601String(),
DateTime.now().toIso8601String(),
mzansiProfileProvider,
context,
)
.then((value) {
if (value == 201) {
context.goNamed("mihHome");
ScaffoldMessenger.of(context).showSnackBar(
MihSnackBar(
child: Text("Thank you for accepting our Policies"),
),
);
} else {
ScaffoldMessenger.of(context).showSnackBar(
MihSnackBar(
child: Text("There was an error, please try again later"),
),
);
}
});
}
@override
Widget build(BuildContext context) {
return Consumer(
builder: (BuildContext context,
MzansiProfileProvider mzansiProfileProvider, Widget? child) {
return Container(
color: Colors.black.withValues(alpha: 0.5),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
children: [
MihPackageWindow(
fullscreen: false,
windowTitle: null,
onWindowTapClose: null,
windowBody: Column(
children: [
Icon(
Icons.policy,
size: 150,
color: MihColors.secondary(),
),
const SizedBox(height: 10),
Text(
"Welcome to the MIH App",
textAlign: TextAlign.center,
style: TextStyle(
color: MihColors.secondary(),
fontSize: 30,
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 10),
Text(
"To keep using the MIH app, please take a moment to review and accept our Policies. Our agreements helps us keep things running smoothly and securely.",
textAlign: TextAlign.center,
style: TextStyle(
color: MihColors.secondary(),
fontSize: 18,
fontWeight: FontWeight.normal,
),
),
const SizedBox(height: 20),
Center(
child: Wrap(
runAlignment: WrapAlignment.center,
crossAxisAlignment: WrapCrossAlignment.center,
alignment: WrapAlignment.center,
spacing: 10,
runSpacing: 10,
children: [
MihButton(
onPressed: () {
WidgetsBinding.instance
.addPostFrameCallback((_) async {
context
.read<AboutMihProvider>()
.setToolIndex(1);
});
context.goNamed("aboutMih",
extra: mzansiProfileProvider.personalHome);
},
buttonColor: MihColors.orange(),
elevation: 10,
width: 300,
child: Text(
"Privacy Policy",
style: TextStyle(
color: MihColors.primary(),
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
),
MihButton(
onPressed: () {
WidgetsBinding.instance
.addPostFrameCallback((_) async {
context
.read<AboutMihProvider>()
.setToolIndex(2);
});
context.goNamed("aboutMih",
extra: mzansiProfileProvider.personalHome);
},
buttonColor: MihColors.yellow(),
elevation: 10,
width: 300,
child: Text(
"Terms of Service",
style: TextStyle(
color: MihColors.primary(),
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
),
MihButton(
onPressed: () {
DateTime now = DateTime.now();
KenLogger.success("Date Time Now: $now");
createOrUpdateAccpetance(mzansiProfileProvider);
},
buttonColor: MihColors.green(),
elevation: 10,
width: 300,
child: Text(
"Accept",
style: TextStyle(
color: MihColors.primary(),
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
),
],
),
),
const SizedBox(height: 10),
],
),
),
],
),
);
},
);
}
}

View file

@ -1,16 +1,12 @@
import 'package:go_router/go_router.dart';
import 'package:ken_logger/ken_logger.dart';
import 'package:mih_package_toolkit/mih_package_toolkit.dart';
import 'package:mzansi_innovation_hub/mih_objects/user_consent.dart';
import 'package:mzansi_innovation_hub/mih_package_components/mih_circle_avatar.dart';
import 'package:mzansi_innovation_hub/mih_providers/about_mih_provider.dart';
import 'package:mzansi_innovation_hub/mih_packages/mih_home/components/mih_user_consent_window.dart';
import 'package:mzansi_innovation_hub/mih_providers/mzansi_profile_provider.dart';
import 'package:mzansi_innovation_hub/mih_packages/mih_home/components/mih_app_drawer.dart';
import 'package:mzansi_innovation_hub/mih_packages/mih_home/package_tools/mih_business_home.dart';
import 'package:mzansi_innovation_hub/mih_packages/mih_home/package_tools/mih_personal_home.dart';
import 'package:flutter/material.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_data_helper_services.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_user_consent_services.dart';
import 'package:provider/provider.dart';
class MihHome extends StatefulWidget {
@ -25,32 +21,6 @@ class MihHome extends StatefulWidget {
class _MihHomeState extends State<MihHome> {
DateTime latestPrivacyPolicyDate = DateTime.parse("2024-12-01");
DateTime latestTermOfServiceDate = DateTime.parse("2024-12-01");
bool _isLoadingInitialData = true;
late final MihPersonalHome _personalHome;
late final MihBusinessHome? _businessHome;
Future<void> _loadInitialData() async {
setState(() {
_isLoadingInitialData = true;
});
MzansiProfileProvider mzansiProfileProvider =
context.read<MzansiProfileProvider>();
if (mzansiProfileProvider.user == null) {
await MihDataHelperServices().loadUserDataWithBusinessesData(
mzansiProfileProvider,
);
}
_personalHome = const MihPersonalHome();
_businessHome = mzansiProfileProvider.business != null
? MihBusinessHome(isLoading: _isLoadingInitialData)
: null;
if (mounted) {
setState(() {
_isLoadingInitialData = false;
});
}
}
bool showPolicyWindow(UserConsent? userConsent) {
if (userConsent == null) {
@ -67,176 +37,14 @@ class _MihHomeState extends State<MihHome> {
}
}
void createOrUpdateAccpetance(MzansiProfileProvider mzansiProfileProvider) {
UserConsent? userConsent = mzansiProfileProvider.userConsent;
userConsent != null
? MihUserConsentServices()
.updateUserConsentStatus(
DateTime.now().toIso8601String(),
DateTime.now().toIso8601String(),
mzansiProfileProvider,
context,
)
.then((value) {
if (!mounted) return;
if (value == 200) {
context.goNamed("mihHome");
ScaffoldMessenger.of(context).showSnackBar(
MihSnackBar(
child: Text("Thank you for accepting our Policies"),
),
);
} else {
ScaffoldMessenger.of(context).showSnackBar(
MihSnackBar(
child: Text("There was an error, please try again later"),
),
);
}
})
: MihUserConsentServices()
.insertUserConsentStatus(
DateTime.now().toIso8601String(),
DateTime.now().toIso8601String(),
mzansiProfileProvider,
context,
)
.then((value) {
if (value == 201) {
context.goNamed("mihHome");
ScaffoldMessenger.of(context).showSnackBar(
MihSnackBar(
child: Text("Thank you for accepting our Policies"),
),
);
} else {
ScaffoldMessenger.of(context).showSnackBar(
MihSnackBar(
child: Text("There was an error, please try again later"),
),
);
}
});
}
Widget displayConsentWindow(MzansiProfileProvider mzansiProfileProvider) {
return Container(
color: Colors.black.withValues(alpha: 0.5),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
children: [
MihPackageWindow(
fullscreen: false,
windowTitle: null,
onWindowTapClose: null,
windowBody: Column(
children: [
Icon(
Icons.policy,
size: 150,
color: MihColors.secondary(),
),
const SizedBox(height: 10),
Text(
"Welcome to the MIH App",
textAlign: TextAlign.center,
style: TextStyle(
color: MihColors.secondary(),
fontSize: 30,
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 10),
Text(
"To keep using the MIH app, please take a moment to review and accept our Policies. Our agreements helps us keep things running smoothly and securely.",
textAlign: TextAlign.center,
style: TextStyle(
color: MihColors.secondary(),
fontSize: 18,
fontWeight: FontWeight.normal,
),
),
const SizedBox(height: 20),
Center(
child: Wrap(
runAlignment: WrapAlignment.center,
crossAxisAlignment: WrapCrossAlignment.center,
alignment: WrapAlignment.center,
spacing: 10,
runSpacing: 10,
children: [
MihButton(
onPressed: () {
WidgetsBinding.instance
.addPostFrameCallback((_) async {
context.read<AboutMihProvider>().setToolIndex(1);
});
context.goNamed("aboutMih",
extra: mzansiProfileProvider.personalHome);
},
buttonColor: MihColors.orange(),
elevation: 10,
width: 300,
child: Text(
"Privacy Policy",
style: TextStyle(
color: MihColors.primary(),
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
),
MihButton(
onPressed: () {
WidgetsBinding.instance
.addPostFrameCallback((_) async {
context.read<AboutMihProvider>().setToolIndex(2);
});
context.goNamed("aboutMih",
extra: mzansiProfileProvider.personalHome);
},
buttonColor: MihColors.yellow(),
elevation: 10,
width: 300,
child: Text(
"Terms of Service",
style: TextStyle(
color: MihColors.primary(),
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
),
MihButton(
onPressed: () {
DateTime now = DateTime.now();
KenLogger.success("Date Time Now: $now");
createOrUpdateAccpetance(mzansiProfileProvider);
},
buttonColor: MihColors.green(),
elevation: 10,
width: 300,
child: Text(
"Accept",
style: TextStyle(
color: MihColors.primary(),
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
),
],
),
),
const SizedBox(height: 10),
],
),
),
],
),
);
}
Future<void> _syncProfileData() async {
MzansiProfileProvider mzansiProfileProvider =
context.read<MzansiProfileProvider>();
mzansiProfileProvider.loadCachedProfileState();
if (mzansiProfileProvider.user == null) {
await mzansiProfileProvider.syncWithCloudPipeline();
}
}
@override
void dispose() {
@ -246,7 +54,11 @@ class _MihHomeState extends State<MihHome> {
@override
void initState() {
super.initState();
_loadInitialData();
WidgetsBinding.instance.addPostFrameCallback((_) {
if (mounted) {
_syncProfileData();
}
});
}
List<String> getToolTitle() {
@ -262,20 +74,18 @@ class _MihHomeState extends State<MihHome> {
return Consumer<MzansiProfileProvider>(
builder: (BuildContext context,
MzansiProfileProvider mzansiProfileProvider, Widget? child) {
if (_isLoadingInitialData) {
return Scaffold(
body: Center(
child: Mihloadingcircle(),
),
);
}
// bool showConsentWindow =
// showPolicyWindow(mzansiProfileProvider.userConsent);
if (mzansiProfileProvider.user == null) {
return Scaffold(
body: Center(
child: Mihloadingcircle(),
),
);
}
return Stack(
children: [
RefreshIndicator(
onRefresh: () async {
await _loadInitialData();
await mzansiProfileProvider.syncWithCloudPipeline();
},
child: SingleChildScrollView(
physics: const AlwaysScrollableScrollPhysics(),
@ -298,7 +108,7 @@ class _MihHomeState extends State<MihHome> {
),
),
if (showPolicyWindow(mzansiProfileProvider.userConsent))
displayConsentWindow(mzansiProfileProvider),
MihUserConsentWindow(),
],
);
},
@ -373,15 +183,10 @@ class _MihHomeState extends State<MihHome> {
}
List<Widget> getToolBody(MzansiProfileProvider mzansiProfileProvider) {
if (mzansiProfileProvider.business == null) {
return [
_personalHome,
];
} else {
return [
_personalHome,
_businessHome!,
];
}
return [
const MihPersonalHome(),
if (mzansiProfileProvider.business != null)
const MihBusinessHome(isLoading: false)
];
}
}

View file

@ -204,7 +204,7 @@ class _MihPersonalHomeState extends State<MihPersonalHome>
searchController.addListener(searchPackage);
MzansiProfileProvider profileProvider =
context.read<MzansiProfileProvider>();
if (profileProvider.user!.username == "") {
if (profileProvider.user == null || profileProvider.user?.username == "") {
personalPackagesMap = setNerUserPersonalPackage();
autoNavToProfile();
} else {
@ -233,7 +233,8 @@ class _MihPersonalHomeState extends State<MihPersonalHome>
return Column(
children: [
Visibility(
visible: profileProvider.user!.username != "",
visible: profileProvider.user != null &&
profileProvider.user?.username != "",
child: Padding(
padding: EdgeInsets.symmetric(horizontal: width / 20),
child: MihSearchBar(

View file

@ -5,8 +5,6 @@ import 'package:mzansi_innovation_hub/mih_providers/mzansi_profile_provider.dart
import 'package:mzansi_innovation_hub/mih_packages/mzansi_profile/personal_profile/package_tools/mih_personal_profile.dart';
import 'package:mzansi_innovation_hub/mih_packages/mzansi_profile/personal_profile/package_tools/mih_personal_settings.dart';
import 'package:flutter/material.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_data_helper_services.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_profile_links_service.dart';
import 'package:provider/provider.dart';
class MzansiProfile extends StatefulWidget {
@ -25,20 +23,12 @@ class _MzansiProfileState extends State<MzansiProfile> {
late final MihPersonalSettings _personalSettings;
Future<void> _loadInitialData() async {
setState(() {
_isLoadingInitialData = true;
});
MzansiProfileProvider mzansiProfileProvider =
context.read<MzansiProfileProvider>();
mzansiProfileProvider.loadCachedProfileState();
if (mzansiProfileProvider.user == null) {
await MihDataHelperServices().loadUserDataWithBusinessesData(
mzansiProfileProvider,
);
mzansiProfileProvider.syncWithCloudPipeline();
}
await MihProfileLinksServices.getUserProfileLinks(
mzansiProfileProvider,
mzansiProfileProvider.user!.app_id,
);
setState(() {
_isLoadingInitialData = false;
});
@ -50,7 +40,9 @@ class _MzansiProfileState extends State<MzansiProfile> {
_personalProfile = const MihPersonalProfile();
_personalQrCode = const MihPersonalQrCode(user: null);
_personalSettings = const MihPersonalSettings();
_loadInitialData();
WidgetsBinding.instance.addPostFrameCallback((_) {
_loadInitialData();
});
}
@override