QueenFruits/Mobile Operasional/lib/features/auth/presentation/controllers/auth_controller.dart

189 lines
5.1 KiB
Dart

import 'dart:async';
import 'dart:io';
import 'package:dio/dio.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:niogu_app/core/database/app_database.dart';
import 'package:niogu_app/core/models/outlet_model.dart';
import 'package:niogu_app/core/providers/app_provider.dart';
import 'package:niogu_app/core/database/database_holder.dart';
import 'package:niogu_app/core/utils/image_service.dart';
import 'package:niogu_app/core/system/system_secure.dart';
import 'package:niogu_app/core/system/system_setting.dart';
import 'package:niogu_app/core/enums/user_role.dart';
import 'package:niogu_app/features/auth/domain/entities/user.dart';
import 'package:niogu_app/features/auth/domain/repositories/i_auth_repository.dart';
import 'package:niogu_app/features/auth/presentation/providers/auth_provider.dart';
import 'package:path/path.dart' as p;
import 'package:path_provider/path_provider.dart';
class AuthController extends AutoDisposeAsyncNotifier<void> {
late final IAuthRepository _repository;
late final Dio _dio;
@override
FutureOr<void> build() {
_repository = ref.read(authRepositoryProvider);
_dio = ref.read(dioProvider);
}
Future<String?> _handleBusinessLogo(String? serverLogoUrl) async {
try {
if (serverLogoUrl != null && serverLogoUrl.isNotEmpty) {
final tempDir = await getTemporaryDirectory();
final tempPath = p.join(tempDir.path, 'temp_logo.jpg');
await _dio.download(serverLogoUrl, tempPath);
return await ImageService.saveImageToLocalDirectory(
File(tempPath),
'logo_images',
);
}
return null;
} catch (e) {
rethrow;
}
}
Future<Map<String, String?>> _handleOutletBanners(
List<OutletModel> outletModels,
) async {
try {
final Map<String, String?> localBannerPaths = {};
for (final outlet in outletModels) {
final id = outlet.serverId;
final banner = outlet.serverBannerUrl;
if (banner != null && banner.isNotEmpty) {
final tempDir = await getTemporaryDirectory();
final tempPath = p.join(tempDir.path, 'temp_logo.jpg');
await _dio.download(banner, tempPath);
final localBannerPath = await ImageService.saveImageToLocalDirectory(
File(tempPath),
'outlet_banner_images',
);
localBannerPaths.putIfAbsent(id, () => localBannerPath);
}
}
return localBannerPaths;
} catch (e) {
rethrow;
}
}
Future<void> login(LoginUser user) async {
state = const AsyncValue.loading();
final result = await AsyncValue.guard(() async {
final response = await _repository.login(user);
final data = response.data!;
final tenantModel = data.user.tenant;
final outletModels = data.user.outlets;
final userModel = data.user;
final staffModels = userModel.staffs;
final localLogoPath = await _handleBusinessLogo(
tenantModel.serverLogoUrl,
);
final localBannerPaths = await _handleOutletBanners(outletModels);
final accessToken = data.accessToken;
await clearDatabase();
await SystemSetting.setTenant(
tenantId: tenantModel.serverId,
tenantCode: tenantModel.businessCode,
tenantName: tenantModel.businessName,
);
await Future.delayed(Duration.zero);
final appDatabase = AppDatabase();
await setDatabase(appDatabase);
await appDatabase.customSelect("SELECT 1").getSingle();
await appDatabase.userDao.login(
tenantModel: tenantModel,
outletModels: outletModels,
userModel: userModel,
staffModels: staffModels,
localLogoPath: localLogoPath,
localBannerPaths: localBannerPaths,
password: user.password,
);
ref.invalidate(appDatabaseProvider);
final syncService = ref.read(syncServiceProvider);
syncService.stopWatching();
await syncService.startWatching();
await SystemSecure.saveAccessToken(accessToken);
await SystemSetting.setIsLoggedIn();
String? outletIdByOwner;
final currentUserRole = UserRole.values.byName(userModel.role);
if (currentUserRole == UserRole.owner) {
outletIdByOwner = userModel.outletId;
}
await SystemSetting.setOutletIdByOwner(outletIdByOwner);
final outletName = outletModels
.firstWhere((outlet) => outlet.serverId == userModel.outletId)
.name;
await SystemSetting.switchOutlet(
outletId: userModel.outletId,
outletName: outletName,
);
await SystemSetting.setUser(
userId: userModel.serverId,
userName: userModel.name,
userEmail: userModel.email,
userRole: currentUserRole,
);
});
state = result;
if (result is AsyncError) throw result.error!;
}
Future<void> register(RegisterUser register) async {
state = const AsyncValue.loading();
final result = await AsyncValue.guard(() async {
await _repository.register(register);
});
state = result;
if (result is AsyncError) throw result.error!;
}
}