added app_users screen and states
This commit is contained in:
@@ -58,6 +58,11 @@ void configureAppRouter() {
|
|||||||
name: 'linked_devices',
|
name: 'linked_devices',
|
||||||
pageBuilder: LinkedDevicesBuilder().buildPage,
|
pageBuilder: LinkedDevicesBuilder().buildPage,
|
||||||
),
|
),
|
||||||
|
GoRoute(
|
||||||
|
path: AppRoutes.appUsers,
|
||||||
|
name: 'app_users',
|
||||||
|
pageBuilder: AppUsersBuilder().buildPage,
|
||||||
|
),
|
||||||
|
|
||||||
GoRoute(
|
GoRoute(
|
||||||
path: AppRoutes.login,
|
path: AppRoutes.login,
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import 'package:account/src/features/linked_devices/domain/entities/device_entity.dart';
|
import 'package:account/src/features/linked_devices/domain/entities/device_entity.dart';
|
||||||
import 'package:account/src/features/personal_data/domain/entities/update_user_request_entity.dart';
|
import 'package:account/src/features/personal_data/domain/entities/update_user_request_entity.dart';
|
||||||
import 'package:account/src/features/personal_data/domain/entities/user_entity.dart';
|
import 'package:account/src/core/data/models/entities/user_entity.dart';
|
||||||
|
|
||||||
abstract class AccountRemoteDatasource {
|
abstract class AccountRemoteDatasource {
|
||||||
Future<List<DeviceEntity>> getLinkedDevices({required String userId});
|
Future<List<DeviceEntity>> getLinkedDevices({required String userId});
|
||||||
@@ -8,4 +8,6 @@ abstract class AccountRemoteDatasource {
|
|||||||
Future<UserEntity> getLoggedUser({required String token});
|
Future<UserEntity> getLoggedUser({required String token});
|
||||||
|
|
||||||
Future<void> updateUser({required String userId, required UpdateUserRequestEntity request});
|
Future<void> updateUser({required String userId, required UpdateUserRequestEntity request});
|
||||||
|
|
||||||
|
Future<List<UserEntity>> getAppUsers({required String userId});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import 'package:account/src/core/data/models/get_logged_user_response_model.dart
|
|||||||
import 'package:account/src/core/data/models/update_user_request_model.dart';
|
import 'package:account/src/core/data/models/update_user_request_model.dart';
|
||||||
import 'package:account/src/features/linked_devices/domain/entities/device_entity.dart';
|
import 'package:account/src/features/linked_devices/domain/entities/device_entity.dart';
|
||||||
import 'package:account/src/features/personal_data/domain/entities/update_user_request_entity.dart';
|
import 'package:account/src/features/personal_data/domain/entities/update_user_request_entity.dart';
|
||||||
import 'package:account/src/features/personal_data/domain/entities/user_entity.dart';
|
import 'package:account/src/core/data/models/entities/user_entity.dart';
|
||||||
import 'package:dio/dio.dart';
|
import 'package:dio/dio.dart';
|
||||||
// import 'package:flutter/material.dart';
|
// import 'package:flutter/material.dart';
|
||||||
import 'package:sf_infrastructure/sf_infrastructure.dart';
|
import 'package:sf_infrastructure/sf_infrastructure.dart';
|
||||||
@@ -87,6 +87,55 @@ class AccountRemoteDatasourceImpl implements AccountRemoteDatasource {
|
|||||||
throw _mapDioError(error, defaultMessage: 'Error in verification code');
|
throw _mapDioError(error, defaultMessage: 'Error in verification code');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<List<UserEntity>> getAppUsers({required String userId}) async {
|
||||||
|
//try {
|
||||||
|
/*final response = await _repository.get<Map<String, dynamic>>(
|
||||||
|
'/$userId/devices',
|
||||||
|
);
|
||||||
|
final data = response.data!['items'];
|
||||||
|
if (data == null || data.isEmpty) {
|
||||||
|
throw Exception('Empty response from /:userId/devices');
|
||||||
|
}
|
||||||
|
|
||||||
|
final model = GetLinkedDevicesResponseModel.fromJson(data);*/
|
||||||
|
/*final model = GetLinkedDevicesResponseModel(items: [
|
||||||
|
GetLinkedDevicesItemResponseModel(
|
||||||
|
identificator: '1111',
|
||||||
|
name: 'Carlos',
|
||||||
|
number: '111111111'),
|
||||||
|
GetLinkedDevicesItemResponseModel(
|
||||||
|
identificator: '1112',
|
||||||
|
name: 'Ana',
|
||||||
|
number: '222222222'),
|
||||||
|
]);
|
||||||
|
return model.toEntity();
|
||||||
|
} on DioException catch (error) {
|
||||||
|
throw _mapDioError(
|
||||||
|
error,
|
||||||
|
defaultMessage: error.message ?? 'Error getting devices',
|
||||||
|
);
|
||||||
|
}*/
|
||||||
|
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',
|
||||||
|
)
|
||||||
|
];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Exception _mapDioError(DioException error, {required String defaultMessage}) {
|
Exception _mapDioError(DioException error, {required String defaultMessage}) {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import 'package:account/src/features/personal_data/domain/entities/user_entity.dart';
|
import 'package:account/src/core/data/models/entities/user_entity.dart';
|
||||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||||
|
|
||||||
part 'get_logged_user_response_model.freezed.dart';
|
part 'get_logged_user_response_model.freezed.dart';
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import 'package:account/src/core/data/datasource/account_remote_datasource.dart'
|
|||||||
import 'package:account/src/core/domain/repositories/account_repository.dart';
|
import 'package:account/src/core/domain/repositories/account_repository.dart';
|
||||||
import 'package:account/src/features/linked_devices/domain/entities/device_entity.dart';
|
import 'package:account/src/features/linked_devices/domain/entities/device_entity.dart';
|
||||||
import 'package:account/src/features/personal_data/domain/entities/update_user_request_entity.dart';
|
import 'package:account/src/features/personal_data/domain/entities/update_user_request_entity.dart';
|
||||||
import 'package:account/src/features/personal_data/domain/entities/user_entity.dart';
|
import 'package:account/src/core/data/models/entities/user_entity.dart';
|
||||||
|
|
||||||
class AccountRepositoryImpl implements AccountRepository {
|
class AccountRepositoryImpl implements AccountRepository {
|
||||||
const AccountRepositoryImpl(this._remote);
|
const AccountRepositoryImpl(this._remote);
|
||||||
@@ -23,4 +23,9 @@ class AccountRepositoryImpl implements AccountRepository {
|
|||||||
Future<void> updateUser({required String userId, required UpdateUserRequestEntity request}) {
|
Future<void> updateUser({required String userId, required UpdateUserRequestEntity request}) {
|
||||||
return _remote.updateUser(userId: userId, request: request);
|
return _remote.updateUser(userId: userId, request: request);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<List<UserEntity>> getAppUsers({required String userId}) {
|
||||||
|
return _remote.getAppUsers(userId: userId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import 'package:account/src/features/linked_devices/domain/entities/device_entity.dart';
|
import 'package:account/src/features/linked_devices/domain/entities/device_entity.dart';
|
||||||
import 'package:account/src/features/personal_data/domain/entities/update_user_request_entity.dart';
|
import 'package:account/src/features/personal_data/domain/entities/update_user_request_entity.dart';
|
||||||
import 'package:account/src/features/personal_data/domain/entities/user_entity.dart';
|
import 'package:account/src/core/data/models/entities/user_entity.dart';
|
||||||
|
|
||||||
abstract class AccountRepository {
|
abstract class AccountRepository {
|
||||||
Future<List<DeviceEntity>> getLinkedDevices({required String userId});
|
Future<List<DeviceEntity>> getLinkedDevices({required String userId});
|
||||||
@@ -8,4 +8,6 @@ abstract class AccountRepository {
|
|||||||
Future<void> updateUser({required String userId, required UpdateUserRequestEntity request});
|
Future<void> updateUser({required String userId, required UpdateUserRequestEntity request});
|
||||||
|
|
||||||
Future<UserEntity> getLoggedUser({required String token});
|
Future<UserEntity> getLoggedUser({required String token});
|
||||||
|
|
||||||
|
Future<List<UserEntity>> getAppUsers({required String userId});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// import 'package:account/src/features/linked_devices/presentation/linked_devices_screen.dart';
|
// import 'package:account/src/features/linked_devices/presentation/app_users_screen.dart';
|
||||||
import 'package:design_system/design_system.dart';
|
import 'package:design_system/design_system.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
@@ -66,7 +66,7 @@ class AccountSettingsScreen extends ConsumerWidget {
|
|||||||
),
|
),
|
||||||
SizedBox(height: SizeUtils.getByScreen(small: 16, big: 15)),
|
SizedBox(height: SizeUtils.getByScreen(small: 16, big: 15)),
|
||||||
AppSectionButton(
|
AppSectionButton(
|
||||||
onPressed: (){},
|
onPressed: (){navigationContract.pushTo(AppRoutes.appUsers);},
|
||||||
icon: Icons.groups_outlined,
|
icon: Icons.groups_outlined,
|
||||||
text: 'App Users'
|
text: 'App Users'
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
import 'package:account/src/features/app_users/presentation/app_users_screen.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:go_router/go_router.dart';
|
||||||
|
import 'package:get_it/get_it.dart';
|
||||||
|
import 'package:navigation/navigation.dart';
|
||||||
|
|
||||||
|
class AppUsersBuilder {
|
||||||
|
const AppUsersBuilder();
|
||||||
|
|
||||||
|
Page<void> buildPage(BuildContext context, GoRouterState state) {
|
||||||
|
final NavigationContract navigationContract = GetIt.I<NavigationContract>();
|
||||||
|
|
||||||
|
return MaterialPage<void>(
|
||||||
|
key: state.pageKey,
|
||||||
|
child: AppUsersScreen(navigationContract: navigationContract),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
import 'package:account/src/core/data/models/entities/user_entity.dart';
|
||||||
|
|
||||||
|
abstract class GetAppUsersUseCase {
|
||||||
|
Future<List<UserEntity>> getAppUsers({required String userId});
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
import 'package:account/src/core/data/models/entities/user_entity.dart';
|
||||||
|
import 'package:account/src/core/domain/repositories/account_repository.dart';
|
||||||
|
import 'package:account/src/features/app_users/domain/get_app_users_use_case.dart';
|
||||||
|
|
||||||
|
class GetAppUsersUseCaseImpl implements GetAppUsersUseCase {
|
||||||
|
GetAppUsersUseCaseImpl(this._repository);
|
||||||
|
|
||||||
|
final AccountRepository _repository;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<List<UserEntity>> getAppUsers({required String userId}) {
|
||||||
|
return _repository.getAppUsers(userId: userId);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,223 @@
|
|||||||
|
import 'package:account/src/core/data/models/entities/user_entity.dart';
|
||||||
|
import 'package:account/src/features/app_users/presentation/state/app_users_view_model.dart';
|
||||||
|
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:sf_localizations/sf_localizations.dart';
|
||||||
|
import 'package:utils/utils.dart';
|
||||||
|
|
||||||
|
class AppUsersScreen extends ConsumerWidget {
|
||||||
|
final NavigationContract navigationContract;
|
||||||
|
|
||||||
|
const AppUsersScreen({super.key, required this.navigationContract});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
|
final vm = ref.read(appUsersViewModelProvider.notifier);
|
||||||
|
final state = ref.watch(appUsersViewModelProvider);
|
||||||
|
|
||||||
|
final theme = ref.watch(themePortProvider);
|
||||||
|
|
||||||
|
return Scaffold(
|
||||||
|
backgroundColor: theme.getColorFor(ThemeCode.backgroundPrimary),
|
||||||
|
body: SafeArea(
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
padding: SizeUtils.getByScreen(
|
||||||
|
small: EdgeInsets.symmetric(horizontal: 22, vertical: 10),
|
||||||
|
big: EdgeInsets.symmetric(horizontal: 21, vertical: 8)
|
||||||
|
),
|
||||||
|
child: Stack(
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
IconButton(onPressed: () {Navigator.pop(context);},
|
||||||
|
icon: Icon(Icons.arrow_back)),
|
||||||
|
if (!state.isEditing) ...[
|
||||||
|
DecoratedBox(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Color(0xFF588EA5),
|
||||||
|
shape: BoxShape.circle
|
||||||
|
),
|
||||||
|
child: IconButton(onPressed: vm.toggleIsEditing,
|
||||||
|
icon: Icon(Icons.edit_outlined,
|
||||||
|
color: Colors.white,
|
||||||
|
size: SizeUtils.getByScreen(small: 30, big: 28),
|
||||||
|
)
|
||||||
|
),
|
||||||
|
)
|
||||||
|
]
|
||||||
|
],
|
||||||
|
),
|
||||||
|
Center(
|
||||||
|
child: Text(context.translate('App users'),
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: SizeUtils.getByScreen(small: 28, big: 27)
|
||||||
|
),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(height: SizeUtils.getByScreen(small: 20, big: 18)),
|
||||||
|
Expanded( child: Container(
|
||||||
|
padding: SizeUtils.getByScreen(
|
||||||
|
small: EdgeInsets.symmetric(horizontal: 22, vertical: 10),
|
||||||
|
big: EdgeInsets.symmetric(horizontal: 21, vertical: 8)
|
||||||
|
),
|
||||||
|
child: ListView.separated(
|
||||||
|
itemBuilder: (BuildContext context, int index)=>AppUserCard(
|
||||||
|
user: state.appUsers[index],
|
||||||
|
isEditing: state.isEditing,
|
||||||
|
),
|
||||||
|
separatorBuilder: (BuildContext context, int index)=>SizedBox(
|
||||||
|
height: SizeUtils.getByScreen(small: 18, big: 17)
|
||||||
|
),
|
||||||
|
itemCount: state.appUsers.length
|
||||||
|
),
|
||||||
|
)),
|
||||||
|
if (state.isEditing) ...[
|
||||||
|
Container(
|
||||||
|
padding: SizeUtils.getByScreen(
|
||||||
|
small: EdgeInsets.symmetric(horizontal: 26, vertical: 14),
|
||||||
|
big: EdgeInsets.symmetric(horizontal: 24, vertical: 12)
|
||||||
|
),
|
||||||
|
child: PrimaryButton(
|
||||||
|
onPressed: vm.toggleIsEditing,
|
||||||
|
text: 'Save',
|
||||||
|
color: Color(0xFF588EA5),
|
||||||
|
height: SizeUtils.getByScreen(small: 44, big: 42),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
]
|
||||||
|
],
|
||||||
|
)
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class AppUserCard extends ConsumerWidget {
|
||||||
|
|
||||||
|
final UserEntity user;
|
||||||
|
final bool isEditing;
|
||||||
|
|
||||||
|
const AppUserCard({
|
||||||
|
required this.user,
|
||||||
|
required this.isEditing,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
|
final theme = ref.read(themePortProvider);
|
||||||
|
|
||||||
|
return Container(
|
||||||
|
padding: SizeUtils.getByScreen(
|
||||||
|
small: EdgeInsets.symmetric(horizontal: 22, vertical: 10),
|
||||||
|
big: EdgeInsets.symmetric(horizontal: 21, vertical: 8)
|
||||||
|
),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: BorderRadius.all(Radius.circular(SizeUtils.getByScreen(small: 12, big: 18))),
|
||||||
|
color: theme.getColorFor(ThemeCode.backgroundSecondary),
|
||||||
|
),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
shape: BoxShape.circle,
|
||||||
|
color: theme.getColorFor(ThemeCode.backgroundPrimary),
|
||||||
|
),
|
||||||
|
padding: EdgeInsets.all(SizeUtils.getByScreen(small: 4, big: 12)),
|
||||||
|
child: Icon(SFIcons.account,
|
||||||
|
size: SizeUtils.getByScreen(small: 40, big: 44),
|
||||||
|
color: Color(0xFF588EA5),
|
||||||
|
weight: 30,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(width: SizeUtils.getByScreen(small: 16, big: 15)),
|
||||||
|
Expanded(
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text(user.firstName,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: SizeUtils.getByScreen(small: 18, big: 19),
|
||||||
|
fontWeight: FontWeight.w500
|
||||||
|
)
|
||||||
|
),
|
||||||
|
Text('Account: ${user.email}',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: SizeUtils.getByScreen(small: 14, big: 13),
|
||||||
|
)
|
||||||
|
),
|
||||||
|
Text('Role: ${user.role}',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: SizeUtils.getByScreen(small: 14, big: 13),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
],
|
||||||
|
)
|
||||||
|
),
|
||||||
|
if (isEditing) ...[
|
||||||
|
DecoratedBox(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Color(0xFFFF5D52),
|
||||||
|
borderRadius: BorderRadius.all(Radius.circular(12)),
|
||||||
|
),
|
||||||
|
child: IconButton(
|
||||||
|
onPressed: (){showDialog(context: context, builder: (context)=>Dialog(
|
||||||
|
child: Container(
|
||||||
|
padding: SizeUtils.getByScreen(
|
||||||
|
small: EdgeInsets.symmetric(horizontal: 32, vertical: 30),
|
||||||
|
big: EdgeInsets.symmetric(horizontal: 30, vertical: 28)
|
||||||
|
),
|
||||||
|
width: SizeUtils.getByScreen(small: 360, big: 350),
|
||||||
|
height: SizeUtils.getByScreen(small: 195, big: 185),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Text('Are you sure you want to delete this user from the list?',
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
style: TextStyle(fontSize: SizeUtils.getByScreen(small: 19, big: 18)),
|
||||||
|
),
|
||||||
|
SizedBox(height: SizeUtils.getByScreen(small: 28, big: 27)),
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
Expanded(child: PrimaryButton(
|
||||||
|
onPressed: (){Navigator.pop(context);},
|
||||||
|
text: 'Cancel',
|
||||||
|
color: Color(0xFF588EA5),
|
||||||
|
height: SizeUtils.getByScreen(small: 38, big: 36),
|
||||||
|
radius: SizeUtils.getByScreen(small: 32, big: 34),
|
||||||
|
)),
|
||||||
|
SizedBox(width: SizeUtils.getByScreen(small: 4, big: 16)),
|
||||||
|
Expanded(child: PrimaryButton(
|
||||||
|
onPressed: (){
|
||||||
|
Navigator.pop(context);
|
||||||
|
},
|
||||||
|
text: 'Delete',
|
||||||
|
color: Color(0xFF588EA5),
|
||||||
|
height: SizeUtils.getByScreen(small: 38, big: 36),
|
||||||
|
radius: SizeUtils.getByScreen(small: 32, big: 34),
|
||||||
|
))
|
||||||
|
],
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
));},
|
||||||
|
icon: Icon(
|
||||||
|
Icons.close,
|
||||||
|
color: Colors.white,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
]
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
import 'package:account/src/core/providers/account_repository_provider.dart';
|
||||||
|
import 'package:account/src/features/app_users/domain/get_app_users_use_case.dart';
|
||||||
|
import 'package:account/src/features/app_users/domain/get_app_users_use_case_impl.dart';
|
||||||
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
|
|
||||||
|
final getAppUsersUseCaseProvider = Provider.autoDispose<GetAppUsersUseCase>((ref) {
|
||||||
|
final authRepository = ref.read(accountRepositoryProvider);
|
||||||
|
return GetAppUsersUseCaseImpl(authRepository);
|
||||||
|
});
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
import 'package:account/src/core/data/models/entities/user_entity.dart';
|
||||||
|
import 'package:account/src/features/app_users/domain/get_app_users_use_case.dart';
|
||||||
|
import 'package:account/src/features/app_users/presentation/providers/get_app_users_use_case_provider.dart';
|
||||||
|
import 'package:account/src/features/app_users/presentation/state/app_users_view_state.dart';
|
||||||
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
|
// import 'package:sf_localizations/sf_localizations.dart';
|
||||||
|
|
||||||
|
final appUsersViewModelProvider =
|
||||||
|
NotifierProvider.autoDispose<AppUsersViewModel, AppUsersViewState>(
|
||||||
|
AppUsersViewModel.new,
|
||||||
|
);
|
||||||
|
|
||||||
|
class AppUsersViewModel extends Notifier<AppUsersViewState> {
|
||||||
|
late final GetAppUsersUseCase _getAppUsersUseCase;
|
||||||
|
|
||||||
|
@override
|
||||||
|
AppUsersViewState build() {
|
||||||
|
_getAppUsersUseCase = ref.read(getAppUsersUseCaseProvider);
|
||||||
|
|
||||||
|
_getAppUsersUseCase.getAppUsers(userId: 'test')
|
||||||
|
.then(setAppUsers);
|
||||||
|
|
||||||
|
return const AppUsersViewState();
|
||||||
|
}
|
||||||
|
|
||||||
|
void setAppUsers(List<UserEntity> appUsers) {
|
||||||
|
state = state.copyWith(appUsers: appUsers);
|
||||||
|
}
|
||||||
|
|
||||||
|
void toggleIsEditing() {
|
||||||
|
state = state.copyWith(isEditing: !state.isEditing);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
import 'package:account/src/core/data/models/entities/user_entity.dart';
|
||||||
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||||
|
|
||||||
|
part 'app_users_view_state.freezed.dart';
|
||||||
|
|
||||||
|
@freezed
|
||||||
|
abstract class AppUsersViewState with _$AppUsersViewState {
|
||||||
|
const factory AppUsersViewState({
|
||||||
|
@Default(false) bool isLoading,
|
||||||
|
@Default([]) List<UserEntity> appUsers,
|
||||||
|
@Default(false) bool isEditing,
|
||||||
|
@Default('') String errorMessage
|
||||||
|
}) = _AppUsersViewState;
|
||||||
|
}
|
||||||
@@ -0,0 +1,286 @@
|
|||||||
|
// 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 'app_users_view_state.dart';
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// FreezedGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
// dart format off
|
||||||
|
T _$identity<T>(T value) => value;
|
||||||
|
/// @nodoc
|
||||||
|
mixin _$AppUsersViewState {
|
||||||
|
|
||||||
|
bool get isLoading; List<UserEntity> get appUsers; bool get isEditing; String get errorMessage;
|
||||||
|
/// Create a copy of AppUsersViewState
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
$AppUsersViewStateCopyWith<AppUsersViewState> get copyWith => _$AppUsersViewStateCopyWithImpl<AppUsersViewState>(this as AppUsersViewState, _$identity);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is AppUsersViewState&&(identical(other.isLoading, isLoading) || other.isLoading == isLoading)&&const DeepCollectionEquality().equals(other.appUsers, appUsers)&&(identical(other.isEditing, isEditing) || other.isEditing == isEditing)&&(identical(other.errorMessage, errorMessage) || other.errorMessage == errorMessage));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode => Object.hash(runtimeType,isLoading,const DeepCollectionEquality().hash(appUsers),isEditing,errorMessage);
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'AppUsersViewState(isLoading: $isLoading, appUsers: $appUsers, isEditing: $isEditing, errorMessage: $errorMessage)';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract mixin class $AppUsersViewStateCopyWith<$Res> {
|
||||||
|
factory $AppUsersViewStateCopyWith(AppUsersViewState value, $Res Function(AppUsersViewState) _then) = _$AppUsersViewStateCopyWithImpl;
|
||||||
|
@useResult
|
||||||
|
$Res call({
|
||||||
|
bool isLoading, List<UserEntity> appUsers, bool isEditing, String errorMessage
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
/// @nodoc
|
||||||
|
class _$AppUsersViewStateCopyWithImpl<$Res>
|
||||||
|
implements $AppUsersViewStateCopyWith<$Res> {
|
||||||
|
_$AppUsersViewStateCopyWithImpl(this._self, this._then);
|
||||||
|
|
||||||
|
final AppUsersViewState _self;
|
||||||
|
final $Res Function(AppUsersViewState) _then;
|
||||||
|
|
||||||
|
/// Create a copy of AppUsersViewState
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@pragma('vm:prefer-inline') @override $Res call({Object? isLoading = null,Object? appUsers = null,Object? isEditing = null,Object? errorMessage = null,}) {
|
||||||
|
return _then(_self.copyWith(
|
||||||
|
isLoading: null == isLoading ? _self.isLoading : isLoading // ignore: cast_nullable_to_non_nullable
|
||||||
|
as bool,appUsers: null == appUsers ? _self.appUsers : appUsers // ignore: cast_nullable_to_non_nullable
|
||||||
|
as List<UserEntity>,isEditing: null == isEditing ? _self.isEditing : isEditing // ignore: cast_nullable_to_non_nullable
|
||||||
|
as bool,errorMessage: null == errorMessage ? _self.errorMessage : errorMessage // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// Adds pattern-matching-related methods to [AppUsersViewState].
|
||||||
|
extension AppUsersViewStatePatterns on AppUsersViewState {
|
||||||
|
/// 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( _AppUsersViewState value)? $default,{required TResult orElse(),}){
|
||||||
|
final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _AppUsersViewState() 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( _AppUsersViewState value) $default,){
|
||||||
|
final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _AppUsersViewState():
|
||||||
|
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( _AppUsersViewState value)? $default,){
|
||||||
|
final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _AppUsersViewState() 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( bool isLoading, List<UserEntity> appUsers, bool isEditing, String errorMessage)? $default,{required TResult orElse(),}) {final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _AppUsersViewState() when $default != null:
|
||||||
|
return $default(_that.isLoading,_that.appUsers,_that.isEditing,_that.errorMessage);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( bool isLoading, List<UserEntity> appUsers, bool isEditing, String errorMessage) $default,) {final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _AppUsersViewState():
|
||||||
|
return $default(_that.isLoading,_that.appUsers,_that.isEditing,_that.errorMessage);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( bool isLoading, List<UserEntity> appUsers, bool isEditing, String errorMessage)? $default,) {final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _AppUsersViewState() when $default != null:
|
||||||
|
return $default(_that.isLoading,_that.appUsers,_that.isEditing,_that.errorMessage);case _:
|
||||||
|
return null;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
|
||||||
|
|
||||||
|
class _AppUsersViewState implements AppUsersViewState {
|
||||||
|
const _AppUsersViewState({this.isLoading = false, final List<UserEntity> appUsers = const [], this.isEditing = false, this.errorMessage = ''}): _appUsers = appUsers;
|
||||||
|
|
||||||
|
|
||||||
|
@override@JsonKey() final bool isLoading;
|
||||||
|
final List<UserEntity> _appUsers;
|
||||||
|
@override@JsonKey() List<UserEntity> get appUsers {
|
||||||
|
if (_appUsers is EqualUnmodifiableListView) return _appUsers;
|
||||||
|
// ignore: implicit_dynamic_type
|
||||||
|
return EqualUnmodifiableListView(_appUsers);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override@JsonKey() final bool isEditing;
|
||||||
|
@override@JsonKey() final String errorMessage;
|
||||||
|
|
||||||
|
/// Create a copy of AppUsersViewState
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
_$AppUsersViewStateCopyWith<_AppUsersViewState> get copyWith => __$AppUsersViewStateCopyWithImpl<_AppUsersViewState>(this, _$identity);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is _AppUsersViewState&&(identical(other.isLoading, isLoading) || other.isLoading == isLoading)&&const DeepCollectionEquality().equals(other._appUsers, _appUsers)&&(identical(other.isEditing, isEditing) || other.isEditing == isEditing)&&(identical(other.errorMessage, errorMessage) || other.errorMessage == errorMessage));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode => Object.hash(runtimeType,isLoading,const DeepCollectionEquality().hash(_appUsers),isEditing,errorMessage);
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'AppUsersViewState(isLoading: $isLoading, appUsers: $appUsers, isEditing: $isEditing, errorMessage: $errorMessage)';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract mixin class _$AppUsersViewStateCopyWith<$Res> implements $AppUsersViewStateCopyWith<$Res> {
|
||||||
|
factory _$AppUsersViewStateCopyWith(_AppUsersViewState value, $Res Function(_AppUsersViewState) _then) = __$AppUsersViewStateCopyWithImpl;
|
||||||
|
@override @useResult
|
||||||
|
$Res call({
|
||||||
|
bool isLoading, List<UserEntity> appUsers, bool isEditing, String errorMessage
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
/// @nodoc
|
||||||
|
class __$AppUsersViewStateCopyWithImpl<$Res>
|
||||||
|
implements _$AppUsersViewStateCopyWith<$Res> {
|
||||||
|
__$AppUsersViewStateCopyWithImpl(this._self, this._then);
|
||||||
|
|
||||||
|
final _AppUsersViewState _self;
|
||||||
|
final $Res Function(_AppUsersViewState) _then;
|
||||||
|
|
||||||
|
/// Create a copy of AppUsersViewState
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override @pragma('vm:prefer-inline') $Res call({Object? isLoading = null,Object? appUsers = null,Object? isEditing = null,Object? errorMessage = null,}) {
|
||||||
|
return _then(_AppUsersViewState(
|
||||||
|
isLoading: null == isLoading ? _self.isLoading : isLoading // ignore: cast_nullable_to_non_nullable
|
||||||
|
as bool,appUsers: null == appUsers ? _self._appUsers : appUsers // ignore: cast_nullable_to_non_nullable
|
||||||
|
as List<UserEntity>,isEditing: null == isEditing ? _self.isEditing : isEditing // ignore: cast_nullable_to_non_nullable
|
||||||
|
as bool,errorMessage: null == errorMessage ? _self.errorMessage : errorMessage // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// dart format on
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import 'package:account/src/features/personal_data/domain/entities/user_entity.dart';
|
import 'package:account/src/core/data/models/entities/user_entity.dart';
|
||||||
|
|
||||||
abstract class GetLoggedUserUseCase {
|
abstract class GetLoggedUserUseCase {
|
||||||
Future<UserEntity> getLoggedUser({required String token});
|
Future<UserEntity> getLoggedUser({required String token});
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import 'package:account/src/core/domain/repositories/account_repository.dart';
|
import 'package:account/src/core/domain/repositories/account_repository.dart';
|
||||||
import 'package:account/src/features/personal_data/domain/entities/user_entity.dart';
|
import 'package:account/src/core/data/models/entities/user_entity.dart';
|
||||||
import 'package:account/src/features/personal_data/domain/get_logged_user_use_case.dart';
|
import 'package:account/src/features/personal_data/domain/get_logged_user_use_case.dart';
|
||||||
|
|
||||||
class GetLoggedUserUseCaseImpl implements GetLoggedUserUseCase {
|
class GetLoggedUserUseCaseImpl implements GetLoggedUserUseCase {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import 'package:account/src/features/personal_data/domain/entities/update_user_request_entity.dart';
|
import 'package:account/src/features/personal_data/domain/entities/update_user_request_entity.dart';
|
||||||
import 'package:account/src/features/personal_data/domain/entities/user_entity.dart';
|
import 'package:account/src/core/data/models/entities/user_entity.dart';
|
||||||
import 'package:account/src/features/personal_data/domain/get_logged_user_use_case.dart';
|
import 'package:account/src/features/personal_data/domain/get_logged_user_use_case.dart';
|
||||||
import 'package:account/src/features/personal_data/domain/update_user_use_case.dart';
|
import 'package:account/src/features/personal_data/domain/update_user_use_case.dart';
|
||||||
import 'package:account/src/features/personal_data/presentation/providers/get_logged_user_use_case_provider.dart';
|
import 'package:account/src/features/personal_data/presentation/providers/get_logged_user_use_case_provider.dart';
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import 'package:account/src/features/personal_data/domain/entities/user_entity.dart';
|
import 'package:account/src/core/data/models/entities/user_entity.dart';
|
||||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||||
|
|
||||||
part 'personal_data_view_state.freezed.dart';
|
part 'personal_data_view_state.freezed.dart';
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ class AppRoutes {
|
|||||||
static const accountSettings = '$legacy/account_settings';
|
static const accountSettings = '$legacy/account_settings';
|
||||||
static const personalData = '$accountSettings/personal_data';
|
static const personalData = '$accountSettings/personal_data';
|
||||||
static const linkedDevices = '$accountSettings/linked_devices';
|
static const linkedDevices = '$accountSettings/linked_devices';
|
||||||
|
static const appUsers = '$accountSettings/app_users';
|
||||||
|
|
||||||
static const legacyDashboard = '$legacy/dashboard';
|
static const legacyDashboard = '$legacy/dashboard';
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user