added functions module and functions and contacts screens, state and use cases
This commit is contained in:
4
.idea/modules.xml
generated
4
.idea/modules.xml
generated
@@ -2,17 +2,19 @@
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/modules/legacy/modules/account/melos_account.iml" filepath="$PROJECT_DIR$/modules/legacy/modules/account/melos_account.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/modules/auth/melos_auth.iml" filepath="$PROJECT_DIR$/modules/auth/melos_auth.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/modules/legacy/modules/customer_service/melos_customer_service.iml" filepath="$PROJECT_DIR$/modules/legacy/modules/customer_service/melos_customer_service.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/modules/dashboard_shell/melos_dashboard_shell.iml" filepath="$PROJECT_DIR$/modules/dashboard_shell/melos_dashboard_shell.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/packages/design_system/melos_design_system.iml" filepath="$PROJECT_DIR$/packages/design_system/melos_design_system.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/packages/fonts/melos_fonts.iml" filepath="$PROJECT_DIR$/packages/fonts/melos_fonts.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/modules/legacy/modules/functions/melos_functions.iml" filepath="$PROJECT_DIR$/modules/legacy/modules/functions/melos_functions.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/modules/home/melos_home.iml" filepath="$PROJECT_DIR$/modules/home/melos_home.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/modules/legacy/modules/hub/melos_hub.iml" filepath="$PROJECT_DIR$/modules/legacy/modules/hub/melos_hub.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/modules/legacy/melos_legacy.iml" filepath="$PROJECT_DIR$/modules/legacy/melos_legacy.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/modules/legacy/modules/legacy_dashboard_shell/melos_legacy_dashboard_shell.iml" filepath="$PROJECT_DIR$/modules/legacy/modules/legacy_dashboard_shell/melos_legacy_dashboard_shell.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/packages/navigation/melos_navigation.iml" filepath="$PROJECT_DIR$/packages/navigation/melos_navigation.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/modules/notifications/melos_notifications.iml" filepath="$PROJECT_DIR$/modules/notifications/melos_notifications.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/modules/payments_dashboard_shell/melos_payments_dashboard_shell.iml" filepath="$PROJECT_DIR$/modules/payments_dashboard_shell/melos_payments_dashboard_shell.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/modules/profile/melos_profile.iml" filepath="$PROJECT_DIR$/modules/profile/melos_profile.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/apps/mobile_app/melos_sf_app_platform.iml" filepath="$PROJECT_DIR$/apps/mobile_app/melos_sf_app_platform.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/packages/sf_infrastructure/melos_sf_infrastructure.iml" filepath="$PROJECT_DIR$/packages/sf_infrastructure/melos_sf_infrastructure.iml" />
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import 'package:auth/auth.dart';
|
||||
import 'package:functions/functions.dart';
|
||||
import 'package:legacy_dashboard_shell/legacy_dashboard_builder.dart';
|
||||
import 'package:dashboard_shell/dashboard_builder.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
@@ -40,8 +41,22 @@ void configureAppRouter() {
|
||||
),
|
||||
],
|
||||
),
|
||||
StatefulShellBranch(
|
||||
routes: [
|
||||
GoRoute(
|
||||
path: AppRoutes.dashboardFunctions,
|
||||
name: 'functions',
|
||||
pageBuilder: FunctionsBuilder().buildPage,
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
GoRoute(
|
||||
path: AppRoutes.contacts,
|
||||
name: 'contacts',
|
||||
pageBuilder: ContactsBuilder().buildPage,
|
||||
),
|
||||
|
||||
GoRoute(
|
||||
path: AppRoutes.login,
|
||||
|
||||
@@ -53,6 +53,8 @@ dependencies:
|
||||
path: ../../modules/legacy/modules/legacy_dashboard_shell
|
||||
splash:
|
||||
path: ../../modules/splash
|
||||
functions:
|
||||
path: ../../modules/legacy/modules/functions
|
||||
#packages dependencies go here
|
||||
navigation:
|
||||
path: ../../packages/navigation
|
||||
|
||||
@@ -17,10 +17,13 @@
|
||||
<excludeFolder url="file://$MODULE_DIR$/macos/Flutter" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/macos/Pods" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/macos/.symlinks" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/modules/functions/.dart_tool" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/modules/functions/.pub" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/modules/functions/build" />
|
||||
</content>
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="library" name="Dart SDK" level="project" />
|
||||
<orderEntry type="library" name="Flutter Plugins" level="project" />
|
||||
<orderEntry type="library" name="Dart Packages" level="project" />
|
||||
</component>
|
||||
</module>
|
||||
</module>
|
||||
@@ -0,0 +1,5 @@
|
||||
import 'package:functions/src/features/contacts/domain/entities/contact_list_entity.dart';
|
||||
|
||||
abstract class FunctionsRemoteDatasource {
|
||||
Future<ContactListEntity> getContacts({required String deviceId});
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:dio/dio.dart';
|
||||
// import 'package:flutter/material.dart';
|
||||
import 'package:functions/src/core/data/datasources/functions_remote_datasource.dart';
|
||||
import 'package:functions/src/features/contacts/domain/entities/contact_list_entity.dart';
|
||||
import 'package:functions/src/features/contacts/domain/entities/list_contact_entity.dart';
|
||||
import 'package:sf_infrastructure/sf_infrastructure.dart';
|
||||
|
||||
class FunctionsRemoteDatasourceImpl implements FunctionsRemoteDatasource {
|
||||
FunctionsRemoteDatasourceImpl(this._repository);
|
||||
|
||||
final QuestiaRepository _repository;
|
||||
|
||||
@override
|
||||
Future<ContactListEntity> getContacts({required String deviceId}) async {
|
||||
/*try {
|
||||
final response = await _repository.post<Map<String, dynamic>>(
|
||||
'/devices/$deviceId/contact-lists',
|
||||
);
|
||||
|
||||
final data = response.data;
|
||||
if (data == null || data.isEmpty) {
|
||||
throw Exception('Empty response from /devices/:deviceId/contact-lists');
|
||||
}
|
||||
|
||||
final model = GetContactsResponseModel.fromJson(data);
|
||||
return model.toEntity();
|
||||
} on DioException catch (error) {
|
||||
throw _mapDioError(error, defaultMessage: 'Error to get contacts');
|
||||
}*/
|
||||
return ContactListEntity(
|
||||
id: 'id',
|
||||
delegationId: 'delegationId',
|
||||
userId: 'userId',
|
||||
groupId: 'groupId',
|
||||
deviceId: 'deviceId',
|
||||
type: 'type',
|
||||
contacts: [
|
||||
ListContactEntity(name: 'Ana', phone: '111111111'),
|
||||
ListContactEntity(name: 'Carlos', phone: '222222222'),
|
||||
],
|
||||
createdAt: 'createdAt',
|
||||
updatedAt: 'updatedAt'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Exception _mapDioError(DioException error, {required String defaultMessage}) {
|
||||
final apiMsg = _extractApiMessage(error.response?.data);
|
||||
final msg = apiMsg ?? error.message ?? defaultMessage;
|
||||
return Exception(msg);
|
||||
}
|
||||
|
||||
String? _extractApiMessage(Object? data) {
|
||||
if (data == null) return null;
|
||||
|
||||
if (data is Map) {
|
||||
final errorObj = data['error'];
|
||||
if (errorObj is Map && errorObj['message'] is String) {
|
||||
return (errorObj['message'] as String).trim();
|
||||
}
|
||||
if (data['message'] is String) {
|
||||
return (data['message'] as String).trim();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
if (data is String) {
|
||||
final raw = data.trim();
|
||||
if (raw.isEmpty) return null;
|
||||
|
||||
try {
|
||||
final decoded = jsonDecode(raw);
|
||||
return _extractApiMessage(decoded);
|
||||
} catch (_) {
|
||||
return raw;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
import 'package:functions/src/core/data/datasources/functions_remote_datasource.dart';
|
||||
import 'package:functions/src/core/domain/repositories/functions_repository.dart';
|
||||
import 'package:functions/src/features/contacts/domain/entities/contact_list_entity.dart';
|
||||
|
||||
class FunctionsRepositoryImpl implements FunctionsRepository {
|
||||
const FunctionsRepositoryImpl(this._remote);
|
||||
|
||||
final FunctionsRemoteDatasource _remote;
|
||||
|
||||
@override
|
||||
Future<ContactListEntity> getContacts({required String deviceId}) {
|
||||
return _remote.getContacts(deviceId: deviceId);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
import 'package:functions/src/features/contacts/domain/entities/contact_list_entity.dart';
|
||||
|
||||
abstract class FunctionsRepository {
|
||||
Future<ContactListEntity> getContacts({required String deviceId});
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:functions/src/core/data/datasources/functions_remote_datasource.dart';
|
||||
import 'package:functions/src/core/data/datasources/functions_remote_datasource_impl.dart';
|
||||
import 'package:sf_infrastructure/sf_infrastructure.dart';
|
||||
|
||||
final functionsRemoteDatasourceProvider = Provider<FunctionsRemoteDatasource>((ref) {
|
||||
final questiaRepository = getIt<QuestiaRepository>();
|
||||
return FunctionsRemoteDatasourceImpl(questiaRepository);
|
||||
});
|
||||
@@ -0,0 +1,9 @@
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:functions/src/core/providers/functions_remote_datasource_provider.dart';
|
||||
import 'package:functions/src/core/data/repositories/functions_repository_impl.dart';
|
||||
import 'package:functions/src/core/domain/repositories/functions_repository.dart';
|
||||
|
||||
final functionsRepositoryProvider = Provider<FunctionsRepository>((ref) {
|
||||
final remote = ref.read(functionsRemoteDatasourceProvider);
|
||||
return FunctionsRepositoryImpl(remote);
|
||||
});
|
||||
@@ -0,0 +1,18 @@
|
||||
import 'presentation/contacts_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 ContactsBuilder {
|
||||
const ContactsBuilder();
|
||||
|
||||
Page<void> buildPage(BuildContext context, GoRouterState state) {
|
||||
final NavigationContract navigationContract = GetIt.I<NavigationContract>();
|
||||
|
||||
return MaterialPage<void>(
|
||||
key: state.pageKey,
|
||||
child: ContactsScreen(navigationContract: navigationContract),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'package:functions/src/features/contacts/domain/entities/list_contact_entity.dart';
|
||||
|
||||
part 'contact_list_entity.freezed.dart';
|
||||
|
||||
@freezed
|
||||
abstract class ContactListEntity with _$ContactListEntity {
|
||||
const factory ContactListEntity({
|
||||
required String id,
|
||||
required String delegationId,
|
||||
required String userId,
|
||||
required String groupId,
|
||||
required String deviceId,
|
||||
required String type,
|
||||
required List<ListContactEntity> contacts,
|
||||
required String createdAt,
|
||||
required String updatedAt
|
||||
}) = _ContactListEntity;
|
||||
}
|
||||
@@ -0,0 +1,301 @@
|
||||
// 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 'contact_list_entity.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// FreezedGenerator
|
||||
// **************************************************************************
|
||||
|
||||
// dart format off
|
||||
T _$identity<T>(T value) => value;
|
||||
/// @nodoc
|
||||
mixin _$ContactListEntity {
|
||||
|
||||
String get id; String get delegationId; String get userId; String get groupId; String get deviceId; String get type; List<ListContactEntity> get contacts; String get createdAt; String get updatedAt;
|
||||
/// Create a copy of ContactListEntity
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
$ContactListEntityCopyWith<ContactListEntity> get copyWith => _$ContactListEntityCopyWithImpl<ContactListEntity>(this as ContactListEntity, _$identity);
|
||||
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is ContactListEntity&&(identical(other.id, id) || other.id == id)&&(identical(other.delegationId, delegationId) || other.delegationId == delegationId)&&(identical(other.userId, userId) || other.userId == userId)&&(identical(other.groupId, groupId) || other.groupId == groupId)&&(identical(other.deviceId, deviceId) || other.deviceId == deviceId)&&(identical(other.type, type) || other.type == type)&&const DeepCollectionEquality().equals(other.contacts, contacts)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt));
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,id,delegationId,userId,groupId,deviceId,type,const DeepCollectionEquality().hash(contacts),createdAt,updatedAt);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'ContactListEntity(id: $id, delegationId: $delegationId, userId: $userId, groupId: $groupId, deviceId: $deviceId, type: $type, contacts: $contacts, createdAt: $createdAt, updatedAt: $updatedAt)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class $ContactListEntityCopyWith<$Res> {
|
||||
factory $ContactListEntityCopyWith(ContactListEntity value, $Res Function(ContactListEntity) _then) = _$ContactListEntityCopyWithImpl;
|
||||
@useResult
|
||||
$Res call({
|
||||
String id, String delegationId, String userId, String groupId, String deviceId, String type, List<ListContactEntity> contacts, String createdAt, String updatedAt
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class _$ContactListEntityCopyWithImpl<$Res>
|
||||
implements $ContactListEntityCopyWith<$Res> {
|
||||
_$ContactListEntityCopyWithImpl(this._self, this._then);
|
||||
|
||||
final ContactListEntity _self;
|
||||
final $Res Function(ContactListEntity) _then;
|
||||
|
||||
/// Create a copy of ContactListEntity
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? delegationId = null,Object? userId = null,Object? groupId = null,Object? deviceId = null,Object? type = null,Object? contacts = null,Object? createdAt = null,Object? updatedAt = null,}) {
|
||||
return _then(_self.copyWith(
|
||||
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
||||
as String,delegationId: null == delegationId ? _self.delegationId : delegationId // ignore: cast_nullable_to_non_nullable
|
||||
as String,userId: null == userId ? _self.userId : userId // ignore: cast_nullable_to_non_nullable
|
||||
as String,groupId: null == groupId ? _self.groupId : groupId // ignore: cast_nullable_to_non_nullable
|
||||
as String,deviceId: null == deviceId ? _self.deviceId : deviceId // ignore: cast_nullable_to_non_nullable
|
||||
as String,type: null == type ? _self.type : type // ignore: cast_nullable_to_non_nullable
|
||||
as String,contacts: null == contacts ? _self.contacts : contacts // ignore: cast_nullable_to_non_nullable
|
||||
as List<ListContactEntity>,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
|
||||
as String,updatedAt: null == updatedAt ? _self.updatedAt : updatedAt // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// Adds pattern-matching-related methods to [ContactListEntity].
|
||||
extension ContactListEntityPatterns on ContactListEntity {
|
||||
/// 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( _ContactListEntity value)? $default,{required TResult orElse(),}){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _ContactListEntity() 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( _ContactListEntity value) $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _ContactListEntity():
|
||||
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( _ContactListEntity value)? $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _ContactListEntity() 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 delegationId, String userId, String groupId, String deviceId, String type, List<ListContactEntity> contacts, String createdAt, String updatedAt)? $default,{required TResult orElse(),}) {final _that = this;
|
||||
switch (_that) {
|
||||
case _ContactListEntity() when $default != null:
|
||||
return $default(_that.id,_that.delegationId,_that.userId,_that.groupId,_that.deviceId,_that.type,_that.contacts,_that.createdAt,_that.updatedAt);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 delegationId, String userId, String groupId, String deviceId, String type, List<ListContactEntity> contacts, String createdAt, String updatedAt) $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _ContactListEntity():
|
||||
return $default(_that.id,_that.delegationId,_that.userId,_that.groupId,_that.deviceId,_that.type,_that.contacts,_that.createdAt,_that.updatedAt);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 delegationId, String userId, String groupId, String deviceId, String type, List<ListContactEntity> contacts, String createdAt, String updatedAt)? $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _ContactListEntity() when $default != null:
|
||||
return $default(_that.id,_that.delegationId,_that.userId,_that.groupId,_that.deviceId,_that.type,_that.contacts,_that.createdAt,_that.updatedAt);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
|
||||
|
||||
class _ContactListEntity implements ContactListEntity {
|
||||
const _ContactListEntity({required this.id, required this.delegationId, required this.userId, required this.groupId, required this.deviceId, required this.type, required final List<ListContactEntity> contacts, required this.createdAt, required this.updatedAt}): _contacts = contacts;
|
||||
|
||||
|
||||
@override final String id;
|
||||
@override final String delegationId;
|
||||
@override final String userId;
|
||||
@override final String groupId;
|
||||
@override final String deviceId;
|
||||
@override final String type;
|
||||
final List<ListContactEntity> _contacts;
|
||||
@override List<ListContactEntity> get contacts {
|
||||
if (_contacts is EqualUnmodifiableListView) return _contacts;
|
||||
// ignore: implicit_dynamic_type
|
||||
return EqualUnmodifiableListView(_contacts);
|
||||
}
|
||||
|
||||
@override final String createdAt;
|
||||
@override final String updatedAt;
|
||||
|
||||
/// Create a copy of ContactListEntity
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
_$ContactListEntityCopyWith<_ContactListEntity> get copyWith => __$ContactListEntityCopyWithImpl<_ContactListEntity>(this, _$identity);
|
||||
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _ContactListEntity&&(identical(other.id, id) || other.id == id)&&(identical(other.delegationId, delegationId) || other.delegationId == delegationId)&&(identical(other.userId, userId) || other.userId == userId)&&(identical(other.groupId, groupId) || other.groupId == groupId)&&(identical(other.deviceId, deviceId) || other.deviceId == deviceId)&&(identical(other.type, type) || other.type == type)&&const DeepCollectionEquality().equals(other._contacts, _contacts)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt));
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,id,delegationId,userId,groupId,deviceId,type,const DeepCollectionEquality().hash(_contacts),createdAt,updatedAt);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'ContactListEntity(id: $id, delegationId: $delegationId, userId: $userId, groupId: $groupId, deviceId: $deviceId, type: $type, contacts: $contacts, createdAt: $createdAt, updatedAt: $updatedAt)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class _$ContactListEntityCopyWith<$Res> implements $ContactListEntityCopyWith<$Res> {
|
||||
factory _$ContactListEntityCopyWith(_ContactListEntity value, $Res Function(_ContactListEntity) _then) = __$ContactListEntityCopyWithImpl;
|
||||
@override @useResult
|
||||
$Res call({
|
||||
String id, String delegationId, String userId, String groupId, String deviceId, String type, List<ListContactEntity> contacts, String createdAt, String updatedAt
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class __$ContactListEntityCopyWithImpl<$Res>
|
||||
implements _$ContactListEntityCopyWith<$Res> {
|
||||
__$ContactListEntityCopyWithImpl(this._self, this._then);
|
||||
|
||||
final _ContactListEntity _self;
|
||||
final $Res Function(_ContactListEntity) _then;
|
||||
|
||||
/// Create a copy of ContactListEntity
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? delegationId = null,Object? userId = null,Object? groupId = null,Object? deviceId = null,Object? type = null,Object? contacts = null,Object? createdAt = null,Object? updatedAt = null,}) {
|
||||
return _then(_ContactListEntity(
|
||||
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
||||
as String,delegationId: null == delegationId ? _self.delegationId : delegationId // ignore: cast_nullable_to_non_nullable
|
||||
as String,userId: null == userId ? _self.userId : userId // ignore: cast_nullable_to_non_nullable
|
||||
as String,groupId: null == groupId ? _self.groupId : groupId // ignore: cast_nullable_to_non_nullable
|
||||
as String,deviceId: null == deviceId ? _self.deviceId : deviceId // ignore: cast_nullable_to_non_nullable
|
||||
as String,type: null == type ? _self.type : type // ignore: cast_nullable_to_non_nullable
|
||||
as String,contacts: null == contacts ? _self._contacts : contacts // ignore: cast_nullable_to_non_nullable
|
||||
as List<ListContactEntity>,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
|
||||
as String,updatedAt: null == updatedAt ? _self.updatedAt : updatedAt // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// dart format on
|
||||
@@ -0,0 +1,11 @@
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
part 'list_contact_entity.freezed.dart';
|
||||
|
||||
@freezed
|
||||
abstract class ListContactEntity with _$ListContactEntity {
|
||||
const factory ListContactEntity({
|
||||
required String name,
|
||||
required String phone,
|
||||
}) = _ListContactEntity;
|
||||
}
|
||||
@@ -0,0 +1,274 @@
|
||||
// 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 'list_contact_entity.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// FreezedGenerator
|
||||
// **************************************************************************
|
||||
|
||||
// dart format off
|
||||
T _$identity<T>(T value) => value;
|
||||
/// @nodoc
|
||||
mixin _$ListContactEntity {
|
||||
|
||||
String get name; String get phone;
|
||||
/// Create a copy of ListContactEntity
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
$ListContactEntityCopyWith<ListContactEntity> get copyWith => _$ListContactEntityCopyWithImpl<ListContactEntity>(this as ListContactEntity, _$identity);
|
||||
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is ListContactEntity&&(identical(other.name, name) || other.name == name)&&(identical(other.phone, phone) || other.phone == phone));
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,name,phone);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'ListContactEntity(name: $name, phone: $phone)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class $ListContactEntityCopyWith<$Res> {
|
||||
factory $ListContactEntityCopyWith(ListContactEntity value, $Res Function(ListContactEntity) _then) = _$ListContactEntityCopyWithImpl;
|
||||
@useResult
|
||||
$Res call({
|
||||
String name, String phone
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class _$ListContactEntityCopyWithImpl<$Res>
|
||||
implements $ListContactEntityCopyWith<$Res> {
|
||||
_$ListContactEntityCopyWithImpl(this._self, this._then);
|
||||
|
||||
final ListContactEntity _self;
|
||||
final $Res Function(ListContactEntity) _then;
|
||||
|
||||
/// Create a copy of ListContactEntity
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline') @override $Res call({Object? name = null,Object? phone = null,}) {
|
||||
return _then(_self.copyWith(
|
||||
name: null == name ? _self.name : name // ignore: cast_nullable_to_non_nullable
|
||||
as String,phone: null == phone ? _self.phone : phone // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// Adds pattern-matching-related methods to [ListContactEntity].
|
||||
extension ListContactEntityPatterns on ListContactEntity {
|
||||
/// 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( _ListContactEntity value)? $default,{required TResult orElse(),}){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _ListContactEntity() 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( _ListContactEntity value) $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _ListContactEntity():
|
||||
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( _ListContactEntity value)? $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _ListContactEntity() 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 name, String phone)? $default,{required TResult orElse(),}) {final _that = this;
|
||||
switch (_that) {
|
||||
case _ListContactEntity() when $default != null:
|
||||
return $default(_that.name,_that.phone);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 name, String phone) $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _ListContactEntity():
|
||||
return $default(_that.name,_that.phone);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 name, String phone)? $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _ListContactEntity() when $default != null:
|
||||
return $default(_that.name,_that.phone);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
|
||||
|
||||
class _ListContactEntity implements ListContactEntity {
|
||||
const _ListContactEntity({required this.name, required this.phone});
|
||||
|
||||
|
||||
@override final String name;
|
||||
@override final String phone;
|
||||
|
||||
/// Create a copy of ListContactEntity
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
_$ListContactEntityCopyWith<_ListContactEntity> get copyWith => __$ListContactEntityCopyWithImpl<_ListContactEntity>(this, _$identity);
|
||||
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _ListContactEntity&&(identical(other.name, name) || other.name == name)&&(identical(other.phone, phone) || other.phone == phone));
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,name,phone);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'ListContactEntity(name: $name, phone: $phone)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class _$ListContactEntityCopyWith<$Res> implements $ListContactEntityCopyWith<$Res> {
|
||||
factory _$ListContactEntityCopyWith(_ListContactEntity value, $Res Function(_ListContactEntity) _then) = __$ListContactEntityCopyWithImpl;
|
||||
@override @useResult
|
||||
$Res call({
|
||||
String name, String phone
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class __$ListContactEntityCopyWithImpl<$Res>
|
||||
implements _$ListContactEntityCopyWith<$Res> {
|
||||
__$ListContactEntityCopyWithImpl(this._self, this._then);
|
||||
|
||||
final _ListContactEntity _self;
|
||||
final $Res Function(_ListContactEntity) _then;
|
||||
|
||||
/// Create a copy of ListContactEntity
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @pragma('vm:prefer-inline') $Res call({Object? name = null,Object? phone = null,}) {
|
||||
return _then(_ListContactEntity(
|
||||
name: null == name ? _self.name : name // ignore: cast_nullable_to_non_nullable
|
||||
as String,phone: null == phone ? _self.phone : phone // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// dart format on
|
||||
@@ -0,0 +1,5 @@
|
||||
import 'package:functions/src/features/contacts/domain/entities/contact_list_entity.dart';
|
||||
|
||||
abstract class GetContactsUseCase {
|
||||
Future<ContactListEntity> getContacts({required String deviceId});
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
import 'package:functions/src/core/domain/repositories/functions_repository.dart';
|
||||
import 'package:functions/src/features/contacts/domain/entities/contact_list_entity.dart';
|
||||
import 'package:functions/src/features/contacts/domain/get_contacts_use_case.dart';
|
||||
|
||||
class GetContactsUseCaseImpl implements GetContactsUseCase {
|
||||
GetContactsUseCaseImpl(this._repository);
|
||||
|
||||
final FunctionsRepository _repository;
|
||||
|
||||
@override
|
||||
Future<ContactListEntity> getContacts({required String deviceId}) {
|
||||
return _repository.getContacts(deviceId: deviceId);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,212 @@
|
||||
import 'package:design_system/design_system.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:functions/src/features/contacts/domain/entities/list_contact_entity.dart';
|
||||
import 'package:functions/src/features/contacts/presentation/state/contacts_view_model.dart';
|
||||
import 'package:navigation/navigation.dart';
|
||||
import 'package:sf_localizations/sf_localizations.dart';
|
||||
import 'package:utils/utils.dart';
|
||||
|
||||
class ContactsScreen extends ConsumerWidget {
|
||||
final NavigationContract navigationContract;
|
||||
|
||||
const ContactsScreen({super.key, required this.navigationContract});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final vm = ref.read(contactsViewModelProvider.notifier);
|
||||
final state = ref.watch(contactsViewModelProvider);
|
||||
|
||||
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('Agenda'),
|
||||
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)=>ContactCard(
|
||||
contact: state.contactList!.contacts[index],
|
||||
isEditing: state.isEditing,
|
||||
),
|
||||
separatorBuilder: (BuildContext context, int index)=>SizedBox(
|
||||
height: SizeUtils.getByScreen(small: 18, big: 17)
|
||||
),
|
||||
itemCount: state.contactList?.contacts.length ?? 0
|
||||
),
|
||||
)),
|
||||
if (state.isEditing) ...[
|
||||
Container(
|
||||
padding: SizeUtils.getByScreen(
|
||||
small: EdgeInsets.symmetric(horizontal: 26, vertical: 14),
|
||||
big: EdgeInsets.symmetric(horizontal: 24, vertical: 12)
|
||||
),
|
||||
),
|
||||
]
|
||||
],
|
||||
)
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class ContactCard extends ConsumerWidget {
|
||||
|
||||
final ListContactEntity contact;
|
||||
final bool isEditing;
|
||||
|
||||
const ContactCard({
|
||||
required this.contact,
|
||||
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(contact.name,
|
||||
style: TextStyle(
|
||||
fontSize: SizeUtils.getByScreen(small: 18, big: 19),
|
||||
fontWeight: FontWeight.w500
|
||||
)
|
||||
),
|
||||
Text(contact.phone,
|
||||
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(context.translate(I18n.legacyDeleteUserDialog),
|
||||
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: context.translate(I18n.legacyCancel),
|
||||
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: context.translate(I18n.legacyDelete),
|
||||
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:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:functions/src/core/providers/functions_repository_provider.dart';
|
||||
import 'package:functions/src/features/contacts/domain/get_contacts_use_case.dart';
|
||||
import 'package:functions/src/features/contacts/domain/get_contacts_use_case_impl.dart';
|
||||
|
||||
final getContactsUseCaseProvider = Provider.autoDispose<GetContactsUseCase>((ref) {
|
||||
final functionsRepository = ref.read(functionsRepositoryProvider);
|
||||
return GetContactsUseCaseImpl(functionsRepository);
|
||||
});
|
||||
@@ -0,0 +1,56 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:functions/src/features/contacts/domain/entities/contact_list_entity.dart';
|
||||
import 'package:functions/src/features/contacts/domain/get_contacts_use_case.dart';
|
||||
import 'package:functions/src/features/contacts/presentation/providers/get_contacts_provider.dart';
|
||||
import 'package:functions/src/features/contacts/presentation/state/contacts_view_state.dart';
|
||||
// import 'package:sf_localizations/sf_localizations.dart';
|
||||
|
||||
final contactsViewModelProvider =
|
||||
NotifierProvider.autoDispose<ContactsViewModel, ContactsViewState>(
|
||||
ContactsViewModel.new,
|
||||
);
|
||||
|
||||
class ContactsViewModel extends Notifier<ContactsViewState> {
|
||||
late final GetContactsUseCase _getContactsUseCase;
|
||||
|
||||
late final TextEditingController nameController;
|
||||
|
||||
@override
|
||||
ContactsViewState build() {
|
||||
_getContactsUseCase = ref.read(getContactsUseCaseProvider);
|
||||
|
||||
nameController = TextEditingController();
|
||||
|
||||
nameController.addListener(_onNameChanged);
|
||||
|
||||
_getContactsUseCase.getContacts(deviceId: '').then(setContacts);
|
||||
|
||||
ref.onDispose(disposeControllers);
|
||||
|
||||
return const ContactsViewState();
|
||||
}
|
||||
|
||||
void setContacts(ContactListEntity contactList) {
|
||||
state = state.copyWith(
|
||||
contactList: contactList
|
||||
);
|
||||
}
|
||||
|
||||
void toggleIsEditing() {
|
||||
state = state.copyWith(isEditing: !state.isEditing);
|
||||
}
|
||||
|
||||
void _onNameChanged() {
|
||||
final text = nameController.text;
|
||||
if (text == state.name) return;
|
||||
|
||||
state = state.copyWith(name: text, errorMessage: '');
|
||||
}
|
||||
|
||||
void disposeControllers() {
|
||||
nameController.removeListener(_onNameChanged);
|
||||
|
||||
nameController.dispose();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'package:functions/src/features/contacts/domain/entities/contact_list_entity.dart';
|
||||
|
||||
part 'contacts_view_state.freezed.dart';
|
||||
|
||||
@freezed
|
||||
abstract class ContactsViewState with _$ContactsViewState {
|
||||
const factory ContactsViewState({
|
||||
@Default(null) ContactListEntity? contactList,
|
||||
@Default(false) bool isLoading,
|
||||
@Default(false) bool isEditing,
|
||||
@Default('') String name,
|
||||
@Default('') String phone,
|
||||
@Default('') String errorMessage,
|
||||
}) = _ContactsViewState;
|
||||
}
|
||||
@@ -0,0 +1,310 @@
|
||||
// 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 'contacts_view_state.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// FreezedGenerator
|
||||
// **************************************************************************
|
||||
|
||||
// dart format off
|
||||
T _$identity<T>(T value) => value;
|
||||
/// @nodoc
|
||||
mixin _$ContactsViewState {
|
||||
|
||||
ContactListEntity? get contactList; bool get isLoading; bool get isEditing; String get name; String get phone; String get errorMessage;
|
||||
/// Create a copy of ContactsViewState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
$ContactsViewStateCopyWith<ContactsViewState> get copyWith => _$ContactsViewStateCopyWithImpl<ContactsViewState>(this as ContactsViewState, _$identity);
|
||||
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is ContactsViewState&&(identical(other.contactList, contactList) || other.contactList == contactList)&&(identical(other.isLoading, isLoading) || other.isLoading == isLoading)&&(identical(other.isEditing, isEditing) || other.isEditing == isEditing)&&(identical(other.name, name) || other.name == name)&&(identical(other.phone, phone) || other.phone == phone)&&(identical(other.errorMessage, errorMessage) || other.errorMessage == errorMessage));
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,contactList,isLoading,isEditing,name,phone,errorMessage);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'ContactsViewState(contactList: $contactList, isLoading: $isLoading, isEditing: $isEditing, name: $name, phone: $phone, errorMessage: $errorMessage)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class $ContactsViewStateCopyWith<$Res> {
|
||||
factory $ContactsViewStateCopyWith(ContactsViewState value, $Res Function(ContactsViewState) _then) = _$ContactsViewStateCopyWithImpl;
|
||||
@useResult
|
||||
$Res call({
|
||||
ContactListEntity? contactList, bool isLoading, bool isEditing, String name, String phone, String errorMessage
|
||||
});
|
||||
|
||||
|
||||
$ContactListEntityCopyWith<$Res>? get contactList;
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class _$ContactsViewStateCopyWithImpl<$Res>
|
||||
implements $ContactsViewStateCopyWith<$Res> {
|
||||
_$ContactsViewStateCopyWithImpl(this._self, this._then);
|
||||
|
||||
final ContactsViewState _self;
|
||||
final $Res Function(ContactsViewState) _then;
|
||||
|
||||
/// Create a copy of ContactsViewState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline') @override $Res call({Object? contactList = freezed,Object? isLoading = null,Object? isEditing = null,Object? name = null,Object? phone = null,Object? errorMessage = null,}) {
|
||||
return _then(_self.copyWith(
|
||||
contactList: freezed == contactList ? _self.contactList : contactList // ignore: cast_nullable_to_non_nullable
|
||||
as ContactListEntity?,isLoading: null == isLoading ? _self.isLoading : isLoading // ignore: cast_nullable_to_non_nullable
|
||||
as bool,isEditing: null == isEditing ? _self.isEditing : isEditing // ignore: cast_nullable_to_non_nullable
|
||||
as bool,name: null == name ? _self.name : name // ignore: cast_nullable_to_non_nullable
|
||||
as String,phone: null == phone ? _self.phone : phone // ignore: cast_nullable_to_non_nullable
|
||||
as String,errorMessage: null == errorMessage ? _self.errorMessage : errorMessage // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
));
|
||||
}
|
||||
/// Create a copy of ContactsViewState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override
|
||||
@pragma('vm:prefer-inline')
|
||||
$ContactListEntityCopyWith<$Res>? get contactList {
|
||||
if (_self.contactList == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $ContactListEntityCopyWith<$Res>(_self.contactList!, (value) {
|
||||
return _then(_self.copyWith(contactList: value));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Adds pattern-matching-related methods to [ContactsViewState].
|
||||
extension ContactsViewStatePatterns on ContactsViewState {
|
||||
/// 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( _ContactsViewState value)? $default,{required TResult orElse(),}){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _ContactsViewState() 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( _ContactsViewState value) $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _ContactsViewState():
|
||||
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( _ContactsViewState value)? $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _ContactsViewState() 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( ContactListEntity? contactList, bool isLoading, bool isEditing, String name, String phone, String errorMessage)? $default,{required TResult orElse(),}) {final _that = this;
|
||||
switch (_that) {
|
||||
case _ContactsViewState() when $default != null:
|
||||
return $default(_that.contactList,_that.isLoading,_that.isEditing,_that.name,_that.phone,_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( ContactListEntity? contactList, bool isLoading, bool isEditing, String name, String phone, String errorMessage) $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _ContactsViewState():
|
||||
return $default(_that.contactList,_that.isLoading,_that.isEditing,_that.name,_that.phone,_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( ContactListEntity? contactList, bool isLoading, bool isEditing, String name, String phone, String errorMessage)? $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _ContactsViewState() when $default != null:
|
||||
return $default(_that.contactList,_that.isLoading,_that.isEditing,_that.name,_that.phone,_that.errorMessage);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
|
||||
|
||||
class _ContactsViewState implements ContactsViewState {
|
||||
const _ContactsViewState({this.contactList = null, this.isLoading = false, this.isEditing = false, this.name = '', this.phone = '', this.errorMessage = ''});
|
||||
|
||||
|
||||
@override@JsonKey() final ContactListEntity? contactList;
|
||||
@override@JsonKey() final bool isLoading;
|
||||
@override@JsonKey() final bool isEditing;
|
||||
@override@JsonKey() final String name;
|
||||
@override@JsonKey() final String phone;
|
||||
@override@JsonKey() final String errorMessage;
|
||||
|
||||
/// Create a copy of ContactsViewState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
_$ContactsViewStateCopyWith<_ContactsViewState> get copyWith => __$ContactsViewStateCopyWithImpl<_ContactsViewState>(this, _$identity);
|
||||
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _ContactsViewState&&(identical(other.contactList, contactList) || other.contactList == contactList)&&(identical(other.isLoading, isLoading) || other.isLoading == isLoading)&&(identical(other.isEditing, isEditing) || other.isEditing == isEditing)&&(identical(other.name, name) || other.name == name)&&(identical(other.phone, phone) || other.phone == phone)&&(identical(other.errorMessage, errorMessage) || other.errorMessage == errorMessage));
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,contactList,isLoading,isEditing,name,phone,errorMessage);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'ContactsViewState(contactList: $contactList, isLoading: $isLoading, isEditing: $isEditing, name: $name, phone: $phone, errorMessage: $errorMessage)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class _$ContactsViewStateCopyWith<$Res> implements $ContactsViewStateCopyWith<$Res> {
|
||||
factory _$ContactsViewStateCopyWith(_ContactsViewState value, $Res Function(_ContactsViewState) _then) = __$ContactsViewStateCopyWithImpl;
|
||||
@override @useResult
|
||||
$Res call({
|
||||
ContactListEntity? contactList, bool isLoading, bool isEditing, String name, String phone, String errorMessage
|
||||
});
|
||||
|
||||
|
||||
@override $ContactListEntityCopyWith<$Res>? get contactList;
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class __$ContactsViewStateCopyWithImpl<$Res>
|
||||
implements _$ContactsViewStateCopyWith<$Res> {
|
||||
__$ContactsViewStateCopyWithImpl(this._self, this._then);
|
||||
|
||||
final _ContactsViewState _self;
|
||||
final $Res Function(_ContactsViewState) _then;
|
||||
|
||||
/// Create a copy of ContactsViewState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @pragma('vm:prefer-inline') $Res call({Object? contactList = freezed,Object? isLoading = null,Object? isEditing = null,Object? name = null,Object? phone = null,Object? errorMessage = null,}) {
|
||||
return _then(_ContactsViewState(
|
||||
contactList: freezed == contactList ? _self.contactList : contactList // ignore: cast_nullable_to_non_nullable
|
||||
as ContactListEntity?,isLoading: null == isLoading ? _self.isLoading : isLoading // ignore: cast_nullable_to_non_nullable
|
||||
as bool,isEditing: null == isEditing ? _self.isEditing : isEditing // ignore: cast_nullable_to_non_nullable
|
||||
as bool,name: null == name ? _self.name : name // ignore: cast_nullable_to_non_nullable
|
||||
as String,phone: null == phone ? _self.phone : phone // ignore: cast_nullable_to_non_nullable
|
||||
as String,errorMessage: null == errorMessage ? _self.errorMessage : errorMessage // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
));
|
||||
}
|
||||
|
||||
/// Create a copy of ContactsViewState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override
|
||||
@pragma('vm:prefer-inline')
|
||||
$ContactListEntityCopyWith<$Res>? get contactList {
|
||||
if (_self.contactList == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $ContactListEntityCopyWith<$Res>(_self.contactList!, (value) {
|
||||
return _then(_self.copyWith(contactList: value));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// dart format on
|
||||
@@ -0,0 +1,18 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:functions/src/features/functions/functions_screen.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:get_it/get_it.dart';
|
||||
import 'package:navigation/navigation.dart';
|
||||
|
||||
class FunctionsBuilder {
|
||||
const FunctionsBuilder();
|
||||
|
||||
Page<void> buildPage(BuildContext context, GoRouterState state) {
|
||||
final NavigationContract navigationContract = GetIt.I<NavigationContract>();
|
||||
|
||||
return MaterialPage<void>(
|
||||
key: state.pageKey,
|
||||
child: FunctionsScreen(navigationContract: navigationContract),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,179 @@
|
||||
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 FunctionsScreen extends ConsumerWidget {
|
||||
final NavigationContract navigationContract;
|
||||
|
||||
const FunctionsScreen({super.key, required this.navigationContract});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
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: [
|
||||
IconButton(onPressed: () {Navigator.pop(context);},
|
||||
icon: Icon(Icons.arrow_back)),
|
||||
Center(
|
||||
child: Text(context.translate('Device Features'),
|
||||
style: TextStyle(
|
||||
fontSize: SizeUtils.getByScreen(small: 28, big: 27)
|
||||
),
|
||||
)
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(height: SizeUtils.getByScreen(small: 30, big: 28)),
|
||||
Expanded(child: SingleChildScrollView(child: Container(
|
||||
padding: SizeUtils.getByScreen(
|
||||
small: EdgeInsets.symmetric(horizontal: 22, vertical: 10),
|
||||
big: EdgeInsets.symmetric(horizontal: 21, vertical: 8)
|
||||
),
|
||||
child: Column(
|
||||
children: [
|
||||
AppSectionButton(
|
||||
onPressed: (){},
|
||||
icon: Icons.menu,
|
||||
text: 'Remote connection'
|
||||
),
|
||||
SizedBox(height: SizeUtils.getByScreen(small: 16, big: 15)),
|
||||
AppSectionButton(
|
||||
onPressed: (){},
|
||||
icon: Icons.menu,
|
||||
text: 'Calendar'
|
||||
),
|
||||
SizedBox(height: SizeUtils.getByScreen(small: 16, big: 15)),
|
||||
AppSectionButton(
|
||||
onPressed: (){navigationContract.pushTo(AppRoutes.contacts);},
|
||||
icon: Icons.menu,
|
||||
text: 'Contacts'
|
||||
),
|
||||
SizedBox(height: SizeUtils.getByScreen(small: 16, big: 15)),
|
||||
AppSectionButton(
|
||||
onPressed: (){},
|
||||
icon: Icons.menu,
|
||||
text: 'Do not disturb'
|
||||
),
|
||||
SizedBox(height: SizeUtils.getByScreen(small: 16, big: 15)),
|
||||
AppSectionButton(
|
||||
onPressed: (){},
|
||||
icon: Icons.menu,
|
||||
text: 'Safety zone'
|
||||
),
|
||||
SizedBox(height: SizeUtils.getByScreen(small: 16, big: 15)),
|
||||
AppSectionButton(
|
||||
onPressed: (){},
|
||||
icon: Icons.menu,
|
||||
text: 'Video call'
|
||||
),
|
||||
SizedBox(height: SizeUtils.getByScreen(small: 16, big: 15)),
|
||||
AppSectionButton(
|
||||
onPressed: (){},
|
||||
icon: Icons.menu,
|
||||
text: 'Fall notice'
|
||||
),
|
||||
SizedBox(height: SizeUtils.getByScreen(small: 16, big: 15)),
|
||||
AppSectionButton(
|
||||
onPressed: (){},
|
||||
icon: Icons.menu,
|
||||
text: 'Medication reminder'
|
||||
),
|
||||
SizedBox(height: SizeUtils.getByScreen(small: 16, big: 15)),
|
||||
AppSectionButton(
|
||||
onPressed: (){},
|
||||
icon: Icons.menu,
|
||||
text: 'Activity meter'
|
||||
),
|
||||
SizedBox(height: SizeUtils.getByScreen(small: 16, big: 15)),
|
||||
AppSectionButton(
|
||||
onPressed: (){},
|
||||
icon: Icons.menu,
|
||||
text: 'Rewards'
|
||||
),
|
||||
SizedBox(height: SizeUtils.getByScreen(small: 16, big: 15)),
|
||||
AppSectionButton(
|
||||
onPressed: (){},
|
||||
icon: Icons.menu,
|
||||
text: 'Locate your SaveFamily'
|
||||
),
|
||||
],
|
||||
),
|
||||
))),
|
||||
],
|
||||
)
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class AppSectionButton extends ConsumerWidget {
|
||||
|
||||
final GestureTapCallback onPressed;
|
||||
final IconData icon;
|
||||
final String text;
|
||||
|
||||
const AppSectionButton({
|
||||
required this.onPressed,
|
||||
required this.icon,
|
||||
required this.text,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final theme = ref.read(themePortProvider);
|
||||
|
||||
return GestureDetector(
|
||||
onTap: onPressed,
|
||||
child: Container(
|
||||
padding: SizeUtils.getByScreen(
|
||||
small: EdgeInsets.symmetric(horizontal: 22, vertical: 14),
|
||||
big: EdgeInsets.symmetric(horizontal: 21, vertical: 12)
|
||||
),
|
||||
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: Color(0xFF588EA5),
|
||||
),
|
||||
padding: EdgeInsets.all(SizeUtils.getByScreen(small: 4, big: 12)),
|
||||
child: Icon(icon,
|
||||
size: SizeUtils.getByScreen(small: 40, big: 44),
|
||||
color: theme.getColorFor(ThemeCode.backgroundPrimary),
|
||||
weight: 30,
|
||||
),
|
||||
),
|
||||
SizedBox(width: SizeUtils.getByScreen(small: 16, big: 15)),
|
||||
Expanded(
|
||||
child: Text(context.translate(text),
|
||||
style: TextStyle(
|
||||
fontSize: SizeUtils.getByScreen(small: 18, big: 19),
|
||||
fontWeight: FontWeight.w500
|
||||
)
|
||||
)
|
||||
)
|
||||
],
|
||||
),
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -61,7 +61,7 @@ class HubScreen extends ConsumerWidget {
|
||||
text: I18n.sfPay),
|
||||
SizedBox(height: SizeUtils.getByScreen(small: 8, big: 7)),
|
||||
AppSectionButton(
|
||||
onPressed: (){},
|
||||
onPressed: (){navigationContract.pushTo(AppRoutes.dashboardFunctions);},
|
||||
icon: SFIcons.functions,
|
||||
text: I18n.functions),
|
||||
SizedBox(height: SizeUtils.getByScreen(small: 8, big: 7)),
|
||||
|
||||
@@ -20,4 +20,7 @@ class AppRoutes {
|
||||
static const legacyDashboard = '$legacy/dashboard';
|
||||
|
||||
static const dashboardHub = '$legacyDashboard/hub';
|
||||
static const dashboardFunctions = '$legacyDashboard/functions';
|
||||
|
||||
static const contacts = '$dashboardFunctions/contacts';
|
||||
}
|
||||
|
||||
@@ -170,4 +170,25 @@ class I18n {
|
||||
static const String home = 'home';
|
||||
static const String location = 'location';
|
||||
static const String chat = 'chat';
|
||||
static const String legacyPersonalData = 'personalData';
|
||||
static const String legacyAddNewSF = 'addNewSF';
|
||||
static const String legacyLinkedDevices = 'linkedDevices';
|
||||
static const String legacyAppUsers = 'appUsers';
|
||||
static const String legacyPrivacyPolicy = 'privacyPolicy';
|
||||
static const String legacyLogOut = 'logOut';
|
||||
static const String legacyLoginEmail = 'loginEmail';
|
||||
static const String legacyUserNameLabel = 'userNameLabel';
|
||||
static const String legacyUserPhoneLabel = 'userPhoneLabel';
|
||||
static const String legacyContactEmailLabel = 'contactEmailLabel';
|
||||
static const String passwordLabel = 'passwordLabel';
|
||||
static const String legacySubmit = 'submit';
|
||||
static const String legacySave = 'save';
|
||||
static const String legacyEditDeviceTitle = 'editDeviceTitle';
|
||||
static const String legacyName = 'name';
|
||||
static const String legacyDeleteDeviceDialog = 'deleteDeviceDialog';
|
||||
static const String legacyDeleteUserDialog = 'deleteUserDialog';
|
||||
static const String legacyCancel = 'cancel';
|
||||
static const String legacyDelete = 'delete';
|
||||
static const String legacyUserAccount = 'userAccount';
|
||||
static const String legacyUserRole = 'userRole';
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user