complete mzansi personal and business profile get & store data offline mode

This commit is contained in:
yaso 2026-06-25 11:59:21 +02:00
parent d42337fc6c
commit 8d78fb6357
13 changed files with 240 additions and 61 deletions

View file

@ -2,6 +2,7 @@
import 'package:hive_ce/hive_ce.dart';
import 'package:mzansi_innovation_hub/mih_objects/app_user.dart';
import 'package:mzansi_innovation_hub/mih_objects/business.dart';
import 'package:mzansi_innovation_hub/mih_objects/business_employee.dart';
import 'package:mzansi_innovation_hub/mih_objects/business_user.dart';
import 'package:mzansi_innovation_hub/mih_objects/profile_link.dart';
import 'package:mzansi_innovation_hub/mih_objects/user_consent.dart';
@ -12,5 +13,6 @@ import 'package:mzansi_innovation_hub/mih_objects/user_consent.dart';
AdapterSpec<BusinessUser>(),
AdapterSpec<UserConsent>(),
AdapterSpec<ProfileLink>(),
AdapterSpec<BusinessEmployee>(),
])
part 'hive_adapters.g.dart';

View file

@ -283,3 +283,58 @@ class ProfileLinkAdapter extends TypeAdapter<ProfileLink> {
runtimeType == other.runtimeType &&
typeId == other.typeId;
}
class BusinessEmployeeAdapter extends TypeAdapter<BusinessEmployee> {
@override
final typeId = 5;
@override
BusinessEmployee read(BinaryReader reader) {
final numOfFields = reader.readByte();
final fields = <int, dynamic>{
for (int i = 0; i < numOfFields; i++) reader.readByte(): reader.read(),
};
return BusinessEmployee(
fields[0] as String,
fields[1] as String,
fields[2] as String,
fields[3] as String,
fields[4] as String,
fields[5] as String,
fields[6] as String,
fields[7] as String,
);
}
@override
void write(BinaryWriter writer, BusinessEmployee obj) {
writer
..writeByte(8)
..writeByte(0)
..write(obj.business_id)
..writeByte(1)
..write(obj.app_id)
..writeByte(2)
..write(obj.title)
..writeByte(3)
..write(obj.access)
..writeByte(4)
..write(obj.fname)
..writeByte(5)
..write(obj.lname)
..writeByte(6)
..write(obj.email)
..writeByte(7)
..write(obj.username);
}
@override
int get hashCode => typeId.hashCode;
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is BusinessEmployeeAdapter &&
runtimeType == other.runtimeType &&
typeId == other.typeId;
}

View file

@ -1,7 +1,7 @@
# Generated by Hive CE
# Manual modifications may be necessary for certain migrations
# Check in to version control
nextTypeId: 5
nextTypeId: 6
types:
AppUser:
typeId: 0
@ -105,3 +105,23 @@ types:
index: 5
order:
index: 6
BusinessEmployee:
typeId: 5
nextIndex: 8
fields:
business_id:
index: 0
app_id:
index: 1
title:
index: 2
access:
index: 3
fname:
index: 4
lname:
index: 5
email:
index: 6
username:
index: 7

View file

@ -9,6 +9,7 @@ extension HiveRegistrar on HiveInterface {
void registerAdapters() {
registerAdapter(AppUserAdapter());
registerAdapter(BusinessAdapter());
registerAdapter(BusinessEmployeeAdapter());
registerAdapter(BusinessUserAdapter());
registerAdapter(ProfileLinkAdapter());
registerAdapter(UserConsentAdapter());
@ -19,6 +20,7 @@ extension IsolatedHiveRegistrar on IsolatedHiveInterface {
void registerAdapters() {
registerAdapter(AppUserAdapter());
registerAdapter(BusinessAdapter());
registerAdapter(BusinessEmployeeAdapter());
registerAdapter(BusinessUserAdapter());
registerAdapter(ProfileLinkAdapter());
registerAdapter(UserConsentAdapter());

View file

@ -1,11 +1,15 @@
import 'dart:math';
import 'package:hive_ce_flutter/hive_ce_flutter.dart';
import 'package:ken_logger/ken_logger.dart';
import 'package:mzansi_innovation_hub/mih_objects/app_user.dart';
import 'package:mzansi_innovation_hub/mih_objects/business.dart';
import 'package:mzansi_innovation_hub/mih_objects/business_employee.dart';
import 'package:mzansi_innovation_hub/mih_objects/business_user.dart';
import 'package:mzansi_innovation_hub/mih_objects/profile_link.dart';
import 'package:mzansi_innovation_hub/mih_objects/user_consent.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_business_details_services.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_business_employee_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_profile_links_service.dart';
@ -21,7 +25,10 @@ class MzansiProfileHiveData {
Hive.box<UserConsent>('user_consent_box');
final Box<ProfileLink> _personalProfileLinksBox =
Hive.box<ProfileLink>('personal_profile_links_box');
final Box<ProfileLink> _businessProfileLinksBox =
Hive.box<ProfileLink>('business_profile_links_box');
final Box<BusinessEmployee> _businessEmployeesBox =
Hive.box<BusinessEmployee>('business_Employees_box');
final Box<String> _resolvedUrlsBox = Hive.box<String>('image_urls_box');
static const String kUserKey = 'current_user';
@ -32,6 +39,7 @@ class MzansiProfileHiveData {
static const String kBusinessPicUrlKey = 'business_pic_url';
static const String kSignatureUrlKey = 'signature_url';
// Get Data from local storage
AppUser? getCachedUser() => _userBox.get(kUserKey);
Business? getCachedBusiness() => _businessBox.get(kBusinessKey);
BusinessUser? getCachedBusinessUser() =>
@ -40,12 +48,26 @@ class MzansiProfileHiveData {
String? getCachedUserPicUrl() => _resolvedUrlsBox.get(kUserPicUrlKey);
String? getCachedBusinessPicUrl() => _resolvedUrlsBox.get(kBusinessPicUrlKey);
String? getCachedSignatureUrl() => _resolvedUrlsBox.get(kSignatureUrlKey);
List<ProfileLink> getCachedPersonalProfileLinks() {
final links = _personalProfileLinksBox.values.toList();
links.sort((a, b) => a.order.compareTo(b.order));
return links;
}
List<ProfileLink> getCachedBusinessProfileLinks() {
final links = _businessProfileLinksBox.values.toList();
links.sort((a, b) => a.order.compareTo(b.order));
return links;
}
List<BusinessEmployee> getCachedBusinessEmployees() {
final employees = _businessEmployeesBox.values.toList();
employees.sort((a, b) => a.fname.compareTo(b.fname));
return employees;
}
// Caching Data to local storage
Future<void> cacheUserData(AppUser remoteUser) async {
await _userBox.put(kUserKey, remoteUser);
if (remoteUser.pro_pic_path.isNotEmpty) {
@ -53,10 +75,12 @@ class MzansiProfileHiveData {
await MihFileApi.getMinioFileUrl(remoteUser.pro_pic_path);
await _resolvedUrlsBox.put(kUserPicUrlKey, userPicUrl);
}
KenLogger.success("User Profile Cached");
}
Future<void> cacheUserConsentData(UserConsent remoteConsent) async {
await _userConsentBox.put(kConsentKey, remoteConsent);
KenLogger.success("User Consent Cached");
}
Future<void> cacheBusinessData(Business remoteBusiness) async {
@ -71,6 +95,7 @@ class MzansiProfileHiveData {
if (remoteBizUser != null) {
cacheBusinessUserData(remoteBizUser);
}
KenLogger.success("Busines Profile Cached");
}
Future<void> cacheBusinessUserData(BusinessUser remoteBizUser) async {
@ -80,33 +105,59 @@ class MzansiProfileHiveData {
await MihFileApi.getMinioFileUrl(remoteBizUser.sig_path);
await _resolvedUrlsBox.put(kSignatureUrlKey, signatureUrl);
}
KenLogger.success("Busines User Profile Cached");
}
Future<void> cacheBusinessEmployeesData(
List<BusinessEmployee> remoteBusinessEmployeeList) async {
await _businessEmployeesBox.clear();
await _businessEmployeesBox.addAll(remoteBusinessEmployeeList);
KenLogger.success("Business Employees Cached");
}
Future<void> cachePersonalProfileLinksData(
List<ProfileLink> remoteLinks) async {
List<ProfileLink> remotePersonalLinks) async {
await _personalProfileLinksBox.clear();
await _personalProfileLinksBox.addAll(remoteLinks);
await _personalProfileLinksBox.addAll(remotePersonalLinks);
KenLogger.success("Personal Profile Links Cached");
}
Future<void> cacheBusinessProfileLinksData(
List<ProfileLink> remoteBusinessLinks) async {
await _businessProfileLinksBox.clear();
await _businessProfileLinksBox.addAll(remoteBusinessLinks);
KenLogger.success("Personal Profile Links Cached");
}
// Sync Local Data from data from MIH Server
Future<void> syncProfileDataWithServer() async {
try {
AppUser? remoteUser = await MihUserServices().getMyUserDetailsV2();
if (remoteUser != null) {
cacheUserData(remoteUser);
UserConsent? remoteConsent =
await MihUserConsentServices().getUserConsentStatusV2();
if (remoteConsent != null) {
cacheUserConsentData(remoteConsent);
}
final remoteLinks = await MihProfileLinksServices.getUserProfileLinksV2(
remoteUser.app_id);
await cachePersonalProfileLinksData(remoteLinks);
final remotePersonalLinks =
await MihProfileLinksServices.getUserProfileLinksV2(
remoteUser.app_id);
cachePersonalProfileLinksData(remotePersonalLinks);
}
Business? remoteBusiness =
await MihBusinessDetailsServices().getBusinessDetailsByUserV2();
if (remoteBusiness != null) {
cacheBusinessData(remoteBusiness);
final remoteBusinessEmployeeList = await MihBusinessEmployeeServices()
.fetchEmployeesV2(remoteBusiness.business_id);
cacheBusinessEmployeesData(remoteBusinessEmployeeList);
final remoteBusinessLinks =
await MihProfileLinksServices.getBusinessProfileLinksV2(
remoteBusiness.business_id);
cacheBusinessProfileLinksData(remoteBusinessLinks);
}
} catch (error) {
KenLogger.warning("App operating offline mode. Sync paused");