profile settings screen to show user information, move getPaymentProfile,getUserInfo,getChildProfiles request to sf shared, some refactors
This commit is contained in:
@@ -80,7 +80,7 @@ class PlatformAppState extends ConsumerState<PlatformApp>
|
||||
routerConfig: appRouter,
|
||||
debugShowCheckedModeBanner: false,
|
||||
localizationsDelegates: [
|
||||
// CountryLocalizations.getDelegate(enableLocalization: false),
|
||||
// CountryLocalizations.delegate,
|
||||
SFLocalizations.delegate,
|
||||
GlobalMaterialLocalizations.delegate,
|
||||
GlobalCupertinoLocalizations.delegate,
|
||||
|
||||
@@ -103,6 +103,13 @@ void configureAppRouter() {
|
||||
path: AppRoutes.dashboardProfile,
|
||||
name: 'profile',
|
||||
pageBuilder: const ProfileBuilder().buildPage,
|
||||
routes: [
|
||||
GoRoute(
|
||||
path: 'settings',
|
||||
name: 'profile_settings',
|
||||
pageBuilder: const ProfileSettingsBuilder().buildPage,
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
@@ -1,14 +1,10 @@
|
||||
import 'package:auth/src/core/data/models/child_profile_response_model.dart';
|
||||
import 'package:auth/src/core/data/models/payment_profile_response_model.dart';
|
||||
import 'package:auth/src/core/data/models/user_response_model.dart';
|
||||
import 'package:auth/src/core/data/models/sign_up_request_model.dart';
|
||||
import 'package:auth/src/core/data/models/sign_up_response_model.dart';
|
||||
import 'package:auth/src/core/data/models/two_fa_secret_response_model.dart';
|
||||
import 'package:auth/src/core/data/models/login_response_model.dart';
|
||||
|
||||
abstract class AuthRemoteDatasource {
|
||||
Future<UserModel> getUserInfo();
|
||||
|
||||
Future<void> requestPhoneCode({required String phone});
|
||||
|
||||
Future<void> verifyPhoneCode({required String phone, required String code});
|
||||
@@ -44,8 +40,6 @@ abstract class AuthRemoteDatasource {
|
||||
|
||||
Future<void> createWallet();
|
||||
|
||||
Future<PaymentProfileResponseModel> getPaymentProfile({required String userId});
|
||||
|
||||
Future<ChildProfileResponseModel> createChildProfile({
|
||||
required String id,
|
||||
required String parentId,
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:auth/src/core/data/models/child_profile_response_model.dart';
|
||||
import 'package:auth/src/core/data/models/payment_profile_response_model.dart';
|
||||
import 'package:auth/src/core/data/models/user_response_model.dart';
|
||||
import 'package:auth/src/core/data/models/sign_up_request_model.dart';
|
||||
import 'package:auth/src/core/data/models/sign_up_response_model.dart';
|
||||
import 'package:auth/src/core/data/models/two_fa_secret_response_model.dart';
|
||||
@@ -17,22 +15,6 @@ class AuthRemoteDatasourceImpl implements AuthRemoteDatasource {
|
||||
AuthRemoteDatasourceImpl(this._repository);
|
||||
|
||||
final QuestiaRepository _repository;
|
||||
@override
|
||||
Future<UserModel> getUserInfo() async {
|
||||
try {
|
||||
final response = await _repository.get<Map<String, dynamic>>('/auth/me');
|
||||
|
||||
final data = response.data;
|
||||
if (data == null || data.isEmpty) {
|
||||
throw Exception('Empty response from /auth/me');
|
||||
}
|
||||
|
||||
final parsed = UserResponseModel.fromJson(data);
|
||||
return parsed.item;
|
||||
} on DioException catch (error) {
|
||||
throw _mapDioError(error, defaultMessage: 'Error in /auth/me');
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> requestPhoneCode({required String phone}) async {
|
||||
@@ -283,29 +265,6 @@ class AuthRemoteDatasourceImpl implements AuthRemoteDatasource {
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<PaymentProfileResponseModel> getPaymentProfile({
|
||||
required String userId,
|
||||
}) async {
|
||||
try {
|
||||
final response = await _repository.get<Map<String, dynamic>>(
|
||||
'/users/$userId/payment-profile',
|
||||
);
|
||||
|
||||
final data = response.data;
|
||||
if (data == null || data.isEmpty) {
|
||||
throw Exception('Empty response from /users/$userId/payment-profile');
|
||||
}
|
||||
|
||||
return PaymentProfileResponseModel.fromJson(data);
|
||||
} on DioException catch (error) {
|
||||
throw _mapDioError(
|
||||
error,
|
||||
defaultMessage: 'Error in /users/$userId/payment-profile',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<ChildProfileResponseModel> createChildProfile({
|
||||
required String id,
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
import 'package:auth/src/core/data/models/user_response_model.dart';
|
||||
import 'package:auth/src/features/login/domain/entities/user_entity.dart';
|
||||
|
||||
extension UserModelMapper on UserModel {
|
||||
UserEntity toEntity() {
|
||||
return UserEntity(
|
||||
id: id,
|
||||
delegationId: delegationId,
|
||||
email: email,
|
||||
createdAt: createdAt,
|
||||
updatedAt: updatedAt,
|
||||
status: status,
|
||||
role: role,
|
||||
lastLogin: lastLogin,
|
||||
currentLogin: currentLogin,
|
||||
language: language,
|
||||
firstName: firstName,
|
||||
lastName: lastName,
|
||||
hasApiKey: hasApiKey,
|
||||
phone: phone,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,15 +1,11 @@
|
||||
import 'package:auth/src/core/data/datasource/auth_remote_datasource.dart';
|
||||
import 'package:auth/src/core/data/mappers/user_model_mapper.dart';
|
||||
import 'package:auth/src/core/data/models/child_profile_response_model.dart';
|
||||
import 'package:auth/src/core/data/models/payment_profile_response_model.dart';
|
||||
import 'package:auth/src/core/data/models/sign_up_request_model.dart';
|
||||
import 'package:auth/src/core/data/models/sign_up_response_model.dart';
|
||||
import 'package:auth/src/core/data/models/two_fa_secret_response_model.dart';
|
||||
import 'package:auth/src/core/domain/repositories/auth_repository.dart';
|
||||
import 'package:auth/src/features/device_setup/domain/entities/child_profile_entity.dart';
|
||||
import 'package:auth/src/features/login/domain/entities/login_response_entity.dart';
|
||||
import 'package:auth/src/features/login/domain/entities/payment_profile_entity.dart';
|
||||
import 'package:auth/src/features/login/domain/entities/user_entity.dart';
|
||||
import 'package:auth/src/features/sign_up/domain/entities/sign_up_request_entity.dart';
|
||||
import 'package:auth/src/features/sign_up/domain/entities/sign_up_response_entity.dart';
|
||||
import 'package:auth/src/core/data/models/login_response_model.dart';
|
||||
@@ -60,25 +56,11 @@ class AuthRepositoryImpl implements AuthRepository {
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<UserEntity> getUserInfo() async {
|
||||
final model = await _remote.getUserInfo();
|
||||
return model.toEntity();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> createWallet() {
|
||||
return _remote.createWallet();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<PaymentProfileEntity> getPaymentProfile({
|
||||
required String userId,
|
||||
}) async {
|
||||
final model = await _remote.getPaymentProfile(userId: userId);
|
||||
return model.toEntity();
|
||||
}
|
||||
|
||||
// @override
|
||||
// Future<String> totpLogin({required String token, required String code}) {
|
||||
// return _remote.totpLogin(token: token, code: code);
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
import 'package:auth/src/core/data/models/child_profile_response_model.dart';
|
||||
import 'package:auth/src/core/data/models/two_fa_secret_response_model.dart';
|
||||
import 'package:auth/src/features/device_setup/domain/entities/child_profile_entity.dart';
|
||||
import 'package:auth/src/features/login/domain/entities/login_response_entity.dart';
|
||||
import 'package:auth/src/features/login/domain/entities/payment_profile_entity.dart';
|
||||
import 'package:auth/src/features/login/domain/entities/user_entity.dart';
|
||||
import 'package:auth/src/features/sign_up/domain/entities/sign_up_request_entity.dart';
|
||||
import 'package:auth/src/features/sign_up/domain/entities/sign_up_response_entity.dart';
|
||||
|
||||
@@ -25,12 +22,9 @@ abstract class AuthRepository {
|
||||
required String code,
|
||||
required String methodType,
|
||||
});
|
||||
Future<UserEntity> getUserInfo();
|
||||
|
||||
Future<void> createWallet();
|
||||
|
||||
Future<PaymentProfileEntity> getPaymentProfile({required String userId});
|
||||
|
||||
// Future<String> totpLogin({required String token, required String code});
|
||||
|
||||
Future<SignUpResponseEntity> signUp({required SignUpRequestEntity request});
|
||||
|
||||
@@ -5,14 +5,12 @@ import 'package:auth/src/features/device_setup/presentation/enums/scan_link_step
|
||||
import 'package:auth/src/features/device_setup/presentation/providers/create_child_profile_use_case_provider.dart';
|
||||
import 'package:auth/src/features/device_setup/presentation/state/device_setup_view_state.dart';
|
||||
import 'package:auth/src/features/device_setup/presentation/enums/add_kid_step.dart';
|
||||
import 'package:auth/src/features/login/domain/entities/user_entity.dart';
|
||||
import 'package:auth/src/features/login/domain/get_me_user_use_case.dart';
|
||||
import 'package:auth/src/features/login/presentation/providers/get_user_info_provider.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:get_it/get_it.dart';
|
||||
import 'package:sca_treezor/sca_treezor.dart';
|
||||
import 'package:sf_localizations/sf_localizations.dart';
|
||||
import 'package:sf_shared/sf_shared.dart';
|
||||
import 'package:uuid/uuid.dart';
|
||||
|
||||
final deviceSetupViewModelProvider =
|
||||
@@ -80,9 +78,7 @@ class DeviceSetupViewModel extends Notifier<DeviceSetupViewState> {
|
||||
case AddKidStep.scanStrap:
|
||||
final hasStrap = state.strapQr.isNotEmpty || state.strapCode.isNotEmpty;
|
||||
if (!hasStrap) {
|
||||
state = state.copyWith(
|
||||
errorMessage: I18n.errorScanStrapRequired,
|
||||
);
|
||||
state = state.copyWith(errorMessage: I18n.errorScanStrapRequired);
|
||||
return;
|
||||
}
|
||||
state = state.copyWith(step: AddKidStep.scanWatch, errorMessage: '');
|
||||
@@ -90,9 +86,7 @@ class DeviceSetupViewModel extends Notifier<DeviceSetupViewState> {
|
||||
case AddKidStep.scanWatch:
|
||||
final hasWatch = state.watchQr.isNotEmpty || state.watchCode.isNotEmpty;
|
||||
if (!hasWatch) {
|
||||
state = state.copyWith(
|
||||
errorMessage: I18n.errorScanWatchRequired,
|
||||
);
|
||||
state = state.copyWith(errorMessage: I18n.errorScanWatchRequired);
|
||||
return;
|
||||
}
|
||||
state = state.copyWith(step: AddKidStep.profile, errorMessage: '');
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
import 'package:auth/src/core/domain/repositories/auth_repository.dart';
|
||||
import 'package:auth/src/features/login/domain/entities/user_entity.dart';
|
||||
import 'package:auth/src/features/login/domain/get_me_user_use_case.dart';
|
||||
|
||||
class GetUserInfoUseCaseImpl implements GetUserInfoUseCase {
|
||||
GetUserInfoUseCaseImpl(this._repository);
|
||||
|
||||
final AuthRepository _repository;
|
||||
|
||||
@override
|
||||
Future<UserEntity> getUserInfo() {
|
||||
return _repository.getUserInfo();
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
import 'package:auth/src/core/providers/auth_repository_provider.dart';
|
||||
import 'package:auth/src/features/login/domain/get_me_user_use_case.dart';
|
||||
import 'package:auth/src/features/login/domain/get_me_user_use_case_impl.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
|
||||
final getUserInfoUseCaseProvider = Provider.autoDispose<GetUserInfoUseCase>((
|
||||
ref,
|
||||
) {
|
||||
final authRepository = ref.read(authRepositoryProvider);
|
||||
return GetUserInfoUseCaseImpl(authRepository);
|
||||
});
|
||||
@@ -1,9 +1,6 @@
|
||||
import 'package:auth/src/features/login/domain/entities/user_entity.dart';
|
||||
import 'package:auth/src/features/login/domain/get_me_user_use_case.dart';
|
||||
import 'package:auth/src/features/login/domain/login_use_case.dart';
|
||||
import 'package:auth/src/features/login/domain/two_fa_request_code_use_case.dart';
|
||||
import 'package:auth/src/features/login/domain/two_fa_send_code_use_case.dart';
|
||||
import 'package:auth/src/features/login/presentation/providers/get_user_info_provider.dart';
|
||||
import 'package:auth/src/features/login/presentation/providers/login_provider.dart';
|
||||
import 'package:auth/src/features/login/presentation/providers/two_fa_request_code_provider.dart';
|
||||
import 'package:auth/src/features/login/presentation/providers/two_fa_send_code_provider.dart';
|
||||
@@ -11,6 +8,7 @@ import 'package:auth/src/features/login/presentation/state/login_view_state.dart
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:sf_localizations/sf_localizations.dart';
|
||||
import 'package:sf_shared/sf_shared.dart';
|
||||
|
||||
final loginViewModelProvider =
|
||||
NotifierProvider.autoDispose<LoginViewModel, LoginViewState>(
|
||||
|
||||
@@ -32,6 +32,8 @@ class SCATreezorViewModel extends Notifier<SCATreezorViewState> {
|
||||
late final TreezorWalletConnectionService _connectionService;
|
||||
late final TreezorWalletSignatureService _signatureService;
|
||||
late final AuthRepository _authRepository;
|
||||
late final GetPaymentProfileUseCase _getPaymentProfileUseCase;
|
||||
late final GetUserInfoUseCase _getUserInfoUseCase;
|
||||
late final SessionLocalDatasource _sessionLocal;
|
||||
|
||||
late final TextEditingController codeController;
|
||||
@@ -52,6 +54,8 @@ class SCATreezorViewModel extends Notifier<SCATreezorViewState> {
|
||||
_connectionService = GetIt.I<TreezorWalletConnectionService>();
|
||||
_signatureService = GetIt.I<TreezorWalletSignatureService>();
|
||||
_authRepository = ref.read(authRepositoryProvider);
|
||||
_getPaymentProfileUseCase = ref.read(getPaymentProfileUseCaseProvider);
|
||||
_getUserInfoUseCase = ref.read(getUserInfoUseCaseProvider);
|
||||
_sessionLocal = ref.read(sessionLocalDatasourceProvider);
|
||||
codeController = TextEditingController();
|
||||
codeController.addListener(_onCodeChanged);
|
||||
@@ -317,8 +321,8 @@ class SCATreezorViewModel extends Notifier<SCATreezorViewState> {
|
||||
if (!connected) return false;
|
||||
|
||||
await signJwtSca();
|
||||
final user = await _authRepository.getUserInfo();
|
||||
final paymentProfile = await _authRepository.getPaymentProfile(
|
||||
final user = await _getUserInfoUseCase.getUserInfo();
|
||||
final paymentProfile = await _getPaymentProfileUseCase.getPaymentProfile(
|
||||
userId: user.id,
|
||||
);
|
||||
debugPrint(
|
||||
@@ -328,6 +332,7 @@ class SCATreezorViewModel extends Notifier<SCATreezorViewState> {
|
||||
if (paymentProfile.paymentWalletId == null ||
|
||||
paymentProfile.paymentWalletId!.isEmpty) {
|
||||
await _authRepository.createWallet();
|
||||
// tengo que coger la walletId de createWallet y pasarlo savePaymentProfileId
|
||||
await _sessionLocal.savePaymentProfileId(paymentProfile.paymentWalletId!);
|
||||
}
|
||||
// remove this when the backend starts returning the walletId on getUserInfo or getPaymentProfile
|
||||
|
||||
@@ -7,7 +7,6 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:navigation/navigation.dart';
|
||||
|
||||
class HomeScreen extends ConsumerWidget {
|
||||
final String name = "Juan";
|
||||
final double total = 95.03;
|
||||
final List<Kid> kids = [
|
||||
Kid(name: "Carlos", balance: 25.47, savings: 8.32),
|
||||
@@ -26,6 +25,11 @@ class HomeScreen extends ConsumerWidget {
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final theme = ref.watch(themePortProvider);
|
||||
final NavigationContract navigationContract = GetIt.I<NavigationContract>();
|
||||
final user = ref.watch(userInfoProvider);
|
||||
final rawName = user.value?.firstName ?? "";
|
||||
final name = rawName.isEmpty
|
||||
? ""
|
||||
: rawName[0].toUpperCase() + rawName.substring(1).toLowerCase();
|
||||
|
||||
return SafeArea(
|
||||
child: SingleChildScrollView(
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
export 'src/presentation/profile_screen.dart';
|
||||
export 'src/profile_builder.dart';
|
||||
export 'src/profile_settings_builder.dart';
|
||||
|
||||
@@ -80,17 +80,15 @@ class KidLineChart extends ConsumerWidget{
|
||||
return SideTitleWidget(
|
||||
space: 4,
|
||||
meta: meta,
|
||||
child: Expanded(
|
||||
child: Center(
|
||||
child: Text(
|
||||
text,
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: theme.getColorFor(ThemeCode.textSecondary)
|
||||
)
|
||||
)
|
||||
)
|
||||
child: Center(
|
||||
child: Text(
|
||||
text,
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: theme.getColorFor(ThemeCode.textSecondary),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
import 'package:design_system/design_system.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:navigation/navigation.dart';
|
||||
import 'package:notifications/notifications.dart';
|
||||
import 'package:profile/src/core/kid_line_chart.dart';
|
||||
import 'package:profile/src/settings_screen.dart';
|
||||
import 'package:sf_shared/sf_shared.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
|
||||
class ProfileScreen extends ConsumerWidget {
|
||||
const ProfileScreen({super.key});
|
||||
final NavigationContract navigationContract;
|
||||
|
||||
const ProfileScreen({super.key, required this.navigationContract});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
@@ -22,10 +24,14 @@ class ProfileScreen extends ConsumerWidget {
|
||||
|
||||
final kids = [
|
||||
Kid(name: "Ana", balance: 15, savings: 5),
|
||||
Kid(name: "Carlos", balance: 15, savings: 5)
|
||||
Kid(name: "Carlos", balance: 15, savings: 5),
|
||||
];
|
||||
|
||||
final name = "Juan";
|
||||
final user = ref.watch(userInfoProvider);
|
||||
final rawName = user.value?.firstName ?? "";
|
||||
final name = rawName.isEmpty
|
||||
? ""
|
||||
: rawName[0].toUpperCase() + rawName.substring(1).toLowerCase();
|
||||
final total = 95.03;
|
||||
final available = 44.09;
|
||||
final savings = 4.16;
|
||||
@@ -44,10 +50,8 @@ class ProfileScreen extends ConsumerWidget {
|
||||
),
|
||||
Spacer(),
|
||||
TextButton(
|
||||
onPressed: () => Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(builder: (_) => SettingsScreen()),
|
||||
),
|
||||
onPressed: () =>
|
||||
navigationContract.pushTo(AppRoutes.dashboardProfileSettings),
|
||||
child: Text(
|
||||
"Ajustes de la cuenta",
|
||||
style: TextStyle(
|
||||
@@ -57,7 +61,12 @@ class ProfileScreen extends ConsumerWidget {
|
||||
),
|
||||
],
|
||||
),
|
||||
WalletBalanceBlock(max: total, value: available, savings: savings, savingsPlan: savingsPlan),
|
||||
WalletBalanceBlock(
|
||||
max: total,
|
||||
value: available,
|
||||
savings: savings,
|
||||
savingsPlan: savingsPlan,
|
||||
),
|
||||
LineGraph(),
|
||||
DepositBlock(max: 150 - total),
|
||||
Container(
|
||||
@@ -67,33 +76,34 @@ class ProfileScreen extends ConsumerWidget {
|
||||
color: theme.getColorFor(ThemeCode.backgroundPrimary),
|
||||
),
|
||||
child: TextButton(
|
||||
onPressed: ()=>{},
|
||||
onPressed: () => {},
|
||||
child: Row(
|
||||
spacing: 10,
|
||||
children: [
|
||||
Icon(Icons.output_outlined,
|
||||
Icon(
|
||||
Icons.output_outlined,
|
||||
size: 24,
|
||||
color: theme.getColorFor(ThemeCode.textPrimary)
|
||||
color: theme.getColorFor(ThemeCode.textPrimary),
|
||||
),
|
||||
Text(
|
||||
"Retirar dinero del wallet",
|
||||
style: TextStyle(
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: theme.getColorFor(ThemeCode.textPrimary)
|
||||
)
|
||||
)
|
||||
color: theme.getColorFor(ThemeCode.textPrimary),
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
)
|
||||
),
|
||||
),
|
||||
),
|
||||
SingleChildScrollView(
|
||||
scrollDirection: Axis.horizontal,
|
||||
child: Row(
|
||||
spacing: 16,
|
||||
children: List<Widget>.generate(kids.length, (int index){
|
||||
children: List<Widget>.generate(kids.length, (int index) {
|
||||
return KidLineChart(kid: kids[index], index: index);
|
||||
})
|
||||
}),
|
||||
),
|
||||
),
|
||||
ActivityList(activity: activity, edit: false),
|
||||
@@ -105,7 +115,10 @@ class ProfileScreen extends ConsumerWidget {
|
||||
children: [
|
||||
DecoratedBox(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: const BorderRadius.only(bottomRight: Radius.circular(24), bottomLeft: Radius.circular(24)),
|
||||
borderRadius: const BorderRadius.only(
|
||||
bottomRight: Radius.circular(24),
|
||||
bottomLeft: Radius.circular(24),
|
||||
),
|
||||
color: Color(0xFF4B4B4B),
|
||||
),
|
||||
child: SizedBox(width: double.infinity, height: 200),
|
||||
|
||||
@@ -1,24 +1,79 @@
|
||||
import 'package:design_system/design_system.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:navigation/navigation.dart';
|
||||
import 'package:sealed_countries/sealed_countries.dart';
|
||||
import '../providers/payment_profile_provider.dart';
|
||||
|
||||
class SettingsScreen extends ConsumerWidget {
|
||||
const SettingsScreen({super.key});
|
||||
class ProfileSettingsScreen extends ConsumerWidget {
|
||||
final NavigationContract navigationContract;
|
||||
|
||||
const ProfileSettingsScreen({super.key, required this.navigationContract});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final theme = ref.watch(themePortProvider);
|
||||
final user = ref.watch(profileSettingsDataProvider);
|
||||
|
||||
final name = "Juan";
|
||||
final balance = 50;
|
||||
final fullName = "Juan Pérez Cruz";
|
||||
final birthDate = "08/03/1976";
|
||||
final relation = "Padre";
|
||||
final address = "Calle Gran Vía 30 6º, 28013";
|
||||
final country = "España";
|
||||
final nationality = "Español";
|
||||
final email = "juanpcruz@gmail.com";
|
||||
final phone = "123456789";
|
||||
return Scaffold(
|
||||
backgroundColor: theme.getColorFor(ThemeCode.backgroundSecondary),
|
||||
body: user.when(
|
||||
loading: () => Center(child: CircularProgressIndicator()),
|
||||
error: (error, _) => Center(
|
||||
child: Padding(
|
||||
padding: EdgeInsets.all(24),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Text(
|
||||
"Error al cargar el perfil",
|
||||
style: TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: theme.getColorFor(ThemeCode.textPrimary),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 8),
|
||||
Text(
|
||||
error.toString(),
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
color: theme.getColorFor(ThemeCode.textPrimary),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 16),
|
||||
TextButton(
|
||||
onPressed: () => ref.invalidate(profileSettingsDataProvider),
|
||||
child: Text("Reintentar"),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
data: (data) => _buildContent(context, ref, theme, data),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildContent(
|
||||
BuildContext context,
|
||||
WidgetRef ref,
|
||||
ThemePort theme,
|
||||
ProfileSettingsData data,
|
||||
) {
|
||||
final profile = data.paymentProfile;
|
||||
final firstName = _capitalize(data.user.firstName);
|
||||
final lastName = _capitalize(data.user.lastName);
|
||||
final fullName = '$firstName $lastName';
|
||||
final birthDate = _formatTimestamp(profile.bornAt);
|
||||
final address = profile.addresses.isNotEmpty
|
||||
? '${profile.addresses.first.street}, ${profile.addresses.first.postCode} ${profile.addresses.first.city}'
|
||||
: '-';
|
||||
final country = profile.addresses.isNotEmpty
|
||||
? profile.addresses.first.country
|
||||
: profile.birthCountry;
|
||||
final locale = Localizations.localeOf(context).languageCode;
|
||||
final nationality = _countryNameFromCode(profile.nationality, locale);
|
||||
|
||||
final content = [
|
||||
Center(
|
||||
@@ -31,12 +86,6 @@ class SettingsScreen extends ConsumerWidget {
|
||||
color: theme.getColorFor(ThemeCode.textSecondary),
|
||||
),
|
||||
),
|
||||
Text(
|
||||
"Saldo: $balance€",
|
||||
style: TextStyle(
|
||||
color: theme.getColorFor(ThemeCode.textSecondary),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
@@ -52,7 +101,7 @@ class SettingsScreen extends ConsumerWidget {
|
||||
spacing: 10,
|
||||
children: [
|
||||
Text(
|
||||
name,
|
||||
firstName,
|
||||
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20),
|
||||
),
|
||||
Spacer(),
|
||||
@@ -60,7 +109,15 @@ class SettingsScreen extends ConsumerWidget {
|
||||
Icon(Icons.account_balance, size: 24),
|
||||
],
|
||||
),
|
||||
Align(alignment: Alignment.centerLeft, child: Text(relation)),
|
||||
Align(
|
||||
alignment: Alignment.centerLeft,
|
||||
child: Text(
|
||||
data.user.status.toUpperCase(),
|
||||
style: TextStyle(
|
||||
color: theme.getColorFor(ThemeCode.textPrimary),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
@@ -82,50 +139,13 @@ class SettingsScreen extends ConsumerWidget {
|
||||
TextButton(onPressed: () => {}, child: Text("Editar")),
|
||||
],
|
||||
),
|
||||
Align(
|
||||
alignment: Alignment.centerLeft,
|
||||
child: Text.rich(
|
||||
TextSpan(
|
||||
text: "Nombre: ",
|
||||
style: TextStyle(fontWeight: FontWeight.bold),
|
||||
children: [
|
||||
TextSpan(
|
||||
text: fullName,
|
||||
style: TextStyle(fontWeight: FontWeight.normal),
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
),
|
||||
Align(
|
||||
alignment: Alignment.centerLeft,
|
||||
child: Text.rich(
|
||||
TextSpan(
|
||||
text: "Fecha de nacimiento: ",
|
||||
style: TextStyle(fontWeight: FontWeight.bold),
|
||||
children: [
|
||||
TextSpan(
|
||||
text: birthDate,
|
||||
style: TextStyle(fontWeight: FontWeight.normal),
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
),
|
||||
Align(
|
||||
alignment: Alignment.centerLeft,
|
||||
child: Text.rich(
|
||||
TextSpan(
|
||||
text: "Familiar: ",
|
||||
style: TextStyle(fontWeight: FontWeight.bold),
|
||||
children: [
|
||||
TextSpan(
|
||||
text: relation,
|
||||
style: TextStyle(fontWeight: FontWeight.normal),
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
_labelValue("Nombre", fullName),
|
||||
_labelValue("Fecha de nacimiento", birthDate),
|
||||
_labelValue("Nacionalidad", nationality),
|
||||
_labelValue("Lugar de nacimiento", profile.placeOfBirth),
|
||||
_labelValue(
|
||||
"Documento (${profile.documentType})",
|
||||
profile.document.toUpperCase(),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -148,51 +168,9 @@ class SettingsScreen extends ConsumerWidget {
|
||||
TextButton(onPressed: () => {}, child: Text("Editar")),
|
||||
],
|
||||
),
|
||||
Align(
|
||||
alignment: Alignment.centerLeft,
|
||||
child: Text.rich(
|
||||
TextSpan(
|
||||
text: "Dirección: ",
|
||||
style: TextStyle(fontWeight: FontWeight.bold),
|
||||
children: [
|
||||
TextSpan(
|
||||
text: address,
|
||||
style: TextStyle(fontWeight: FontWeight.normal),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
Align(
|
||||
alignment: Alignment.centerLeft,
|
||||
child: Text.rich(
|
||||
TextSpan(
|
||||
text: "País: ",
|
||||
style: TextStyle(fontWeight: FontWeight.bold),
|
||||
children: [
|
||||
TextSpan(
|
||||
text: country,
|
||||
style: TextStyle(fontWeight: FontWeight.normal),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
Align(
|
||||
alignment: Alignment.centerLeft,
|
||||
child: Text.rich(
|
||||
TextSpan(
|
||||
text: "Nacionalidad: ",
|
||||
style: TextStyle(fontWeight: FontWeight.bold),
|
||||
children: [
|
||||
TextSpan(
|
||||
text: nationality,
|
||||
style: TextStyle(fontWeight: FontWeight.normal),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
)
|
||||
_labelValue("Dirección", address),
|
||||
_labelValue("País", country),
|
||||
_labelValue("Nacionalidad", nationality),
|
||||
],
|
||||
),
|
||||
),
|
||||
@@ -214,36 +192,8 @@ class SettingsScreen extends ConsumerWidget {
|
||||
TextButton(onPressed: () => {}, child: Text("Editar")),
|
||||
],
|
||||
),
|
||||
Align(
|
||||
alignment: Alignment.centerLeft,
|
||||
child: Text.rich(
|
||||
TextSpan(
|
||||
text: "Correo: ",
|
||||
style: TextStyle(fontWeight: FontWeight.bold),
|
||||
children: [
|
||||
TextSpan(
|
||||
text: email,
|
||||
style: TextStyle(fontWeight: FontWeight.normal),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
Align(
|
||||
alignment: Alignment.centerLeft,
|
||||
child: Text.rich(
|
||||
TextSpan(
|
||||
text: "Teléfono: ",
|
||||
style: TextStyle(fontWeight: FontWeight.bold),
|
||||
children: [
|
||||
TextSpan(
|
||||
text: phone,
|
||||
style: TextStyle(fontWeight: FontWeight.normal),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
)
|
||||
_labelValue("Correo", data.user.email),
|
||||
_labelValue("Teléfono", profile.phone),
|
||||
],
|
||||
),
|
||||
),
|
||||
@@ -299,9 +249,11 @@ class SettingsScreen extends ConsumerWidget {
|
||||
"Retirar y reembolsar dinero del wallet",
|
||||
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20),
|
||||
),
|
||||
Text("Para transferirte el saldo a tu cuenta necesitamos tu IBAN y algunos datos básics. Así nos aseguramos de que la transferencia sea segura y rápida."),
|
||||
Text(
|
||||
"Para transferirte el saldo a tu cuenta necesitamos tu IBAN y algunos datos básics. Así nos aseguramos de que la transferencia sea segura y rápida.",
|
||||
),
|
||||
CustomTextField(label: "Nombre y Apellidos", hint: "******"),
|
||||
CustomTextField(label: "IBAN con número español", hint: "******")
|
||||
CustomTextField(label: "IBAN con número español", hint: "******"),
|
||||
],
|
||||
),
|
||||
),
|
||||
@@ -334,7 +286,7 @@ class SettingsScreen extends ConsumerWidget {
|
||||
style: TextStyle(fontSize: 16, letterSpacing: 0),
|
||||
),
|
||||
],
|
||||
)
|
||||
),
|
||||
),
|
||||
Align(
|
||||
alignment: Alignment.centerLeft,
|
||||
@@ -347,7 +299,7 @@ class SettingsScreen extends ConsumerWidget {
|
||||
style: TextStyle(fontSize: 16, letterSpacing: 0),
|
||||
),
|
||||
],
|
||||
)
|
||||
),
|
||||
),
|
||||
Align(
|
||||
alignment: Alignment.centerLeft,
|
||||
@@ -360,7 +312,7 @@ class SettingsScreen extends ConsumerWidget {
|
||||
style: TextStyle(fontSize: 16, letterSpacing: 0),
|
||||
),
|
||||
],
|
||||
)
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -371,89 +323,130 @@ class SettingsScreen extends ConsumerWidget {
|
||||
Align(
|
||||
alignment: Alignment.topLeft,
|
||||
child: TextButton(
|
||||
style: ButtonStyle(padding: WidgetStatePropertyAll(EdgeInsets.all(0))),
|
||||
style: ButtonStyle(
|
||||
padding: WidgetStatePropertyAll(EdgeInsets.all(0)),
|
||||
),
|
||||
onPressed: () => {},
|
||||
child: Row(
|
||||
spacing: 4,
|
||||
children: [
|
||||
Icon(Icons.contact_support_outlined, size: 24),
|
||||
Text("Contáctanos")
|
||||
Text("Contáctanos"),
|
||||
],
|
||||
)
|
||||
)
|
||||
),
|
||||
),
|
||||
),
|
||||
Align(
|
||||
alignment: Alignment.topLeft,
|
||||
child: TextButton(
|
||||
style: ButtonStyle(padding: WidgetStatePropertyAll(EdgeInsets.all(0))),
|
||||
style: ButtonStyle(
|
||||
padding: WidgetStatePropertyAll(EdgeInsets.all(0)),
|
||||
),
|
||||
onPressed: () => {},
|
||||
child: Row(
|
||||
spacing: 4,
|
||||
children: [
|
||||
Icon(Icons.contact_support_outlined, size: 24),
|
||||
Text("Preguntas frecuentes")
|
||||
Text("Preguntas frecuentes"),
|
||||
],
|
||||
)
|
||||
)
|
||||
),
|
||||
],
|
||||
)
|
||||
];
|
||||
|
||||
return Scaffold(
|
||||
backgroundColor: theme.getColorFor(ThemeCode.backgroundSecondary),
|
||||
body: Stack(
|
||||
children: [
|
||||
DecoratedBox(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: const BorderRadius.only(bottomLeft: Radius.circular(24), bottomRight: Radius.circular(24)),
|
||||
color: Color(0xFF4B4B4B),
|
||||
),
|
||||
),
|
||||
child: SizedBox(width: double.infinity, height: 200),
|
||||
),
|
||||
Column(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Container(
|
||||
margin: EdgeInsets.all(20),
|
||||
child: ListView.separated(
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
return content[index];
|
||||
},
|
||||
separatorBuilder: (BuildContext context, int index) {
|
||||
return Divider(color: Colors.transparent, height: 20);
|
||||
},
|
||||
itemCount: content.length,
|
||||
),
|
||||
),
|
||||
),
|
||||
Container(
|
||||
padding: EdgeInsets.all(20),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.only(
|
||||
topLeft: Radius.circular(20),
|
||||
topRight: Radius.circular(20),
|
||||
),
|
||||
color: theme.getColorFor(ThemeCode.backgroundPrimary),
|
||||
),
|
||||
child: Column(
|
||||
children: [
|
||||
PrimaryButton(
|
||||
onPressed: () => {},
|
||||
text: "Guardar cambios",
|
||||
color: theme.getColorFor(ThemeCode.buttonPrimary)
|
||||
),
|
||||
TextButton(
|
||||
onPressed: () => Navigator.pop(context),
|
||||
child: Text("Cancelar"),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
];
|
||||
|
||||
return Stack(
|
||||
children: [
|
||||
DecoratedBox(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: const BorderRadius.only(
|
||||
bottomLeft: Radius.circular(24),
|
||||
bottomRight: Radius.circular(24),
|
||||
),
|
||||
color: Color(0xFF4B4B4B),
|
||||
),
|
||||
child: SizedBox(width: double.infinity, height: 200),
|
||||
),
|
||||
Column(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Container(
|
||||
margin: EdgeInsets.all(20),
|
||||
child: ListView.separated(
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
return content[index];
|
||||
},
|
||||
separatorBuilder: (BuildContext context, int index) {
|
||||
return Divider(color: Colors.transparent, height: 20);
|
||||
},
|
||||
itemCount: content.length,
|
||||
),
|
||||
),
|
||||
),
|
||||
Container(
|
||||
padding: EdgeInsets.all(20),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.only(
|
||||
topLeft: Radius.circular(20),
|
||||
topRight: Radius.circular(20),
|
||||
),
|
||||
color: theme.getColorFor(ThemeCode.backgroundPrimary),
|
||||
),
|
||||
child: Column(
|
||||
children: [
|
||||
PrimaryButton(
|
||||
onPressed: () => {},
|
||||
text: "Guardar cambios",
|
||||
color: theme.getColorFor(ThemeCode.buttonPrimary),
|
||||
),
|
||||
TextButton(
|
||||
onPressed: () => navigationContract.goBack(),
|
||||
child: Text("Cancelar"),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget _labelValue(String label, String value) {
|
||||
return Align(
|
||||
alignment: Alignment.centerLeft,
|
||||
child: Text.rich(
|
||||
TextSpan(
|
||||
text: "$label: ",
|
||||
style: TextStyle(fontWeight: FontWeight.bold),
|
||||
children: [
|
||||
TextSpan(
|
||||
text: value,
|
||||
style: TextStyle(fontWeight: FontWeight.normal),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
String _capitalize(String s) =>
|
||||
s.isEmpty ? s : s[0].toUpperCase() + s.substring(1).toLowerCase();
|
||||
|
||||
String _countryNameFromCode(String code, String locale) {
|
||||
if (code.isEmpty) return '-';
|
||||
try {
|
||||
final country = WorldCountry.fromCodeShort(code.toUpperCase());
|
||||
final language = NaturalLanguage.fromCodeShort(locale);
|
||||
return country.commonNameFor(BasicTypedLocale(language));
|
||||
} catch (_) {
|
||||
return code;
|
||||
}
|
||||
}
|
||||
|
||||
String _formatTimestamp(int timestamp) {
|
||||
final date = DateTime.fromMillisecondsSinceEpoch(timestamp);
|
||||
return '${date.day.toString().padLeft(2, '0')}/${date.month.toString().padLeft(2, '0')}/${date.year}';
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,17 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get_it/get_it.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:navigation/navigation.dart';
|
||||
import 'package:profile/profile.dart';
|
||||
|
||||
class ProfileBuilder {
|
||||
const ProfileBuilder();
|
||||
|
||||
Page<void> buildPage(BuildContext context, GoRouterState state) {
|
||||
return MaterialPage(child: ProfileScreen());
|
||||
final navigationContract = GetIt.I<NavigationContract>();
|
||||
return MaterialPage(
|
||||
key: state.pageKey,
|
||||
child: ProfileScreen(navigationContract: navigationContract),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
17
modules/profile/lib/src/profile_settings_builder.dart
Normal file
17
modules/profile/lib/src/profile_settings_builder.dart
Normal file
@@ -0,0 +1,17 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get_it/get_it.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:navigation/navigation.dart';
|
||||
import 'package:profile/src/presentation/profile_settings_screen.dart';
|
||||
|
||||
class ProfileSettingsBuilder {
|
||||
const ProfileSettingsBuilder();
|
||||
|
||||
Page<void> buildPage(BuildContext context, GoRouterState state) {
|
||||
final navigationContract = GetIt.I<NavigationContract>();
|
||||
return MaterialPage(
|
||||
key: state.pageKey,
|
||||
child: ProfileSettingsScreen(navigationContract: navigationContract),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:sf_shared/sf_shared.dart';
|
||||
|
||||
class ProfileSettingsData {
|
||||
final UserEntity user;
|
||||
final PaymentProfileEntity paymentProfile;
|
||||
|
||||
const ProfileSettingsData({
|
||||
required this.user,
|
||||
required this.paymentProfile,
|
||||
});
|
||||
}
|
||||
|
||||
final profileSettingsDataProvider =
|
||||
FutureProvider.autoDispose<ProfileSettingsData>((ref) async {
|
||||
final getUserInfoUseCase = ref.read(getUserInfoUseCaseProvider);
|
||||
final getPaymentProfileUseCase = ref.read(getPaymentProfileUseCaseProvider);
|
||||
|
||||
final user = await getUserInfoUseCase.getUserInfo();
|
||||
final paymentProfile =
|
||||
await getPaymentProfileUseCase.getPaymentProfile(userId: user.id);
|
||||
|
||||
return ProfileSettingsData(
|
||||
user: user,
|
||||
paymentProfile: paymentProfile,
|
||||
);
|
||||
});
|
||||
@@ -20,8 +20,11 @@ dependencies:
|
||||
path: ../../packages/design_system
|
||||
sf_shared:
|
||||
path: ../../packages/sf_shared
|
||||
navigation:
|
||||
path: ../../packages/navigation
|
||||
|
||||
#dependencies go here
|
||||
sealed_countries: ^2.8.0
|
||||
flutter_riverpod: ^3.0.3
|
||||
get_it: ^9.0.5
|
||||
go_router: ^17.0.0
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# melos_managed_dependency_overrides: design_system,notifications,sf_shared,utils,fonts,sf_infrastructure,flutter_treezor_entrust_sdk_bridge,sca_treezor
|
||||
# melos_managed_dependency_overrides: design_system,notifications,sf_shared,utils,fonts,sf_infrastructure,flutter_treezor_entrust_sdk_bridge,sca_treezor,navigation
|
||||
dependency_overrides:
|
||||
design_system:
|
||||
path: ../../packages/design_system
|
||||
@@ -6,6 +6,8 @@ dependency_overrides:
|
||||
path: ../../packages/flutter_treezor_entrust_sdk_bridge
|
||||
fonts:
|
||||
path: ../../packages/fonts
|
||||
navigation:
|
||||
path: ../../packages/navigation
|
||||
notifications:
|
||||
path: ../notifications
|
||||
sca_treezor:
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
abstract class SplashRemoteDatasource {
|
||||
Future<List<dynamic>> getChildProfiles();
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
import 'package:sf_infrastructure/sf_infrastructure.dart';
|
||||
|
||||
import 'splash_remote_datasource.dart';
|
||||
|
||||
class SplashRemoteDatasourceImpl implements SplashRemoteDatasource {
|
||||
SplashRemoteDatasourceImpl(this._repository);
|
||||
|
||||
final QuestiaRepository _repository;
|
||||
|
||||
@override
|
||||
Future<List<dynamic>> getChildProfiles() async {
|
||||
final response =
|
||||
await _repository.get<Map<String, dynamic>>('/child-profiles');
|
||||
final data = response.data;
|
||||
if (data == null) return [];
|
||||
final items = data['items'] ?? data['data'] ?? [];
|
||||
return items is List ? items : [];
|
||||
}
|
||||
}
|
||||
@@ -1,18 +1,18 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:sf_shared/sf_shared.dart';
|
||||
|
||||
import '../data/splash_remote_datasource.dart';
|
||||
import 'check_session_use_case.dart';
|
||||
import 'initial_route.dart';
|
||||
|
||||
class CheckSessionUseCaseImpl implements CheckSessionUseCase {
|
||||
CheckSessionUseCaseImpl(this._datasource);
|
||||
CheckSessionUseCaseImpl(this._userRepository);
|
||||
|
||||
final SplashRemoteDatasource _datasource;
|
||||
final UserRepository _userRepository;
|
||||
|
||||
@override
|
||||
Future<InitialRoute> execute() async {
|
||||
try {
|
||||
final profiles = await _datasource.getChildProfiles();
|
||||
final profiles = await _userRepository.getChildProfiles();
|
||||
return profiles.isEmpty ? InitialRoute.deviceSetup : InitialRoute.home;
|
||||
} catch (e) {
|
||||
debugPrint('[CheckSessionUseCase] error: $e');
|
||||
|
||||
@@ -3,7 +3,7 @@ import 'package:get_it/get_it.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:navigation/navigation_contract.dart';
|
||||
import 'package:sf_infrastructure/sf_infrastructure.dart';
|
||||
import 'package:splash/src/data/splash_remote_datasource_impl.dart';
|
||||
import 'package:sf_shared/sf_shared.dart';
|
||||
import 'package:splash/src/domain/check_session_use_case_impl.dart';
|
||||
import 'package:splash/src/presentation/splash_screen.dart';
|
||||
|
||||
@@ -12,8 +12,9 @@ class SplashBuilder {
|
||||
|
||||
Page<void> buildPage(BuildContext context, GoRouterState state) {
|
||||
final navigationContract = GetIt.I<NavigationContract>();
|
||||
final datasource = SplashRemoteDatasourceImpl(GetIt.I<QuestiaRepository>());
|
||||
final checkSessionUseCase = CheckSessionUseCaseImpl(datasource);
|
||||
final remote = UserRemoteDatasourceImpl(GetIt.I<QuestiaRepository>());
|
||||
final userRepository = UserRepositoryImpl(remote);
|
||||
final checkSessionUseCase = CheckSessionUseCaseImpl(userRepository);
|
||||
|
||||
return NoTransitionPage(
|
||||
child: SplashScreen(
|
||||
|
||||
@@ -19,6 +19,8 @@ dependencies:
|
||||
path: ../../packages/navigation
|
||||
sf_infrastructure:
|
||||
path: ../../packages/sf_infrastructure
|
||||
sf_shared:
|
||||
path: ../../packages/sf_shared
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
sdk: flutter
|
||||
|
||||
@@ -1,4 +1,18 @@
|
||||
# melos_managed_dependency_overrides: navigation
|
||||
# melos_managed_dependency_overrides: navigation,sf_infrastructure,design_system,flutter_treezor_entrust_sdk_bridge,fonts,sca_treezor,sf_shared,utils
|
||||
dependency_overrides:
|
||||
design_system:
|
||||
path: ../../packages/design_system
|
||||
flutter_treezor_entrust_sdk_bridge:
|
||||
path: ../../packages/flutter_treezor_entrust_sdk_bridge
|
||||
fonts:
|
||||
path: ../../packages/fonts
|
||||
navigation:
|
||||
path: ../../packages/navigation
|
||||
sca_treezor:
|
||||
path: ../../packages/sca_treezor
|
||||
sf_infrastructure:
|
||||
path: ../../packages/sf_infrastructure
|
||||
sf_shared:
|
||||
path: ../../packages/sf_shared
|
||||
utils:
|
||||
path: ../../packages/utils
|
||||
|
||||
@@ -7,6 +7,6 @@
|
||||
<versions>
|
||||
<version>2.6.4</version>
|
||||
</versions>
|
||||
<lastUpdated>20260210000000</lastUpdated>
|
||||
<lastUpdated>20260212000000</lastUpdated>
|
||||
</versioning>
|
||||
</metadata>
|
||||
|
||||
@@ -1 +1 @@
|
||||
d77d08495d6aeaec19114b634957c84c
|
||||
299dd618be3c19b3aced93d75bb14a01
|
||||
@@ -1 +1 @@
|
||||
bdcbc45dfb9b2a6ccb485f2e1114aeef96a11ce7
|
||||
9967947368e66f19dfcef5b3d016f0fdfd89f20e
|
||||
@@ -15,4 +15,5 @@ class AppRoutes {
|
||||
static const dashboardActivity = '$dashboard/activity';
|
||||
static const dashboardNotifications = '$dashboard/notifications';
|
||||
static const dashboardProfile = '$dashboard/profile';
|
||||
static const dashboardProfileSettings = '$dashboardProfile/settings';
|
||||
}
|
||||
|
||||
@@ -13,3 +13,14 @@ export 'src/domain/entities/sca_wallet_entity.dart';
|
||||
export 'src/domain/use_cases/sca_wallets_use_case.dart';
|
||||
export 'src/domain/use_cases/send_jws_sesion_use_case.dart';
|
||||
export 'src/providers/send_jws_sesion_use_case_provider.dart';
|
||||
export 'src/domain/entities/payment_profile_entity.dart';
|
||||
export 'src/domain/use_cases/get_payment_profile_use_case.dart';
|
||||
export 'src/providers/get_payment_profile_use_case_provider.dart';
|
||||
export 'src/domain/entities/child_profile_entity.dart';
|
||||
export 'src/domain/entities/user_entity.dart';
|
||||
export 'src/domain/use_cases/get_user_info_use_case.dart';
|
||||
export 'src/providers/get_user_info_use_case_provider.dart';
|
||||
export 'src/providers/user_info_provider.dart';
|
||||
export 'src/domain/repositories/user_repository.dart';
|
||||
export 'src/data/repositories/user_repository_impl.dart';
|
||||
export 'src/data/datasource/user_remote_datasource_impl.dart';
|
||||
|
||||
@@ -1,7 +1,12 @@
|
||||
import 'package:sf_shared/src/data/models/payment_profile_response_model.dart';
|
||||
import 'package:sf_shared/src/data/models/sca_wallet_model.dart';
|
||||
|
||||
abstract class TreezorRemoteDatasource {
|
||||
Future<ScaWalletsResponseModel> scaWallets();
|
||||
|
||||
Future<bool> sendJWSSesion({required String jws});
|
||||
|
||||
Future<PaymentProfileResponseModel> getPaymentProfile({
|
||||
required String userId,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ import 'dart:convert';
|
||||
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:sf_infrastructure/sf_infrastructure.dart';
|
||||
import 'package:sf_shared/src/data/models/payment_profile_response_model.dart';
|
||||
import 'package:sf_shared/src/data/models/sca_wallet_model.dart';
|
||||
|
||||
import 'treezor_remote_data_source.dart';
|
||||
@@ -61,6 +62,28 @@ class TreezorRemoteDatasourceImpl implements TreezorRemoteDatasource {
|
||||
);
|
||||
}
|
||||
}
|
||||
@override
|
||||
Future<PaymentProfileResponseModel> getPaymentProfile({
|
||||
required String userId,
|
||||
}) async {
|
||||
try {
|
||||
final response = await _repository.get<Map<String, dynamic>>(
|
||||
'/users/$userId/payment-profile',
|
||||
);
|
||||
|
||||
final data = response.data;
|
||||
if (data == null || data.isEmpty) {
|
||||
throw Exception('Empty response from /users/$userId/payment-profile');
|
||||
}
|
||||
|
||||
return PaymentProfileResponseModel.fromJson(data);
|
||||
} on DioException catch (error) {
|
||||
throw _mapDioError(
|
||||
error,
|
||||
defaultMessage: 'Error in /users/$userId/payment-profile',
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Exception _mapDioError(DioException error, {required String defaultMessage}) {
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
import 'package:sf_shared/src/data/models/child_profile_response_model.dart';
|
||||
import 'package:sf_shared/src/data/models/user_response_model.dart';
|
||||
|
||||
abstract class UserRemoteDatasource {
|
||||
Future<UserModel> getUserInfo();
|
||||
Future<ChildProfileResponseModel> getChildProfiles();
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:sf_infrastructure/sf_infrastructure.dart';
|
||||
import 'package:sf_shared/src/data/models/child_profile_response_model.dart';
|
||||
import 'package:sf_shared/src/data/models/user_response_model.dart';
|
||||
|
||||
import 'user_remote_datasource.dart';
|
||||
|
||||
class UserRemoteDatasourceImpl implements UserRemoteDatasource {
|
||||
UserRemoteDatasourceImpl(this._repository);
|
||||
|
||||
final QuestiaRepository _repository;
|
||||
|
||||
@override
|
||||
Future<UserModel> getUserInfo() async {
|
||||
try {
|
||||
final response = await _repository.get<Map<String, dynamic>>('/auth/me');
|
||||
|
||||
final data = response.data;
|
||||
if (data == null || data.isEmpty) {
|
||||
throw Exception('Empty response from /auth/me');
|
||||
}
|
||||
|
||||
final parsed = UserResponseModel.fromJson(data);
|
||||
return parsed.item;
|
||||
} on DioException catch (error) {
|
||||
final apiMsg = error.response?.data;
|
||||
final msg = apiMsg is String ? apiMsg : (error.message ?? 'Error in /auth/me');
|
||||
throw Exception(msg);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<ChildProfileResponseModel> getChildProfiles() async {
|
||||
final response =
|
||||
await _repository.get<Map<String, dynamic>>('/child-profiles');
|
||||
final data = response.data;
|
||||
if (data == null) {
|
||||
throw Exception('Empty response from /child-profiles');
|
||||
}
|
||||
return ChildProfileResponseModel.fromJson(data);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'package:sf_shared/src/domain/entities/child_profile_entity.dart';
|
||||
|
||||
part 'child_profile_response_model.freezed.dart';
|
||||
part 'child_profile_response_model.g.dart';
|
||||
|
||||
@freezed
|
||||
abstract class ChildProfileResponseModel with _$ChildProfileResponseModel {
|
||||
const factory ChildProfileResponseModel({
|
||||
required int total,
|
||||
required List<ChildProfileModel> items,
|
||||
required int page,
|
||||
required int pages,
|
||||
}) = _ChildProfileResponseModel;
|
||||
|
||||
factory ChildProfileResponseModel.fromJson(Map<String, dynamic> json) =>
|
||||
_$ChildProfileResponseModelFromJson(json);
|
||||
}
|
||||
|
||||
@freezed
|
||||
abstract class ChildProfileModel with _$ChildProfileModel {
|
||||
const factory ChildProfileModel({
|
||||
required String id,
|
||||
required String deviceIdentificator,
|
||||
required String parentId,
|
||||
required String firstName,
|
||||
required String lastName,
|
||||
required int bornAt,
|
||||
required String walletId,
|
||||
required String treezorUserId,
|
||||
required String address,
|
||||
required int createdAt,
|
||||
}) = _ChildProfileModel;
|
||||
|
||||
factory ChildProfileModel.fromJson(Map<String, dynamic> json) =>
|
||||
_$ChildProfileModelFromJson(json);
|
||||
}
|
||||
|
||||
extension ChildProfileModelMapper on ChildProfileModel {
|
||||
ChildProfileEntity toEntity() {
|
||||
return ChildProfileEntity(
|
||||
id: id,
|
||||
deviceIdentificator: deviceIdentificator,
|
||||
parentId: parentId,
|
||||
firstName: firstName,
|
||||
lastName: lastName,
|
||||
bornAt: bornAt,
|
||||
walletId: walletId,
|
||||
treezorUserId: treezorUserId,
|
||||
address: address,
|
||||
createdAt: createdAt,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,582 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
// coverage:ignore-file
|
||||
// ignore_for_file: type=lint
|
||||
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark
|
||||
|
||||
part of 'child_profile_response_model.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// FreezedGenerator
|
||||
// **************************************************************************
|
||||
|
||||
// dart format off
|
||||
T _$identity<T>(T value) => value;
|
||||
|
||||
/// @nodoc
|
||||
mixin _$ChildProfileResponseModel {
|
||||
|
||||
int get total; List<ChildProfileModel> get items; int get page; int get pages;
|
||||
/// Create a copy of ChildProfileResponseModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
$ChildProfileResponseModelCopyWith<ChildProfileResponseModel> get copyWith => _$ChildProfileResponseModelCopyWithImpl<ChildProfileResponseModel>(this as ChildProfileResponseModel, _$identity);
|
||||
|
||||
/// Serializes this ChildProfileResponseModel to a JSON map.
|
||||
Map<String, dynamic> toJson();
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is ChildProfileResponseModel&&(identical(other.total, total) || other.total == total)&&const DeepCollectionEquality().equals(other.items, items)&&(identical(other.page, page) || other.page == page)&&(identical(other.pages, pages) || other.pages == pages));
|
||||
}
|
||||
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,total,const DeepCollectionEquality().hash(items),page,pages);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'ChildProfileResponseModel(total: $total, items: $items, page: $page, pages: $pages)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class $ChildProfileResponseModelCopyWith<$Res> {
|
||||
factory $ChildProfileResponseModelCopyWith(ChildProfileResponseModel value, $Res Function(ChildProfileResponseModel) _then) = _$ChildProfileResponseModelCopyWithImpl;
|
||||
@useResult
|
||||
$Res call({
|
||||
int total, List<ChildProfileModel> items, int page, int pages
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class _$ChildProfileResponseModelCopyWithImpl<$Res>
|
||||
implements $ChildProfileResponseModelCopyWith<$Res> {
|
||||
_$ChildProfileResponseModelCopyWithImpl(this._self, this._then);
|
||||
|
||||
final ChildProfileResponseModel _self;
|
||||
final $Res Function(ChildProfileResponseModel) _then;
|
||||
|
||||
/// Create a copy of ChildProfileResponseModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline') @override $Res call({Object? total = null,Object? items = null,Object? page = null,Object? pages = null,}) {
|
||||
return _then(_self.copyWith(
|
||||
total: null == total ? _self.total : total // ignore: cast_nullable_to_non_nullable
|
||||
as int,items: null == items ? _self.items : items // ignore: cast_nullable_to_non_nullable
|
||||
as List<ChildProfileModel>,page: null == page ? _self.page : page // ignore: cast_nullable_to_non_nullable
|
||||
as int,pages: null == pages ? _self.pages : pages // ignore: cast_nullable_to_non_nullable
|
||||
as int,
|
||||
));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// Adds pattern-matching-related methods to [ChildProfileResponseModel].
|
||||
extension ChildProfileResponseModelPatterns on ChildProfileResponseModel {
|
||||
/// A variant of `map` that fallback to returning `orElse`.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return orElse();
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _ChildProfileResponseModel value)? $default,{required TResult orElse(),}){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _ChildProfileResponseModel() when $default != null:
|
||||
return $default(_that);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
}
|
||||
/// A `switch`-like method, using callbacks.
|
||||
///
|
||||
/// Callbacks receives the raw object, upcasted.
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case final Subclass2 value:
|
||||
/// return ...;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _ChildProfileResponseModel value) $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _ChildProfileResponseModel():
|
||||
return $default(_that);case _:
|
||||
throw StateError('Unexpected subclass');
|
||||
|
||||
}
|
||||
}
|
||||
/// A variant of `map` that fallback to returning `null`.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return null;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _ChildProfileResponseModel value)? $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _ChildProfileResponseModel() when $default != null:
|
||||
return $default(_that);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
/// A variant of `when` that fallback to an `orElse` callback.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return orElse();
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( int total, List<ChildProfileModel> items, int page, int pages)? $default,{required TResult orElse(),}) {final _that = this;
|
||||
switch (_that) {
|
||||
case _ChildProfileResponseModel() when $default != null:
|
||||
return $default(_that.total,_that.items,_that.page,_that.pages);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
}
|
||||
/// A `switch`-like method, using callbacks.
|
||||
///
|
||||
/// As opposed to `map`, this offers destructuring.
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case Subclass2(:final field2):
|
||||
/// return ...;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( int total, List<ChildProfileModel> items, int page, int pages) $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _ChildProfileResponseModel():
|
||||
return $default(_that.total,_that.items,_that.page,_that.pages);case _:
|
||||
throw StateError('Unexpected subclass');
|
||||
|
||||
}
|
||||
}
|
||||
/// A variant of `when` that fallback to returning `null`
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return null;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( int total, List<ChildProfileModel> items, int page, int pages)? $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _ChildProfileResponseModel() when $default != null:
|
||||
return $default(_that.total,_that.items,_that.page,_that.pages);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
@JsonSerializable()
|
||||
|
||||
class _ChildProfileResponseModel implements ChildProfileResponseModel {
|
||||
const _ChildProfileResponseModel({required this.total, required final List<ChildProfileModel> items, required this.page, required this.pages}): _items = items;
|
||||
factory _ChildProfileResponseModel.fromJson(Map<String, dynamic> json) => _$ChildProfileResponseModelFromJson(json);
|
||||
|
||||
@override final int total;
|
||||
final List<ChildProfileModel> _items;
|
||||
@override List<ChildProfileModel> get items {
|
||||
if (_items is EqualUnmodifiableListView) return _items;
|
||||
// ignore: implicit_dynamic_type
|
||||
return EqualUnmodifiableListView(_items);
|
||||
}
|
||||
|
||||
@override final int page;
|
||||
@override final int pages;
|
||||
|
||||
/// Create a copy of ChildProfileResponseModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
_$ChildProfileResponseModelCopyWith<_ChildProfileResponseModel> get copyWith => __$ChildProfileResponseModelCopyWithImpl<_ChildProfileResponseModel>(this, _$identity);
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
return _$ChildProfileResponseModelToJson(this, );
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _ChildProfileResponseModel&&(identical(other.total, total) || other.total == total)&&const DeepCollectionEquality().equals(other._items, _items)&&(identical(other.page, page) || other.page == page)&&(identical(other.pages, pages) || other.pages == pages));
|
||||
}
|
||||
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,total,const DeepCollectionEquality().hash(_items),page,pages);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'ChildProfileResponseModel(total: $total, items: $items, page: $page, pages: $pages)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class _$ChildProfileResponseModelCopyWith<$Res> implements $ChildProfileResponseModelCopyWith<$Res> {
|
||||
factory _$ChildProfileResponseModelCopyWith(_ChildProfileResponseModel value, $Res Function(_ChildProfileResponseModel) _then) = __$ChildProfileResponseModelCopyWithImpl;
|
||||
@override @useResult
|
||||
$Res call({
|
||||
int total, List<ChildProfileModel> items, int page, int pages
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class __$ChildProfileResponseModelCopyWithImpl<$Res>
|
||||
implements _$ChildProfileResponseModelCopyWith<$Res> {
|
||||
__$ChildProfileResponseModelCopyWithImpl(this._self, this._then);
|
||||
|
||||
final _ChildProfileResponseModel _self;
|
||||
final $Res Function(_ChildProfileResponseModel) _then;
|
||||
|
||||
/// Create a copy of ChildProfileResponseModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @pragma('vm:prefer-inline') $Res call({Object? total = null,Object? items = null,Object? page = null,Object? pages = null,}) {
|
||||
return _then(_ChildProfileResponseModel(
|
||||
total: null == total ? _self.total : total // ignore: cast_nullable_to_non_nullable
|
||||
as int,items: null == items ? _self._items : items // ignore: cast_nullable_to_non_nullable
|
||||
as List<ChildProfileModel>,page: null == page ? _self.page : page // ignore: cast_nullable_to_non_nullable
|
||||
as int,pages: null == pages ? _self.pages : pages // ignore: cast_nullable_to_non_nullable
|
||||
as int,
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// @nodoc
|
||||
mixin _$ChildProfileModel {
|
||||
|
||||
String get id; String get deviceIdentificator; String get parentId; String get firstName; String get lastName; int get bornAt; String get walletId; String get treezorUserId; String get address; int get createdAt;
|
||||
/// Create a copy of ChildProfileModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
$ChildProfileModelCopyWith<ChildProfileModel> get copyWith => _$ChildProfileModelCopyWithImpl<ChildProfileModel>(this as ChildProfileModel, _$identity);
|
||||
|
||||
/// Serializes this ChildProfileModel to a JSON map.
|
||||
Map<String, dynamic> toJson();
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is ChildProfileModel&&(identical(other.id, id) || other.id == id)&&(identical(other.deviceIdentificator, deviceIdentificator) || other.deviceIdentificator == deviceIdentificator)&&(identical(other.parentId, parentId) || other.parentId == parentId)&&(identical(other.firstName, firstName) || other.firstName == firstName)&&(identical(other.lastName, lastName) || other.lastName == lastName)&&(identical(other.bornAt, bornAt) || other.bornAt == bornAt)&&(identical(other.walletId, walletId) || other.walletId == walletId)&&(identical(other.treezorUserId, treezorUserId) || other.treezorUserId == treezorUserId)&&(identical(other.address, address) || other.address == address)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt));
|
||||
}
|
||||
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,id,deviceIdentificator,parentId,firstName,lastName,bornAt,walletId,treezorUserId,address,createdAt);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'ChildProfileModel(id: $id, deviceIdentificator: $deviceIdentificator, parentId: $parentId, firstName: $firstName, lastName: $lastName, bornAt: $bornAt, walletId: $walletId, treezorUserId: $treezorUserId, address: $address, createdAt: $createdAt)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class $ChildProfileModelCopyWith<$Res> {
|
||||
factory $ChildProfileModelCopyWith(ChildProfileModel value, $Res Function(ChildProfileModel) _then) = _$ChildProfileModelCopyWithImpl;
|
||||
@useResult
|
||||
$Res call({
|
||||
String id, String deviceIdentificator, String parentId, String firstName, String lastName, int bornAt, String walletId, String treezorUserId, String address, int createdAt
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class _$ChildProfileModelCopyWithImpl<$Res>
|
||||
implements $ChildProfileModelCopyWith<$Res> {
|
||||
_$ChildProfileModelCopyWithImpl(this._self, this._then);
|
||||
|
||||
final ChildProfileModel _self;
|
||||
final $Res Function(ChildProfileModel) _then;
|
||||
|
||||
/// Create a copy of ChildProfileModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? deviceIdentificator = null,Object? parentId = null,Object? firstName = null,Object? lastName = null,Object? bornAt = null,Object? walletId = null,Object? treezorUserId = null,Object? address = null,Object? createdAt = null,}) {
|
||||
return _then(_self.copyWith(
|
||||
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
||||
as String,deviceIdentificator: null == deviceIdentificator ? _self.deviceIdentificator : deviceIdentificator // ignore: cast_nullable_to_non_nullable
|
||||
as String,parentId: null == parentId ? _self.parentId : parentId // ignore: cast_nullable_to_non_nullable
|
||||
as String,firstName: null == firstName ? _self.firstName : firstName // ignore: cast_nullable_to_non_nullable
|
||||
as String,lastName: null == lastName ? _self.lastName : lastName // ignore: cast_nullable_to_non_nullable
|
||||
as String,bornAt: null == bornAt ? _self.bornAt : bornAt // ignore: cast_nullable_to_non_nullable
|
||||
as int,walletId: null == walletId ? _self.walletId : walletId // ignore: cast_nullable_to_non_nullable
|
||||
as String,treezorUserId: null == treezorUserId ? _self.treezorUserId : treezorUserId // ignore: cast_nullable_to_non_nullable
|
||||
as String,address: null == address ? _self.address : address // ignore: cast_nullable_to_non_nullable
|
||||
as String,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
|
||||
as int,
|
||||
));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// Adds pattern-matching-related methods to [ChildProfileModel].
|
||||
extension ChildProfileModelPatterns on ChildProfileModel {
|
||||
/// A variant of `map` that fallback to returning `orElse`.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return orElse();
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _ChildProfileModel value)? $default,{required TResult orElse(),}){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _ChildProfileModel() when $default != null:
|
||||
return $default(_that);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
}
|
||||
/// A `switch`-like method, using callbacks.
|
||||
///
|
||||
/// Callbacks receives the raw object, upcasted.
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case final Subclass2 value:
|
||||
/// return ...;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _ChildProfileModel value) $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _ChildProfileModel():
|
||||
return $default(_that);case _:
|
||||
throw StateError('Unexpected subclass');
|
||||
|
||||
}
|
||||
}
|
||||
/// A variant of `map` that fallback to returning `null`.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return null;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _ChildProfileModel value)? $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _ChildProfileModel() when $default != null:
|
||||
return $default(_that);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
/// A variant of `when` that fallback to an `orElse` callback.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return orElse();
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String id, String deviceIdentificator, String parentId, String firstName, String lastName, int bornAt, String walletId, String treezorUserId, String address, int createdAt)? $default,{required TResult orElse(),}) {final _that = this;
|
||||
switch (_that) {
|
||||
case _ChildProfileModel() when $default != null:
|
||||
return $default(_that.id,_that.deviceIdentificator,_that.parentId,_that.firstName,_that.lastName,_that.bornAt,_that.walletId,_that.treezorUserId,_that.address,_that.createdAt);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
}
|
||||
/// A `switch`-like method, using callbacks.
|
||||
///
|
||||
/// As opposed to `map`, this offers destructuring.
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case Subclass2(:final field2):
|
||||
/// return ...;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String id, String deviceIdentificator, String parentId, String firstName, String lastName, int bornAt, String walletId, String treezorUserId, String address, int createdAt) $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _ChildProfileModel():
|
||||
return $default(_that.id,_that.deviceIdentificator,_that.parentId,_that.firstName,_that.lastName,_that.bornAt,_that.walletId,_that.treezorUserId,_that.address,_that.createdAt);case _:
|
||||
throw StateError('Unexpected subclass');
|
||||
|
||||
}
|
||||
}
|
||||
/// A variant of `when` that fallback to returning `null`
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return null;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String id, String deviceIdentificator, String parentId, String firstName, String lastName, int bornAt, String walletId, String treezorUserId, String address, int createdAt)? $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _ChildProfileModel() when $default != null:
|
||||
return $default(_that.id,_that.deviceIdentificator,_that.parentId,_that.firstName,_that.lastName,_that.bornAt,_that.walletId,_that.treezorUserId,_that.address,_that.createdAt);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
@JsonSerializable()
|
||||
|
||||
class _ChildProfileModel implements ChildProfileModel {
|
||||
const _ChildProfileModel({required this.id, required this.deviceIdentificator, required this.parentId, required this.firstName, required this.lastName, required this.bornAt, required this.walletId, required this.treezorUserId, required this.address, required this.createdAt});
|
||||
factory _ChildProfileModel.fromJson(Map<String, dynamic> json) => _$ChildProfileModelFromJson(json);
|
||||
|
||||
@override final String id;
|
||||
@override final String deviceIdentificator;
|
||||
@override final String parentId;
|
||||
@override final String firstName;
|
||||
@override final String lastName;
|
||||
@override final int bornAt;
|
||||
@override final String walletId;
|
||||
@override final String treezorUserId;
|
||||
@override final String address;
|
||||
@override final int createdAt;
|
||||
|
||||
/// Create a copy of ChildProfileModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
_$ChildProfileModelCopyWith<_ChildProfileModel> get copyWith => __$ChildProfileModelCopyWithImpl<_ChildProfileModel>(this, _$identity);
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
return _$ChildProfileModelToJson(this, );
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _ChildProfileModel&&(identical(other.id, id) || other.id == id)&&(identical(other.deviceIdentificator, deviceIdentificator) || other.deviceIdentificator == deviceIdentificator)&&(identical(other.parentId, parentId) || other.parentId == parentId)&&(identical(other.firstName, firstName) || other.firstName == firstName)&&(identical(other.lastName, lastName) || other.lastName == lastName)&&(identical(other.bornAt, bornAt) || other.bornAt == bornAt)&&(identical(other.walletId, walletId) || other.walletId == walletId)&&(identical(other.treezorUserId, treezorUserId) || other.treezorUserId == treezorUserId)&&(identical(other.address, address) || other.address == address)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt));
|
||||
}
|
||||
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,id,deviceIdentificator,parentId,firstName,lastName,bornAt,walletId,treezorUserId,address,createdAt);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'ChildProfileModel(id: $id, deviceIdentificator: $deviceIdentificator, parentId: $parentId, firstName: $firstName, lastName: $lastName, bornAt: $bornAt, walletId: $walletId, treezorUserId: $treezorUserId, address: $address, createdAt: $createdAt)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class _$ChildProfileModelCopyWith<$Res> implements $ChildProfileModelCopyWith<$Res> {
|
||||
factory _$ChildProfileModelCopyWith(_ChildProfileModel value, $Res Function(_ChildProfileModel) _then) = __$ChildProfileModelCopyWithImpl;
|
||||
@override @useResult
|
||||
$Res call({
|
||||
String id, String deviceIdentificator, String parentId, String firstName, String lastName, int bornAt, String walletId, String treezorUserId, String address, int createdAt
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class __$ChildProfileModelCopyWithImpl<$Res>
|
||||
implements _$ChildProfileModelCopyWith<$Res> {
|
||||
__$ChildProfileModelCopyWithImpl(this._self, this._then);
|
||||
|
||||
final _ChildProfileModel _self;
|
||||
final $Res Function(_ChildProfileModel) _then;
|
||||
|
||||
/// Create a copy of ChildProfileModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? deviceIdentificator = null,Object? parentId = null,Object? firstName = null,Object? lastName = null,Object? bornAt = null,Object? walletId = null,Object? treezorUserId = null,Object? address = null,Object? createdAt = null,}) {
|
||||
return _then(_ChildProfileModel(
|
||||
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
||||
as String,deviceIdentificator: null == deviceIdentificator ? _self.deviceIdentificator : deviceIdentificator // ignore: cast_nullable_to_non_nullable
|
||||
as String,parentId: null == parentId ? _self.parentId : parentId // ignore: cast_nullable_to_non_nullable
|
||||
as String,firstName: null == firstName ? _self.firstName : firstName // ignore: cast_nullable_to_non_nullable
|
||||
as String,lastName: null == lastName ? _self.lastName : lastName // ignore: cast_nullable_to_non_nullable
|
||||
as String,bornAt: null == bornAt ? _self.bornAt : bornAt // ignore: cast_nullable_to_non_nullable
|
||||
as int,walletId: null == walletId ? _self.walletId : walletId // ignore: cast_nullable_to_non_nullable
|
||||
as String,treezorUserId: null == treezorUserId ? _self.treezorUserId : treezorUserId // ignore: cast_nullable_to_non_nullable
|
||||
as String,address: null == address ? _self.address : address // ignore: cast_nullable_to_non_nullable
|
||||
as String,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
|
||||
as int,
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// dart format on
|
||||
@@ -0,0 +1,55 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'child_profile_response_model.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
_ChildProfileResponseModel _$ChildProfileResponseModelFromJson(
|
||||
Map<String, dynamic> json,
|
||||
) => _ChildProfileResponseModel(
|
||||
total: (json['total'] as num).toInt(),
|
||||
items: (json['items'] as List<dynamic>)
|
||||
.map((e) => ChildProfileModel.fromJson(e as Map<String, dynamic>))
|
||||
.toList(),
|
||||
page: (json['page'] as num).toInt(),
|
||||
pages: (json['pages'] as num).toInt(),
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$ChildProfileResponseModelToJson(
|
||||
_ChildProfileResponseModel instance,
|
||||
) => <String, dynamic>{
|
||||
'total': instance.total,
|
||||
'items': instance.items,
|
||||
'page': instance.page,
|
||||
'pages': instance.pages,
|
||||
};
|
||||
|
||||
_ChildProfileModel _$ChildProfileModelFromJson(Map<String, dynamic> json) =>
|
||||
_ChildProfileModel(
|
||||
id: json['id'] as String,
|
||||
deviceIdentificator: json['deviceIdentificator'] as String,
|
||||
parentId: json['parentId'] as String,
|
||||
firstName: json['firstName'] as String,
|
||||
lastName: json['lastName'] as String,
|
||||
bornAt: (json['bornAt'] as num).toInt(),
|
||||
walletId: json['walletId'] as String,
|
||||
treezorUserId: json['treezorUserId'] as String,
|
||||
address: json['address'] as String,
|
||||
createdAt: (json['createdAt'] as num).toInt(),
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$ChildProfileModelToJson(_ChildProfileModel instance) =>
|
||||
<String, dynamic>{
|
||||
'id': instance.id,
|
||||
'deviceIdentificator': instance.deviceIdentificator,
|
||||
'parentId': instance.parentId,
|
||||
'firstName': instance.firstName,
|
||||
'lastName': instance.lastName,
|
||||
'bornAt': instance.bornAt,
|
||||
'walletId': instance.walletId,
|
||||
'treezorUserId': instance.treezorUserId,
|
||||
'address': instance.address,
|
||||
'createdAt': instance.createdAt,
|
||||
};
|
||||
@@ -1,4 +1,4 @@
|
||||
import 'package:auth/src/features/login/domain/entities/payment_profile_entity.dart';
|
||||
import 'package:sf_shared/src/domain/entities/payment_profile_entity.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
part 'payment_profile_response_model.freezed.dart';
|
||||
@@ -26,7 +26,6 @@ abstract class PaymentProfileItemModel with _$PaymentProfileItemModel {
|
||||
required List<PaymentProfileAddressModel> taxResidences,
|
||||
required List<PaymentProfileAddressModel> addresses,
|
||||
required String status,
|
||||
//talk with Hector to change those names in the backend to be more consistent with the rest of the fields
|
||||
// ignore: non_constant_identifier_names
|
||||
required String KYCStatus,
|
||||
// ignore: non_constant_identifier_names
|
||||
@@ -296,8 +296,7 @@ $PaymentProfileItemModelCopyWith<$Res> get item {
|
||||
/// @nodoc
|
||||
mixin _$PaymentProfileItemModel {
|
||||
|
||||
String get id; String get userId; String get paymentProfileId; String? get jwt; int get bornAt; String get phone; List<PaymentProfileAddressModel> get taxResidences; List<PaymentProfileAddressModel> get addresses; String get status;//talk with Hector to change those names in the backend to be more consistent with the rest of the fields
|
||||
// ignore: non_constant_identifier_names
|
||||
String get id; String get userId; String get paymentProfileId; String? get jwt; int get bornAt; String get phone; List<PaymentProfileAddressModel> get taxResidences; List<PaymentProfileAddressModel> get addresses; String get status;// ignore: non_constant_identifier_names
|
||||
String get KYCStatus;// ignore: non_constant_identifier_names
|
||||
String get KYCLevel; String get placeOfBirth; String get birthCountry; String get nationality; String get documentType; String get document; String? get paymentWalletId; int get createdAt;
|
||||
/// Create a copy of PaymentProfileItemModel
|
||||
@@ -534,7 +533,6 @@ class _PaymentProfileItemModel implements PaymentProfileItemModel {
|
||||
}
|
||||
|
||||
@override final String status;
|
||||
//talk with Hector to change those names in the backend to be more consistent with the rest of the fields
|
||||
// ignore: non_constant_identifier_names
|
||||
@override final String KYCStatus;
|
||||
// ignore: non_constant_identifier_names
|
||||
@@ -1,4 +1,5 @@
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'package:sf_shared/src/domain/entities/user_entity.dart';
|
||||
|
||||
part 'user_response_model.freezed.dart';
|
||||
part 'user_response_model.g.dart';
|
||||
@@ -34,3 +35,24 @@ abstract class UserModel with _$UserModel {
|
||||
factory UserModel.fromJson(Map<String, dynamic> json) =>
|
||||
_$UserModelFromJson(json);
|
||||
}
|
||||
|
||||
extension UserModelMapper on UserModel {
|
||||
UserEntity toEntity() {
|
||||
return UserEntity(
|
||||
id: id,
|
||||
delegationId: delegationId,
|
||||
email: email,
|
||||
createdAt: createdAt,
|
||||
updatedAt: updatedAt,
|
||||
status: status,
|
||||
role: role,
|
||||
lastLogin: lastLogin,
|
||||
currentLogin: currentLogin,
|
||||
language: language,
|
||||
firstName: firstName,
|
||||
lastName: lastName,
|
||||
hasApiKey: hasApiKey,
|
||||
phone: phone,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,6 @@
|
||||
import 'package:sf_shared/src/data/models/payment_profile_response_model.dart';
|
||||
import 'package:sf_shared/src/data/models/sca_wallet_model.dart';
|
||||
import 'package:sf_shared/src/domain/entities/payment_profile_entity.dart';
|
||||
import 'package:sf_shared/src/domain/entities/sca_wallet_entity.dart';
|
||||
import 'package:sf_shared/src/domain/repositories/treezor_repository.dart';
|
||||
|
||||
@@ -55,4 +57,12 @@ class TreezorRepositoryImpl implements TreezorRepository {
|
||||
Future<bool> sendJWSSesion({required String jws}) {
|
||||
return _remote.sendJWSSesion(jws: jws);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<PaymentProfileEntity> getPaymentProfile({
|
||||
required String userId,
|
||||
}) async {
|
||||
final model = await _remote.getPaymentProfile(userId: userId);
|
||||
return model.toEntity();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
import 'package:sf_shared/src/data/models/child_profile_response_model.dart';
|
||||
import 'package:sf_shared/src/data/models/user_response_model.dart';
|
||||
import 'package:sf_shared/src/domain/entities/child_profile_entity.dart';
|
||||
import 'package:sf_shared/src/domain/entities/user_entity.dart';
|
||||
import 'package:sf_shared/src/domain/repositories/user_repository.dart';
|
||||
|
||||
import '../datasource/user_remote_datasource.dart';
|
||||
|
||||
class UserRepositoryImpl implements UserRepository {
|
||||
UserRepositoryImpl(this._remote);
|
||||
|
||||
final UserRemoteDatasource _remote;
|
||||
|
||||
@override
|
||||
Future<UserEntity> getUserInfo() async {
|
||||
final model = await _remote.getUserInfo();
|
||||
return model.toEntity();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<List<ChildProfileEntity>> getChildProfiles() async {
|
||||
final model = await _remote.getChildProfiles();
|
||||
return model.items.map((item) => item.toEntity()).toList();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
part 'child_profile_entity.freezed.dart';
|
||||
|
||||
@freezed
|
||||
abstract class ChildProfileEntity with _$ChildProfileEntity {
|
||||
const factory ChildProfileEntity({
|
||||
required String id,
|
||||
required String deviceIdentificator,
|
||||
required String parentId,
|
||||
required String firstName,
|
||||
required String lastName,
|
||||
required int bornAt,
|
||||
required String walletId,
|
||||
required String treezorUserId,
|
||||
required String address,
|
||||
required int createdAt,
|
||||
}) = _ChildProfileEntity;
|
||||
}
|
||||
@@ -0,0 +1,298 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
// coverage:ignore-file
|
||||
// ignore_for_file: type=lint
|
||||
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark
|
||||
|
||||
part of 'child_profile_entity.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// FreezedGenerator
|
||||
// **************************************************************************
|
||||
|
||||
// dart format off
|
||||
T _$identity<T>(T value) => value;
|
||||
/// @nodoc
|
||||
mixin _$ChildProfileEntity {
|
||||
|
||||
String get id; String get deviceIdentificator; String get parentId; String get firstName; String get lastName; int get bornAt; String get walletId; String get treezorUserId; String get address; int get createdAt;
|
||||
/// Create a copy of ChildProfileEntity
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
$ChildProfileEntityCopyWith<ChildProfileEntity> get copyWith => _$ChildProfileEntityCopyWithImpl<ChildProfileEntity>(this as ChildProfileEntity, _$identity);
|
||||
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is ChildProfileEntity&&(identical(other.id, id) || other.id == id)&&(identical(other.deviceIdentificator, deviceIdentificator) || other.deviceIdentificator == deviceIdentificator)&&(identical(other.parentId, parentId) || other.parentId == parentId)&&(identical(other.firstName, firstName) || other.firstName == firstName)&&(identical(other.lastName, lastName) || other.lastName == lastName)&&(identical(other.bornAt, bornAt) || other.bornAt == bornAt)&&(identical(other.walletId, walletId) || other.walletId == walletId)&&(identical(other.treezorUserId, treezorUserId) || other.treezorUserId == treezorUserId)&&(identical(other.address, address) || other.address == address)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt));
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,id,deviceIdentificator,parentId,firstName,lastName,bornAt,walletId,treezorUserId,address,createdAt);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'ChildProfileEntity(id: $id, deviceIdentificator: $deviceIdentificator, parentId: $parentId, firstName: $firstName, lastName: $lastName, bornAt: $bornAt, walletId: $walletId, treezorUserId: $treezorUserId, address: $address, createdAt: $createdAt)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class $ChildProfileEntityCopyWith<$Res> {
|
||||
factory $ChildProfileEntityCopyWith(ChildProfileEntity value, $Res Function(ChildProfileEntity) _then) = _$ChildProfileEntityCopyWithImpl;
|
||||
@useResult
|
||||
$Res call({
|
||||
String id, String deviceIdentificator, String parentId, String firstName, String lastName, int bornAt, String walletId, String treezorUserId, String address, int createdAt
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class _$ChildProfileEntityCopyWithImpl<$Res>
|
||||
implements $ChildProfileEntityCopyWith<$Res> {
|
||||
_$ChildProfileEntityCopyWithImpl(this._self, this._then);
|
||||
|
||||
final ChildProfileEntity _self;
|
||||
final $Res Function(ChildProfileEntity) _then;
|
||||
|
||||
/// Create a copy of ChildProfileEntity
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? deviceIdentificator = null,Object? parentId = null,Object? firstName = null,Object? lastName = null,Object? bornAt = null,Object? walletId = null,Object? treezorUserId = null,Object? address = null,Object? createdAt = null,}) {
|
||||
return _then(_self.copyWith(
|
||||
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
||||
as String,deviceIdentificator: null == deviceIdentificator ? _self.deviceIdentificator : deviceIdentificator // ignore: cast_nullable_to_non_nullable
|
||||
as String,parentId: null == parentId ? _self.parentId : parentId // ignore: cast_nullable_to_non_nullable
|
||||
as String,firstName: null == firstName ? _self.firstName : firstName // ignore: cast_nullable_to_non_nullable
|
||||
as String,lastName: null == lastName ? _self.lastName : lastName // ignore: cast_nullable_to_non_nullable
|
||||
as String,bornAt: null == bornAt ? _self.bornAt : bornAt // ignore: cast_nullable_to_non_nullable
|
||||
as int,walletId: null == walletId ? _self.walletId : walletId // ignore: cast_nullable_to_non_nullable
|
||||
as String,treezorUserId: null == treezorUserId ? _self.treezorUserId : treezorUserId // ignore: cast_nullable_to_non_nullable
|
||||
as String,address: null == address ? _self.address : address // ignore: cast_nullable_to_non_nullable
|
||||
as String,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
|
||||
as int,
|
||||
));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// Adds pattern-matching-related methods to [ChildProfileEntity].
|
||||
extension ChildProfileEntityPatterns on ChildProfileEntity {
|
||||
/// A variant of `map` that fallback to returning `orElse`.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return orElse();
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _ChildProfileEntity value)? $default,{required TResult orElse(),}){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _ChildProfileEntity() when $default != null:
|
||||
return $default(_that);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
}
|
||||
/// A `switch`-like method, using callbacks.
|
||||
///
|
||||
/// Callbacks receives the raw object, upcasted.
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case final Subclass2 value:
|
||||
/// return ...;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _ChildProfileEntity value) $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _ChildProfileEntity():
|
||||
return $default(_that);case _:
|
||||
throw StateError('Unexpected subclass');
|
||||
|
||||
}
|
||||
}
|
||||
/// A variant of `map` that fallback to returning `null`.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return null;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _ChildProfileEntity value)? $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _ChildProfileEntity() when $default != null:
|
||||
return $default(_that);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
/// A variant of `when` that fallback to an `orElse` callback.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return orElse();
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String id, String deviceIdentificator, String parentId, String firstName, String lastName, int bornAt, String walletId, String treezorUserId, String address, int createdAt)? $default,{required TResult orElse(),}) {final _that = this;
|
||||
switch (_that) {
|
||||
case _ChildProfileEntity() when $default != null:
|
||||
return $default(_that.id,_that.deviceIdentificator,_that.parentId,_that.firstName,_that.lastName,_that.bornAt,_that.walletId,_that.treezorUserId,_that.address,_that.createdAt);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
}
|
||||
/// A `switch`-like method, using callbacks.
|
||||
///
|
||||
/// As opposed to `map`, this offers destructuring.
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case Subclass2(:final field2):
|
||||
/// return ...;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String id, String deviceIdentificator, String parentId, String firstName, String lastName, int bornAt, String walletId, String treezorUserId, String address, int createdAt) $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _ChildProfileEntity():
|
||||
return $default(_that.id,_that.deviceIdentificator,_that.parentId,_that.firstName,_that.lastName,_that.bornAt,_that.walletId,_that.treezorUserId,_that.address,_that.createdAt);case _:
|
||||
throw StateError('Unexpected subclass');
|
||||
|
||||
}
|
||||
}
|
||||
/// A variant of `when` that fallback to returning `null`
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return null;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String id, String deviceIdentificator, String parentId, String firstName, String lastName, int bornAt, String walletId, String treezorUserId, String address, int createdAt)? $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _ChildProfileEntity() when $default != null:
|
||||
return $default(_that.id,_that.deviceIdentificator,_that.parentId,_that.firstName,_that.lastName,_that.bornAt,_that.walletId,_that.treezorUserId,_that.address,_that.createdAt);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
|
||||
|
||||
class _ChildProfileEntity implements ChildProfileEntity {
|
||||
const _ChildProfileEntity({required this.id, required this.deviceIdentificator, required this.parentId, required this.firstName, required this.lastName, required this.bornAt, required this.walletId, required this.treezorUserId, required this.address, required this.createdAt});
|
||||
|
||||
|
||||
@override final String id;
|
||||
@override final String deviceIdentificator;
|
||||
@override final String parentId;
|
||||
@override final String firstName;
|
||||
@override final String lastName;
|
||||
@override final int bornAt;
|
||||
@override final String walletId;
|
||||
@override final String treezorUserId;
|
||||
@override final String address;
|
||||
@override final int createdAt;
|
||||
|
||||
/// Create a copy of ChildProfileEntity
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
_$ChildProfileEntityCopyWith<_ChildProfileEntity> get copyWith => __$ChildProfileEntityCopyWithImpl<_ChildProfileEntity>(this, _$identity);
|
||||
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _ChildProfileEntity&&(identical(other.id, id) || other.id == id)&&(identical(other.deviceIdentificator, deviceIdentificator) || other.deviceIdentificator == deviceIdentificator)&&(identical(other.parentId, parentId) || other.parentId == parentId)&&(identical(other.firstName, firstName) || other.firstName == firstName)&&(identical(other.lastName, lastName) || other.lastName == lastName)&&(identical(other.bornAt, bornAt) || other.bornAt == bornAt)&&(identical(other.walletId, walletId) || other.walletId == walletId)&&(identical(other.treezorUserId, treezorUserId) || other.treezorUserId == treezorUserId)&&(identical(other.address, address) || other.address == address)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt));
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,id,deviceIdentificator,parentId,firstName,lastName,bornAt,walletId,treezorUserId,address,createdAt);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'ChildProfileEntity(id: $id, deviceIdentificator: $deviceIdentificator, parentId: $parentId, firstName: $firstName, lastName: $lastName, bornAt: $bornAt, walletId: $walletId, treezorUserId: $treezorUserId, address: $address, createdAt: $createdAt)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class _$ChildProfileEntityCopyWith<$Res> implements $ChildProfileEntityCopyWith<$Res> {
|
||||
factory _$ChildProfileEntityCopyWith(_ChildProfileEntity value, $Res Function(_ChildProfileEntity) _then) = __$ChildProfileEntityCopyWithImpl;
|
||||
@override @useResult
|
||||
$Res call({
|
||||
String id, String deviceIdentificator, String parentId, String firstName, String lastName, int bornAt, String walletId, String treezorUserId, String address, int createdAt
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class __$ChildProfileEntityCopyWithImpl<$Res>
|
||||
implements _$ChildProfileEntityCopyWith<$Res> {
|
||||
__$ChildProfileEntityCopyWithImpl(this._self, this._then);
|
||||
|
||||
final _ChildProfileEntity _self;
|
||||
final $Res Function(_ChildProfileEntity) _then;
|
||||
|
||||
/// Create a copy of ChildProfileEntity
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? deviceIdentificator = null,Object? parentId = null,Object? firstName = null,Object? lastName = null,Object? bornAt = null,Object? walletId = null,Object? treezorUserId = null,Object? address = null,Object? createdAt = null,}) {
|
||||
return _then(_ChildProfileEntity(
|
||||
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
||||
as String,deviceIdentificator: null == deviceIdentificator ? _self.deviceIdentificator : deviceIdentificator // ignore: cast_nullable_to_non_nullable
|
||||
as String,parentId: null == parentId ? _self.parentId : parentId // ignore: cast_nullable_to_non_nullable
|
||||
as String,firstName: null == firstName ? _self.firstName : firstName // ignore: cast_nullable_to_non_nullable
|
||||
as String,lastName: null == lastName ? _self.lastName : lastName // ignore: cast_nullable_to_non_nullable
|
||||
as String,bornAt: null == bornAt ? _self.bornAt : bornAt // ignore: cast_nullable_to_non_nullable
|
||||
as int,walletId: null == walletId ? _self.walletId : walletId // ignore: cast_nullable_to_non_nullable
|
||||
as String,treezorUserId: null == treezorUserId ? _self.treezorUserId : treezorUserId // ignore: cast_nullable_to_non_nullable
|
||||
as String,address: null == address ? _self.address : address // ignore: cast_nullable_to_non_nullable
|
||||
as String,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
|
||||
as int,
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// dart format on
|
||||
@@ -1,3 +1,4 @@
|
||||
import '../entities/payment_profile_entity.dart';
|
||||
import '../entities/sca_wallet_entity.dart';
|
||||
|
||||
abstract class TreezorRepository {
|
||||
@@ -6,4 +7,6 @@ abstract class TreezorRepository {
|
||||
Future<void> resetScaWallets();
|
||||
|
||||
Future<bool> sendJWSSesion({required String jws});
|
||||
|
||||
Future<PaymentProfileEntity> getPaymentProfile({required String userId});
|
||||
}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
import '../entities/child_profile_entity.dart';
|
||||
import '../entities/user_entity.dart';
|
||||
|
||||
abstract class UserRepository {
|
||||
Future<UserEntity> getUserInfo();
|
||||
Future<List<ChildProfileEntity>> getChildProfiles();
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
import '../entities/payment_profile_entity.dart';
|
||||
|
||||
abstract class GetPaymentProfileUseCase {
|
||||
Future<PaymentProfileEntity> getPaymentProfile({required String userId});
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
import '../entities/payment_profile_entity.dart';
|
||||
import '../repositories/treezor_repository.dart';
|
||||
import 'get_payment_profile_use_case.dart';
|
||||
|
||||
class GetPaymentProfileUseCaseImpl implements GetPaymentProfileUseCase {
|
||||
const GetPaymentProfileUseCaseImpl(this._repository);
|
||||
|
||||
final TreezorRepository _repository;
|
||||
|
||||
@override
|
||||
Future<PaymentProfileEntity> getPaymentProfile({
|
||||
required String userId,
|
||||
}) {
|
||||
return _repository.getPaymentProfile(userId: userId);
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
import 'package:auth/src/features/login/domain/entities/user_entity.dart';
|
||||
import '../entities/user_entity.dart';
|
||||
|
||||
abstract class GetUserInfoUseCase {
|
||||
Future<UserEntity> getUserInfo();
|
||||
@@ -0,0 +1,14 @@
|
||||
import '../entities/user_entity.dart';
|
||||
import '../repositories/user_repository.dart';
|
||||
import 'get_user_info_use_case.dart';
|
||||
|
||||
class GetUserInfoUseCaseImpl implements GetUserInfoUseCase {
|
||||
const GetUserInfoUseCaseImpl(this._repository);
|
||||
|
||||
final UserRepository _repository;
|
||||
|
||||
@override
|
||||
Future<UserEntity> getUserInfo() {
|
||||
return _repository.getUserInfo();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
|
||||
import 'package:sf_shared/src/domain/use_cases/get_payment_profile_use_case.dart';
|
||||
import 'package:sf_shared/src/domain/use_cases/get_payment_profile_use_case_impl.dart';
|
||||
import 'package:sf_shared/src/providers/treezor_repository_provider.dart';
|
||||
|
||||
final getPaymentProfileUseCaseProvider =
|
||||
Provider<GetPaymentProfileUseCase>((ref) {
|
||||
final repository = ref.watch(treezorRepositoryProvider);
|
||||
return GetPaymentProfileUseCaseImpl(repository);
|
||||
});
|
||||
@@ -0,0 +1,11 @@
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
|
||||
import 'package:sf_shared/src/domain/use_cases/get_user_info_use_case.dart';
|
||||
import 'package:sf_shared/src/domain/use_cases/get_user_info_use_case_impl.dart';
|
||||
import 'package:sf_shared/src/providers/user_repository_provider.dart';
|
||||
|
||||
final getUserInfoUseCaseProvider =
|
||||
Provider<GetUserInfoUseCase>((ref) {
|
||||
final repository = ref.watch(userRepositoryProvider);
|
||||
return GetUserInfoUseCaseImpl(repository);
|
||||
});
|
||||
@@ -0,0 +1,8 @@
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:sf_shared/sf_shared.dart';
|
||||
|
||||
final userInfoProvider =
|
||||
FutureProvider.autoDispose<UserEntity>((ref) async {
|
||||
final getUserInfoUseCase = ref.read(getUserInfoUseCaseProvider);
|
||||
return getUserInfoUseCase.getUserInfo();
|
||||
});
|
||||
@@ -0,0 +1,12 @@
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:get_it/get_it.dart';
|
||||
import 'package:sf_infrastructure/sf_infrastructure.dart';
|
||||
import 'package:sf_shared/src/data/datasource/user_remote_datasource_impl.dart';
|
||||
import 'package:sf_shared/src/data/repositories/user_repository_impl.dart';
|
||||
import 'package:sf_shared/src/domain/repositories/user_repository.dart';
|
||||
|
||||
final userRepositoryProvider = Provider<UserRepository>((ref) {
|
||||
final questiaRepository = GetIt.I<QuestiaRepository>();
|
||||
final remote = UserRemoteDatasourceImpl(questiaRepository);
|
||||
return UserRepositoryImpl(remote);
|
||||
});
|
||||
@@ -86,7 +86,7 @@ class LineGraphState extends ConsumerState<LineGraph> {
|
||||
return SideTitleWidget(
|
||||
space: 4,
|
||||
meta: meta,
|
||||
child: Expanded(child: Center(child: Text(text, style: TextStyle(fontSize: 12)))),
|
||||
child: Center(child: Text(text, style: TextStyle(fontSize: 12))),
|
||||
);
|
||||
},
|
||||
),
|
||||
|
||||
Reference in New Issue
Block a user