feat: Refactor code structure and optimize performance across multiple modules

This commit is contained in:
Achintha Isuru
2025-11-17 23:29:28 -05:00
parent 831570f2e0
commit a64cbd9edf
1508 changed files with 105319 additions and 0 deletions

View File

@@ -0,0 +1,48 @@
import 'dart:developer';
import 'package:injectable/injectable.dart';
import 'package:krow/core/application/clients/api/api_client.dart';
import 'package:krow/core/data/models/staff/staff.dart';
import 'package:krow/core/data/models/staff_role.dart';
import 'package:krow/features/profile/profile_main/data/profile_gql.dart';
@injectable
class ProfileApiProvider {
final ApiClient _apiClient;
ProfileApiProvider({required ApiClient apiClient}) : _apiClient = apiClient;
Future<List<StaffRole>> fetchUserProfileRoles() async {
var result = await _apiClient.query(schema: getStaffProfileRolesQuery);
if (result.hasException) {
throw Exception(result.exception.toString());
}
return result.data!['staff_roles'].map<StaffRole>((e) {
return StaffRole.fromJson(e);
}).toList();
}
Stream<Staff> getMeWithCache() async* {
await for (var response in _apiClient.queryWithCache(schema: getMeQuery)) {
if (response == null || response.data == null) continue;
if (response.hasException) {
throw Exception(response.exception.toString());
}
try {
final staffData = response.data?['me'] as Map<String, dynamic>? ?? {};
if (staffData.isEmpty) continue;
yield Staff.fromJson(staffData);
} catch (except) {
log(
'Exception in StaffApi on getMeWithCache()',
error: except,
);
continue;
}
}
}
}

View File

@@ -0,0 +1,36 @@
import 'package:krow/core/application/clients/api/gql.dart';
const String getMeQuery = '''
$staffFragment
query GetMe {
me {
id
...StaffFields
}
}
''';
const String getStaffProfileRolesQuery = '''
$skillFragment
query GetStaffRoles {
staff_roles {
id
skill {
...SkillFragment
}
confirmed_uniforms {
id
skill_kit_id
photo
}
confirmed_equipments {
id
skill_kit_id
photo
}
level
experience
status
}
}
''';

View File

@@ -0,0 +1,54 @@
import 'dart:convert';
import 'package:injectable/injectable.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:krow/core/data/models/staff/staff.dart';
import 'package:krow/core/data/models/staff_role.dart';
import 'package:firebase_auth/firebase_auth.dart';
@LazySingleton()
class ProfileLocalProvider {
Future<String> _getUserId() async {
final user = FirebaseAuth.instance.currentUser;
if (user != null) {
return user.uid;
} else {
throw Exception('No user logged in');
}
}
Future<void> saveStaff(Staff staff) async {
final prefs = await SharedPreferences.getInstance();
final userId = await _getUserId();
final staffJson = jsonEncode(staff.toJson());
await prefs.setString('cached_staff_$userId', staffJson);
}
Future<Staff?> loadStaff() async {
final prefs = await SharedPreferences.getInstance();
final userId = await _getUserId();
final staffJson = prefs.getString('cached_staff_$userId');
if (staffJson != null) {
return Staff.fromJson(jsonDecode(staffJson));
}
return null;
}
Future<void> saveRoles(List<StaffRole> roles) async {
final prefs = await SharedPreferences.getInstance();
final userId = await _getUserId();
final rolesJson = jsonEncode(roles.map((role) => role.toJson()).toList());
await prefs.setString('cached_roles_$userId', rolesJson);
}
Future<List<StaffRole>?> loadRoles() async {
final prefs = await SharedPreferences.getInstance();
final userId = await _getUserId();
final rolesJson = prefs.getString('cached_roles_$userId');
if (rolesJson != null) {
final List<dynamic> rolesList = jsonDecode(rolesJson);
return rolesList.map((json) => StaffRole.fromJson(json)).toList();
}
return null;
}
}

View File

@@ -0,0 +1,36 @@
import 'package:injectable/injectable.dart';
import 'package:krow/core/data/models/staff/staff.dart';
import 'package:krow/core/data/models/staff_role.dart';
import 'package:krow/features/profile/profile_main/data/profile_api_provider.dart';
import 'package:krow/features/profile/profile_main/data/profile_local_provider.dart';
import 'package:krow/features/profile/profile_main/domain/profile_repository.dart';
@Injectable(as: ProfileRepository)
class ProfileRepositoryImpl extends ProfileRepository{
final ProfileApiProvider _apiProvider;
final ProfileLocalProvider _cacheProvider;
ProfileRepositoryImpl(this._apiProvider, this._cacheProvider);
@override
Future<List<StaffRole>> getUserProfileRoles() async{
var roles = await _apiProvider.fetchUserProfileRoles();
await cacheProfileRoles(roles);
return roles;
}
@override
Future<void> cacheProfileRoles(List<StaffRole> roles) async{
await _cacheProvider.saveRoles(roles);
}
@override
Future<List<StaffRole>?> getCachedProfileRoles() {
return _cacheProvider.loadRoles();
}
@override
Stream<Staff> getUserProfile() {
return _apiProvider.getMeWithCache();
}
}