added account_settings, linked_devices and edit_linked_device screens and state
This commit is contained in:
3
.idea/modules.xml
generated
3
.idea/modules.xml
generated
@@ -2,7 +2,9 @@
|
||||
<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" />
|
||||
@@ -12,7 +14,6 @@
|
||||
<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" />
|
||||
|
||||
12
apps/mobile_app/assets/images/ui/profile.svg
Normal file
12
apps/mobile_app/assets/images/ui/profile.svg
Normal file
@@ -0,0 +1,12 @@
|
||||
<svg width="160" height="160" viewBox="0 0 160 160" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M108.055 98.4048L117.431 107.744C119.993 110.297 119.993 114.478 117.431 117.084C114.869 119.636 110.672 119.636 108.055 117.084L98.6799 107.744C96.1179 105.192 96.1179 101.011 98.6799 98.4048C101.242 95.7983 105.439 95.7983 108.055 98.4048Z" fill="#588EA5"/>
|
||||
<path d="M53.4371 79.7255C53.4371 83.3636 50.4936 86.2958 46.8414 86.2958H33.5956C29.9435 86.2958 27 83.3636 27 79.7255C27 76.0874 29.9435 73.1552 33.5956 73.1552H46.8414C50.4936 73.1552 53.4371 76.0874 53.4371 79.7255Z" fill="#588EA5"/>
|
||||
<path d="M51.8563 61.0462L42.4807 51.7609C39.9187 49.2087 39.9187 45.0276 42.4807 42.4212C45.0426 39.8691 49.2398 39.8691 51.8563 42.4212L61.2319 51.7609C63.7938 54.313 63.7938 58.4941 61.2319 61.1005C58.6155 63.6526 54.4182 63.6526 51.8563 61.0462Z" fill="#588EA5"/>
|
||||
<path d="M51.8563 117.03C49.2943 119.582 45.0971 119.582 42.4807 117.03C39.9187 114.478 39.9187 110.297 42.4807 107.69L51.8563 98.3505C54.4182 95.7984 58.6155 95.7984 61.2319 98.3505C63.7938 100.903 63.7938 105.084 61.2319 107.69L51.8563 117.03Z" fill="#588EA5"/>
|
||||
<path d="M79.9287 53.3356C76.2765 53.3356 73.333 50.4034 73.333 46.7653V33.5703C73.333 29.9322 76.2765 27 79.9287 27C83.5808 27 86.5243 29.9322 86.5243 33.5703V46.7653C86.5788 50.4034 83.5808 53.3356 79.9287 53.3356Z" fill="#588EA5"/>
|
||||
<path d="M79.9287 132.505C76.2765 132.505 73.333 129.573 73.333 125.935V112.74C73.333 109.102 76.2765 106.17 79.9287 106.17C83.5808 106.17 86.5243 109.102 86.5243 112.74V125.935C86.5788 129.573 83.5808 132.505 79.9287 132.505Z" fill="#588EA5"/>
|
||||
<path d="M108.055 61.0462C105.494 63.5983 101.296 63.5983 98.6799 61.0462C96.1179 58.4941 96.1179 54.313 98.6799 51.7066L108.055 42.367C110.617 39.8149 114.815 39.8149 117.431 42.367C119.993 44.9191 119.993 49.1002 117.431 51.7066L108.055 61.0462Z" fill="#588EA5"/>
|
||||
<path d="M126.316 86.3501H113.07C109.418 86.3501 106.475 83.4179 106.475 79.7798C106.475 76.1417 109.418 73.2095 113.07 73.2095H126.316C129.968 73.2095 132.912 76.1417 132.912 79.7798C132.912 83.3636 129.968 86.3501 126.316 86.3501Z" fill="#588EA5"/>
|
||||
<path d="M78.1299 61.6435C78.5659 61.2634 79.0565 60.8833 79.6561 60.829C81.1279 60.7204 81.8365 62.5124 82.109 63.9785C82.6541 66.9107 83.1447 69.8972 83.6898 72.8294C83.7988 73.481 83.9624 74.1869 84.5075 74.567C84.998 74.8928 85.7067 74.8385 86.3063 74.7299C89.8494 74.3498 93.556 75.11 96.6085 76.9562C97.5897 77.5535 98.5164 78.3137 98.6799 79.454C98.8434 81.083 97.1536 82.2233 95.5729 82.7663C92.7929 83.7437 89.7404 83.9609 86.8514 83.4179C87.8325 85.3184 88.5957 87.3818 89.1953 89.4452C89.9039 92.0517 89.7404 95.5812 87.2329 96.5586C85.3251 97.2645 83.2537 95.9613 82 94.3866C80.7463 92.8119 79.8742 90.9114 78.2934 89.6082C76.113 92.2146 72.6789 93.4635 69.4083 94.3866C67.0644 95.0382 64.0664 95.2554 62.7582 93.192C62.1041 92.106 63.4668 88.7394 65.2656 87.3275C67.2825 85.7528 68.3727 84.2324 70.444 83.1464C65.9197 81.4631 63.6303 80.8115 60.7413 76.9562C59.9237 75.8702 59.3786 74.1326 60.5233 73.4267C60.9049 73.2095 61.3409 73.2095 61.7225 73.2095C65.6472 73.1009 69.9534 74.5127 72.5699 71.5262C74.9683 68.7026 74.9683 64.4672 78.1299 61.6435Z" fill="#588EA5"/>
|
||||
<circle cx="80" cy="80" r="78" stroke="#588EA5" stroke-width="4"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.3 KiB |
@@ -1,3 +1,4 @@
|
||||
import 'package:account/account.dart';
|
||||
import 'package:auth/auth.dart';
|
||||
import 'package:legacy_dashboard_shell/legacy_dashboard_builder.dart';
|
||||
import 'package:dashboard_shell/dashboard_builder.dart';
|
||||
@@ -42,6 +43,11 @@ void configureAppRouter() {
|
||||
),
|
||||
],
|
||||
),
|
||||
GoRoute(
|
||||
path: AppRoutes.accountSettings,
|
||||
name: 'account_settings',
|
||||
pageBuilder: AccountSettingsBuilder().buildPage,
|
||||
),
|
||||
|
||||
GoRoute(
|
||||
path: AppRoutes.login,
|
||||
|
||||
@@ -53,6 +53,8 @@ dependencies:
|
||||
path: ../../modules/legacy/modules/legacy_dashboard_shell
|
||||
splash:
|
||||
path: ../../modules/splash
|
||||
account:
|
||||
path: ../../modules/legacy/modules/account
|
||||
#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/account/.dart_tool" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/modules/account/.pub" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/modules/account/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:account/src/features/linked_devices/domain/entities/device_entity.dart';
|
||||
|
||||
abstract class AccountRemoteDatasource {
|
||||
Future<List<DeviceEntity>> getLinkedDevices({required String userId});
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:account/src/core/data/datasource/account_remote_datasource.dart';
|
||||
import 'package:account/src/core/data/models/get_linked_devices_response_model.dart';
|
||||
import 'package:account/src/features/linked_devices/domain/entities/device_entity.dart';
|
||||
import 'package:dio/dio.dart';
|
||||
// import 'package:flutter/material.dart';
|
||||
// import 'package:sf_infrastructure/sf_infrastructure.dart';
|
||||
|
||||
class AccountRemoteDatasourceImpl implements AccountRemoteDatasource {
|
||||
AccountRemoteDatasourceImpl(/*this._repository*/);
|
||||
|
||||
// final QuestiaRepository _repository;
|
||||
|
||||
@override
|
||||
Future<List<DeviceEntity>> getLinkedDevices({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',
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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,38 @@
|
||||
import 'package:account/src/features/linked_devices/domain/entities/device_entity.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
part 'get_linked_devices_response_model.freezed.dart';
|
||||
part 'get_linked_devices_response_model.g.dart';
|
||||
|
||||
@freezed
|
||||
abstract class GetLinkedDevicesResponseModel with _$GetLinkedDevicesResponseModel {
|
||||
const factory GetLinkedDevicesResponseModel({
|
||||
required List<GetLinkedDevicesItemResponseModel> items,
|
||||
}) = _GetLinkedDevicesResponseModel;
|
||||
|
||||
factory GetLinkedDevicesResponseModel.fromJson(Map<String, dynamic> json) =>
|
||||
_$GetLinkedDevicesResponseModelFromJson(json);
|
||||
}
|
||||
|
||||
@freezed
|
||||
abstract class GetLinkedDevicesItemResponseModel with _$GetLinkedDevicesItemResponseModel {
|
||||
const factory GetLinkedDevicesItemResponseModel({
|
||||
required String identificator,
|
||||
required String name,
|
||||
required String number,
|
||||
}) =
|
||||
_GetLinkedDevicesItemResponseModel;
|
||||
|
||||
factory GetLinkedDevicesItemResponseModel.fromJson(Map<String, dynamic> json) =>
|
||||
_$GetLinkedDevicesItemResponseModelFromJson(json);
|
||||
}
|
||||
|
||||
extension GetDevicesResponseModelMapper on GetLinkedDevicesResponseModel {
|
||||
List<DeviceEntity> toEntity() {
|
||||
return items.map((GetLinkedDevicesItemResponseModel item) => DeviceEntity(
|
||||
identificator: item.identificator,
|
||||
name: item.name,
|
||||
number: item.number
|
||||
)).toList();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,552 @@
|
||||
// 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 'get_linked_devices_response_model.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// FreezedGenerator
|
||||
// **************************************************************************
|
||||
|
||||
// dart format off
|
||||
T _$identity<T>(T value) => value;
|
||||
|
||||
/// @nodoc
|
||||
mixin _$GetLinkedDevicesResponseModel {
|
||||
|
||||
List<GetLinkedDevicesItemResponseModel> get items;
|
||||
/// Create a copy of GetLinkedDevicesResponseModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
$GetLinkedDevicesResponseModelCopyWith<GetLinkedDevicesResponseModel> get copyWith => _$GetLinkedDevicesResponseModelCopyWithImpl<GetLinkedDevicesResponseModel>(this as GetLinkedDevicesResponseModel, _$identity);
|
||||
|
||||
/// Serializes this GetLinkedDevicesResponseModel to a JSON map.
|
||||
Map<String, dynamic> toJson();
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is GetLinkedDevicesResponseModel&&const DeepCollectionEquality().equals(other.items, items));
|
||||
}
|
||||
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,const DeepCollectionEquality().hash(items));
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'GetLinkedDevicesResponseModel(items: $items)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class $GetLinkedDevicesResponseModelCopyWith<$Res> {
|
||||
factory $GetLinkedDevicesResponseModelCopyWith(GetLinkedDevicesResponseModel value, $Res Function(GetLinkedDevicesResponseModel) _then) = _$GetLinkedDevicesResponseModelCopyWithImpl;
|
||||
@useResult
|
||||
$Res call({
|
||||
List<GetLinkedDevicesItemResponseModel> items
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class _$GetLinkedDevicesResponseModelCopyWithImpl<$Res>
|
||||
implements $GetLinkedDevicesResponseModelCopyWith<$Res> {
|
||||
_$GetLinkedDevicesResponseModelCopyWithImpl(this._self, this._then);
|
||||
|
||||
final GetLinkedDevicesResponseModel _self;
|
||||
final $Res Function(GetLinkedDevicesResponseModel) _then;
|
||||
|
||||
/// Create a copy of GetLinkedDevicesResponseModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline') @override $Res call({Object? items = null,}) {
|
||||
return _then(_self.copyWith(
|
||||
items: null == items ? _self.items : items // ignore: cast_nullable_to_non_nullable
|
||||
as List<GetLinkedDevicesItemResponseModel>,
|
||||
));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// Adds pattern-matching-related methods to [GetLinkedDevicesResponseModel].
|
||||
extension GetLinkedDevicesResponseModelPatterns on GetLinkedDevicesResponseModel {
|
||||
/// 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( _GetLinkedDevicesResponseModel value)? $default,{required TResult orElse(),}){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _GetLinkedDevicesResponseModel() 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( _GetLinkedDevicesResponseModel value) $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _GetLinkedDevicesResponseModel():
|
||||
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( _GetLinkedDevicesResponseModel value)? $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _GetLinkedDevicesResponseModel() 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( List<GetLinkedDevicesItemResponseModel> items)? $default,{required TResult orElse(),}) {final _that = this;
|
||||
switch (_that) {
|
||||
case _GetLinkedDevicesResponseModel() when $default != null:
|
||||
return $default(_that.items);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( List<GetLinkedDevicesItemResponseModel> items) $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _GetLinkedDevicesResponseModel():
|
||||
return $default(_that.items);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( List<GetLinkedDevicesItemResponseModel> items)? $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _GetLinkedDevicesResponseModel() when $default != null:
|
||||
return $default(_that.items);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
@JsonSerializable()
|
||||
|
||||
class _GetLinkedDevicesResponseModel implements GetLinkedDevicesResponseModel {
|
||||
const _GetLinkedDevicesResponseModel({required final List<GetLinkedDevicesItemResponseModel> items}): _items = items;
|
||||
factory _GetLinkedDevicesResponseModel.fromJson(Map<String, dynamic> json) => _$GetLinkedDevicesResponseModelFromJson(json);
|
||||
|
||||
final List<GetLinkedDevicesItemResponseModel> _items;
|
||||
@override List<GetLinkedDevicesItemResponseModel> get items {
|
||||
if (_items is EqualUnmodifiableListView) return _items;
|
||||
// ignore: implicit_dynamic_type
|
||||
return EqualUnmodifiableListView(_items);
|
||||
}
|
||||
|
||||
|
||||
/// Create a copy of GetLinkedDevicesResponseModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
_$GetLinkedDevicesResponseModelCopyWith<_GetLinkedDevicesResponseModel> get copyWith => __$GetLinkedDevicesResponseModelCopyWithImpl<_GetLinkedDevicesResponseModel>(this, _$identity);
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
return _$GetLinkedDevicesResponseModelToJson(this, );
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _GetLinkedDevicesResponseModel&&const DeepCollectionEquality().equals(other._items, _items));
|
||||
}
|
||||
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,const DeepCollectionEquality().hash(_items));
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'GetLinkedDevicesResponseModel(items: $items)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class _$GetLinkedDevicesResponseModelCopyWith<$Res> implements $GetLinkedDevicesResponseModelCopyWith<$Res> {
|
||||
factory _$GetLinkedDevicesResponseModelCopyWith(_GetLinkedDevicesResponseModel value, $Res Function(_GetLinkedDevicesResponseModel) _then) = __$GetLinkedDevicesResponseModelCopyWithImpl;
|
||||
@override @useResult
|
||||
$Res call({
|
||||
List<GetLinkedDevicesItemResponseModel> items
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class __$GetLinkedDevicesResponseModelCopyWithImpl<$Res>
|
||||
implements _$GetLinkedDevicesResponseModelCopyWith<$Res> {
|
||||
__$GetLinkedDevicesResponseModelCopyWithImpl(this._self, this._then);
|
||||
|
||||
final _GetLinkedDevicesResponseModel _self;
|
||||
final $Res Function(_GetLinkedDevicesResponseModel) _then;
|
||||
|
||||
/// Create a copy of GetLinkedDevicesResponseModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @pragma('vm:prefer-inline') $Res call({Object? items = null,}) {
|
||||
return _then(_GetLinkedDevicesResponseModel(
|
||||
items: null == items ? _self._items : items // ignore: cast_nullable_to_non_nullable
|
||||
as List<GetLinkedDevicesItemResponseModel>,
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// @nodoc
|
||||
mixin _$GetLinkedDevicesItemResponseModel {
|
||||
|
||||
String get identificator; String get name; String get number;
|
||||
/// Create a copy of GetLinkedDevicesItemResponseModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
$GetLinkedDevicesItemResponseModelCopyWith<GetLinkedDevicesItemResponseModel> get copyWith => _$GetLinkedDevicesItemResponseModelCopyWithImpl<GetLinkedDevicesItemResponseModel>(this as GetLinkedDevicesItemResponseModel, _$identity);
|
||||
|
||||
/// Serializes this GetLinkedDevicesItemResponseModel to a JSON map.
|
||||
Map<String, dynamic> toJson();
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is GetLinkedDevicesItemResponseModel&&(identical(other.identificator, identificator) || other.identificator == identificator)&&(identical(other.name, name) || other.name == name)&&(identical(other.number, number) || other.number == number));
|
||||
}
|
||||
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,identificator,name,number);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'GetLinkedDevicesItemResponseModel(identificator: $identificator, name: $name, number: $number)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class $GetLinkedDevicesItemResponseModelCopyWith<$Res> {
|
||||
factory $GetLinkedDevicesItemResponseModelCopyWith(GetLinkedDevicesItemResponseModel value, $Res Function(GetLinkedDevicesItemResponseModel) _then) = _$GetLinkedDevicesItemResponseModelCopyWithImpl;
|
||||
@useResult
|
||||
$Res call({
|
||||
String identificator, String name, String number
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class _$GetLinkedDevicesItemResponseModelCopyWithImpl<$Res>
|
||||
implements $GetLinkedDevicesItemResponseModelCopyWith<$Res> {
|
||||
_$GetLinkedDevicesItemResponseModelCopyWithImpl(this._self, this._then);
|
||||
|
||||
final GetLinkedDevicesItemResponseModel _self;
|
||||
final $Res Function(GetLinkedDevicesItemResponseModel) _then;
|
||||
|
||||
/// Create a copy of GetLinkedDevicesItemResponseModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline') @override $Res call({Object? identificator = null,Object? name = null,Object? number = null,}) {
|
||||
return _then(_self.copyWith(
|
||||
identificator: null == identificator ? _self.identificator : identificator // ignore: cast_nullable_to_non_nullable
|
||||
as String,name: null == name ? _self.name : name // ignore: cast_nullable_to_non_nullable
|
||||
as String,number: null == number ? _self.number : number // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// Adds pattern-matching-related methods to [GetLinkedDevicesItemResponseModel].
|
||||
extension GetLinkedDevicesItemResponseModelPatterns on GetLinkedDevicesItemResponseModel {
|
||||
/// 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( _GetLinkedDevicesItemResponseModel value)? $default,{required TResult orElse(),}){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _GetLinkedDevicesItemResponseModel() 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( _GetLinkedDevicesItemResponseModel value) $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _GetLinkedDevicesItemResponseModel():
|
||||
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( _GetLinkedDevicesItemResponseModel value)? $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _GetLinkedDevicesItemResponseModel() 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 identificator, String name, String number)? $default,{required TResult orElse(),}) {final _that = this;
|
||||
switch (_that) {
|
||||
case _GetLinkedDevicesItemResponseModel() when $default != null:
|
||||
return $default(_that.identificator,_that.name,_that.number);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 identificator, String name, String number) $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _GetLinkedDevicesItemResponseModel():
|
||||
return $default(_that.identificator,_that.name,_that.number);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 identificator, String name, String number)? $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _GetLinkedDevicesItemResponseModel() when $default != null:
|
||||
return $default(_that.identificator,_that.name,_that.number);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
@JsonSerializable()
|
||||
|
||||
class _GetLinkedDevicesItemResponseModel implements GetLinkedDevicesItemResponseModel {
|
||||
const _GetLinkedDevicesItemResponseModel({required this.identificator, required this.name, required this.number});
|
||||
factory _GetLinkedDevicesItemResponseModel.fromJson(Map<String, dynamic> json) => _$GetLinkedDevicesItemResponseModelFromJson(json);
|
||||
|
||||
@override final String identificator;
|
||||
@override final String name;
|
||||
@override final String number;
|
||||
|
||||
/// Create a copy of GetLinkedDevicesItemResponseModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
_$GetLinkedDevicesItemResponseModelCopyWith<_GetLinkedDevicesItemResponseModel> get copyWith => __$GetLinkedDevicesItemResponseModelCopyWithImpl<_GetLinkedDevicesItemResponseModel>(this, _$identity);
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
return _$GetLinkedDevicesItemResponseModelToJson(this, );
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _GetLinkedDevicesItemResponseModel&&(identical(other.identificator, identificator) || other.identificator == identificator)&&(identical(other.name, name) || other.name == name)&&(identical(other.number, number) || other.number == number));
|
||||
}
|
||||
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,identificator,name,number);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'GetLinkedDevicesItemResponseModel(identificator: $identificator, name: $name, number: $number)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class _$GetLinkedDevicesItemResponseModelCopyWith<$Res> implements $GetLinkedDevicesItemResponseModelCopyWith<$Res> {
|
||||
factory _$GetLinkedDevicesItemResponseModelCopyWith(_GetLinkedDevicesItemResponseModel value, $Res Function(_GetLinkedDevicesItemResponseModel) _then) = __$GetLinkedDevicesItemResponseModelCopyWithImpl;
|
||||
@override @useResult
|
||||
$Res call({
|
||||
String identificator, String name, String number
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class __$GetLinkedDevicesItemResponseModelCopyWithImpl<$Res>
|
||||
implements _$GetLinkedDevicesItemResponseModelCopyWith<$Res> {
|
||||
__$GetLinkedDevicesItemResponseModelCopyWithImpl(this._self, this._then);
|
||||
|
||||
final _GetLinkedDevicesItemResponseModel _self;
|
||||
final $Res Function(_GetLinkedDevicesItemResponseModel) _then;
|
||||
|
||||
/// Create a copy of GetLinkedDevicesItemResponseModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @pragma('vm:prefer-inline') $Res call({Object? identificator = null,Object? name = null,Object? number = null,}) {
|
||||
return _then(_GetLinkedDevicesItemResponseModel(
|
||||
identificator: null == identificator ? _self.identificator : identificator // ignore: cast_nullable_to_non_nullable
|
||||
as String,name: null == name ? _self.name : name // ignore: cast_nullable_to_non_nullable
|
||||
as String,number: null == number ? _self.number : number // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// dart format on
|
||||
@@ -0,0 +1,39 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'get_linked_devices_response_model.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
_GetLinkedDevicesResponseModel _$GetLinkedDevicesResponseModelFromJson(
|
||||
Map<String, dynamic> json,
|
||||
) => _GetLinkedDevicesResponseModel(
|
||||
items: (json['items'] as List<dynamic>)
|
||||
.map(
|
||||
(e) => GetLinkedDevicesItemResponseModel.fromJson(
|
||||
e as Map<String, dynamic>,
|
||||
),
|
||||
)
|
||||
.toList(),
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$GetLinkedDevicesResponseModelToJson(
|
||||
_GetLinkedDevicesResponseModel instance,
|
||||
) => <String, dynamic>{'items': instance.items};
|
||||
|
||||
_GetLinkedDevicesItemResponseModel _$GetLinkedDevicesItemResponseModelFromJson(
|
||||
Map<String, dynamic> json,
|
||||
) => _GetLinkedDevicesItemResponseModel(
|
||||
identificator: json['identificator'] as String,
|
||||
name: json['name'] as String,
|
||||
number: json['number'] as String,
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$GetLinkedDevicesItemResponseModelToJson(
|
||||
_GetLinkedDevicesItemResponseModel instance,
|
||||
) => <String, dynamic>{
|
||||
'identificator': instance.identificator,
|
||||
'name': instance.name,
|
||||
'number': instance.number,
|
||||
};
|
||||
@@ -0,0 +1,14 @@
|
||||
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/features/linked_devices/domain/entities/device_entity.dart';
|
||||
|
||||
class AccountRepositoryImpl implements AccountRepository {
|
||||
const AccountRepositoryImpl(this._remote);
|
||||
|
||||
final AccountRemoteDatasource _remote;
|
||||
|
||||
@override
|
||||
Future<List<DeviceEntity>> getLinkedDevices({required String userId}) {
|
||||
return _remote.getLinkedDevices(userId: userId);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
import 'package:account/src/features/linked_devices/domain/entities/device_entity.dart';
|
||||
|
||||
abstract class AccountRepository {
|
||||
Future<List<DeviceEntity>> getLinkedDevices({required String userId});
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
import 'package:account/src/core/data/datasource/account_remote_datasource.dart';
|
||||
import 'package:account/src/core/data/datasource/account_remote_datasource_impl.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
// import 'package:sf_infrastructure/sf_infrastructure.dart';
|
||||
|
||||
final accountRemoteDatasourceProvider = Provider<AccountRemoteDatasource>((ref) {
|
||||
// final questiaRepository = getIt<QuestiaRepository>();
|
||||
return AccountRemoteDatasourceImpl(/*questiaRepository*/);
|
||||
});
|
||||
@@ -0,0 +1,9 @@
|
||||
import 'package:account/src/core/data/repositories/account_repository_impl.dart';
|
||||
import 'package:account/src/core/domain/repositories/account_repository.dart';
|
||||
import 'package:account/src/core/providers/account_remote_datasource_provider.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
|
||||
final accountRepositoryProvider = Provider<AccountRepository>((ref) {
|
||||
final remote = ref.read(accountRemoteDatasourceProvider);
|
||||
return AccountRepositoryImpl(remote);
|
||||
});
|
||||
@@ -0,0 +1,18 @@
|
||||
import 'package:account/src/features/account_settings/presentation/account_settings_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 AccountSettingsBuilder {
|
||||
const AccountSettingsBuilder();
|
||||
|
||||
Page<void> buildPage(BuildContext context, GoRouterState state) {
|
||||
final NavigationContract navigationContract = GetIt.I<NavigationContract>();
|
||||
|
||||
return MaterialPage<void>(
|
||||
key: state.pageKey,
|
||||
child: AccountSettingsScreen(navigationContract: navigationContract),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
import 'package:account/src/features/linked_devices/presentation/linked_devices_screen.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 AccountSettingsScreen extends ConsumerWidget {
|
||||
final NavigationContract navigationContract;
|
||||
|
||||
const AccountSettingsScreen({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(I18n.accountSettings),
|
||||
style: TextStyle(
|
||||
fontSize: SizeUtils.getByScreen(small: 28, big: 27)
|
||||
),
|
||||
)
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(height: SizeUtils.getByScreen(small: 30, big: 28)),
|
||||
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: SFIcons.account,
|
||||
text: 'Personal Data'
|
||||
),
|
||||
SizedBox(height: SizeUtils.getByScreen(small: 16, big: 15)),
|
||||
AppSectionButton(
|
||||
onPressed: (){},
|
||||
icon: Icons.add_circle_outline,
|
||||
text: 'Add a new SaveFamily'
|
||||
),
|
||||
SizedBox(height: SizeUtils.getByScreen(small: 16, big: 15)),
|
||||
AppSectionButton(
|
||||
onPressed: (){Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(builder: (_) => LinkedDevicesScreen(navigationContract: navigationContract)),
|
||||
);},
|
||||
icon: Icons.account_circle_outlined,
|
||||
text: 'Linked Devices'
|
||||
),
|
||||
SizedBox(height: SizeUtils.getByScreen(small: 16, big: 15)),
|
||||
AppSectionButton(
|
||||
onPressed: (){},
|
||||
icon: Icons.groups_outlined,
|
||||
text: 'App Users'
|
||||
),
|
||||
SizedBox(height: SizeUtils.getByScreen(small: 16, big: 15)),
|
||||
AppSectionButton(
|
||||
onPressed: (){},
|
||||
icon: SFIcons.privacy,
|
||||
text: 'User privacy policy'
|
||||
),
|
||||
SizedBox(height: SizeUtils.getByScreen(small: 48, big: 47)),
|
||||
PrimaryButton(text: 'Log out', color: Color(0xFF588EA5))
|
||||
],
|
||||
),
|
||||
)),
|
||||
],
|
||||
)
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
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: 20),
|
||||
big: EdgeInsets.symmetric(horizontal: 21, vertical: 18)
|
||||
),
|
||||
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(icon,
|
||||
size: SizeUtils.getByScreen(small: 40, big: 44),
|
||||
color: Color(0xFF588EA5),
|
||||
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
|
||||
)
|
||||
)
|
||||
)
|
||||
],
|
||||
),
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
part 'device_entity.freezed.dart';
|
||||
|
||||
@freezed
|
||||
abstract class DeviceEntity with _$DeviceEntity {
|
||||
const factory DeviceEntity({
|
||||
required String identificator,
|
||||
required String name,
|
||||
required String number,
|
||||
}) = _DeviceEntity;
|
||||
}
|
||||
@@ -0,0 +1,277 @@
|
||||
// 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 'device_entity.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// FreezedGenerator
|
||||
// **************************************************************************
|
||||
|
||||
// dart format off
|
||||
T _$identity<T>(T value) => value;
|
||||
/// @nodoc
|
||||
mixin _$DeviceEntity {
|
||||
|
||||
String get identificator; String get name; String get number;
|
||||
/// Create a copy of DeviceEntity
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
$DeviceEntityCopyWith<DeviceEntity> get copyWith => _$DeviceEntityCopyWithImpl<DeviceEntity>(this as DeviceEntity, _$identity);
|
||||
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is DeviceEntity&&(identical(other.identificator, identificator) || other.identificator == identificator)&&(identical(other.name, name) || other.name == name)&&(identical(other.number, number) || other.number == number));
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,identificator,name,number);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'DeviceEntity(identificator: $identificator, name: $name, number: $number)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class $DeviceEntityCopyWith<$Res> {
|
||||
factory $DeviceEntityCopyWith(DeviceEntity value, $Res Function(DeviceEntity) _then) = _$DeviceEntityCopyWithImpl;
|
||||
@useResult
|
||||
$Res call({
|
||||
String identificator, String name, String number
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class _$DeviceEntityCopyWithImpl<$Res>
|
||||
implements $DeviceEntityCopyWith<$Res> {
|
||||
_$DeviceEntityCopyWithImpl(this._self, this._then);
|
||||
|
||||
final DeviceEntity _self;
|
||||
final $Res Function(DeviceEntity) _then;
|
||||
|
||||
/// Create a copy of DeviceEntity
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline') @override $Res call({Object? identificator = null,Object? name = null,Object? number = null,}) {
|
||||
return _then(_self.copyWith(
|
||||
identificator: null == identificator ? _self.identificator : identificator // ignore: cast_nullable_to_non_nullable
|
||||
as String,name: null == name ? _self.name : name // ignore: cast_nullable_to_non_nullable
|
||||
as String,number: null == number ? _self.number : number // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// Adds pattern-matching-related methods to [DeviceEntity].
|
||||
extension DeviceEntityPatterns on DeviceEntity {
|
||||
/// 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( _DeviceEntity value)? $default,{required TResult orElse(),}){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _DeviceEntity() 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( _DeviceEntity value) $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _DeviceEntity():
|
||||
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( _DeviceEntity value)? $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _DeviceEntity() 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 identificator, String name, String number)? $default,{required TResult orElse(),}) {final _that = this;
|
||||
switch (_that) {
|
||||
case _DeviceEntity() when $default != null:
|
||||
return $default(_that.identificator,_that.name,_that.number);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 identificator, String name, String number) $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _DeviceEntity():
|
||||
return $default(_that.identificator,_that.name,_that.number);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 identificator, String name, String number)? $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _DeviceEntity() when $default != null:
|
||||
return $default(_that.identificator,_that.name,_that.number);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
|
||||
|
||||
class _DeviceEntity implements DeviceEntity {
|
||||
const _DeviceEntity({required this.identificator, required this.name, required this.number});
|
||||
|
||||
|
||||
@override final String identificator;
|
||||
@override final String name;
|
||||
@override final String number;
|
||||
|
||||
/// Create a copy of DeviceEntity
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
_$DeviceEntityCopyWith<_DeviceEntity> get copyWith => __$DeviceEntityCopyWithImpl<_DeviceEntity>(this, _$identity);
|
||||
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _DeviceEntity&&(identical(other.identificator, identificator) || other.identificator == identificator)&&(identical(other.name, name) || other.name == name)&&(identical(other.number, number) || other.number == number));
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,identificator,name,number);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'DeviceEntity(identificator: $identificator, name: $name, number: $number)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class _$DeviceEntityCopyWith<$Res> implements $DeviceEntityCopyWith<$Res> {
|
||||
factory _$DeviceEntityCopyWith(_DeviceEntity value, $Res Function(_DeviceEntity) _then) = __$DeviceEntityCopyWithImpl;
|
||||
@override @useResult
|
||||
$Res call({
|
||||
String identificator, String name, String number
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class __$DeviceEntityCopyWithImpl<$Res>
|
||||
implements _$DeviceEntityCopyWith<$Res> {
|
||||
__$DeviceEntityCopyWithImpl(this._self, this._then);
|
||||
|
||||
final _DeviceEntity _self;
|
||||
final $Res Function(_DeviceEntity) _then;
|
||||
|
||||
/// Create a copy of DeviceEntity
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @pragma('vm:prefer-inline') $Res call({Object? identificator = null,Object? name = null,Object? number = null,}) {
|
||||
return _then(_DeviceEntity(
|
||||
identificator: null == identificator ? _self.identificator : identificator // ignore: cast_nullable_to_non_nullable
|
||||
as String,name: null == name ? _self.name : name // ignore: cast_nullable_to_non_nullable
|
||||
as String,number: null == number ? _self.number : number // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// dart format on
|
||||
@@ -0,0 +1,5 @@
|
||||
import 'package:account/src/features/linked_devices/domain/entities/device_entity.dart';
|
||||
|
||||
abstract class GetLinkedDevicesUseCase {
|
||||
Future<List<DeviceEntity>> getLinkedDevices({required String userId});
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
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/get_linked_devices_use_case.dart';
|
||||
|
||||
class GetLinkedDevicesUseCaseImpl implements GetLinkedDevicesUseCase {
|
||||
GetLinkedDevicesUseCaseImpl(this._repository);
|
||||
|
||||
final AccountRepository _repository;
|
||||
|
||||
@override
|
||||
Future<List<DeviceEntity>> getLinkedDevices({required String userId}) {
|
||||
return _repository.getLinkedDevices(userId: userId);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
import 'package:account/src/features/linked_devices/state/linked_devices_view_model.dart';
|
||||
import 'package:design_system/design_system.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
// import 'package:navigation/navigation.dart';
|
||||
import 'package:sf_localizations/sf_localizations.dart';
|
||||
import 'package:utils/utils.dart';
|
||||
|
||||
class EditLinkedDeviceScreen extends ConsumerWidget {
|
||||
//final NavigationContract navigationContract;
|
||||
final String deviceName;
|
||||
|
||||
const EditLinkedDeviceScreen({super.key, required this.deviceName /*required this.navigationContract*/});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final vm = ref.read(linkedDevicesViewModelProvider.notifier);
|
||||
// final state = ref.watch(linkedDevicesViewModelProvider);
|
||||
|
||||
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('Edit device'),
|
||||
style: TextStyle(
|
||||
fontSize: SizeUtils.getByScreen(small: 28, big: 27)
|
||||
),
|
||||
)
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(height: SizeUtils.getByScreen(small: 20, big: 18)),
|
||||
Container(
|
||||
padding: SizeUtils.getByScreen(
|
||||
small: EdgeInsets.symmetric(horizontal: 22, vertical: 10),
|
||||
big: EdgeInsets.symmetric(horizontal: 21, vertical: 8)
|
||||
),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Stack(
|
||||
children: [
|
||||
Center(child: SvgPicture.asset('assets/images/ui/profile.svg')),
|
||||
Center(child: SizedBox(
|
||||
width: 160,
|
||||
height: 160,
|
||||
child: Align(alignment: Alignment.bottomRight,
|
||||
child: IconButton(
|
||||
onPressed: (){},
|
||||
icon: Container(
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
color: Color(0xFFCAC9C9)
|
||||
),
|
||||
padding: EdgeInsets.all(8),
|
||||
child: Icon(
|
||||
Icons.edit_outlined,
|
||||
color: Colors.white,
|
||||
size: SizeUtils.getByScreen(small: 32, big: 30),
|
||||
),
|
||||
),
|
||||
)
|
||||
)
|
||||
))
|
||||
],
|
||||
),
|
||||
CustomTextField(
|
||||
controller: vm.deviceNameController,
|
||||
hint: deviceName,
|
||||
)
|
||||
],
|
||||
),
|
||||
PrimaryButton(text: 'Save', color: Color(0xFF588EA5))
|
||||
],
|
||||
)
|
||||
),
|
||||
],
|
||||
)
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,226 @@
|
||||
import 'package:account/src/features/linked_devices/presentation/edit_linked_device_screen.dart';
|
||||
import 'package:account/src/features/linked_devices/state/linked_devices_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 LinkedDevicesScreen extends ConsumerWidget {
|
||||
final NavigationContract navigationContract;
|
||||
|
||||
const LinkedDevicesScreen({super.key, required this.navigationContract});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final vm = ref.read(linkedDevicesViewModelProvider.notifier);
|
||||
final state = ref.watch(linkedDevicesViewModelProvider);
|
||||
|
||||
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)),
|
||||
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('Linked Devices'),
|
||||
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)=>LinkedDeviceCard(
|
||||
name: state.linkedDevices[index].name,
|
||||
body: state.linkedDevices[index].number,
|
||||
isEditing: state.isEditing,
|
||||
),
|
||||
separatorBuilder: (BuildContext context, int index)=>SizedBox(
|
||||
height: SizeUtils.getByScreen(small: 18, big: 17)
|
||||
),
|
||||
itemCount: state.linkedDevices.length
|
||||
),
|
||||
)),
|
||||
],
|
||||
)
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class LinkedDeviceCard extends ConsumerWidget {
|
||||
|
||||
final String name;
|
||||
final String body;
|
||||
final bool isEditing;
|
||||
|
||||
const LinkedDeviceCard({
|
||||
required this.name,
|
||||
required this.body,
|
||||
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.watch,
|
||||
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(name,
|
||||
style: TextStyle(
|
||||
fontSize: SizeUtils.getByScreen(small: 18, big: 19),
|
||||
fontWeight: FontWeight.w500
|
||||
)
|
||||
),
|
||||
Text(body,
|
||||
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 device 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,
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(width: SizeUtils.getByScreen(small: 16, big: 14)),
|
||||
DecoratedBox(
|
||||
decoration: BoxDecoration(
|
||||
color: Color(0xFF588EA5),
|
||||
borderRadius: BorderRadius.all(Radius.circular(12)),
|
||||
),
|
||||
child:
|
||||
IconButton(
|
||||
onPressed: (){Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(builder: (_) => EditLinkedDeviceScreen(
|
||||
deviceName: name,
|
||||
/*navigationContract: navigationContract*/
|
||||
)),
|
||||
);},
|
||||
icon: Icon(
|
||||
Icons.edit_outlined,
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
),
|
||||
]
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
import 'package:account/src/core/providers/account_repository_provider.dart';
|
||||
import 'package:account/src/features/linked_devices/domain/get_linked_devices_use_case.dart';
|
||||
import 'package:account/src/features/linked_devices/domain/get_linked_devices_use_case_impl.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
|
||||
final getLinkedDevicesUseCaseProvider = Provider.autoDispose<GetLinkedDevicesUseCase>((ref) {
|
||||
final authRepository = ref.read(accountRepositoryProvider);
|
||||
return GetLinkedDevicesUseCaseImpl(authRepository);
|
||||
});
|
||||
@@ -0,0 +1,56 @@
|
||||
import 'package:account/src/features/linked_devices/domain/entities/device_entity.dart';
|
||||
import 'package:account/src/features/linked_devices/domain/get_linked_devices_use_case.dart';
|
||||
import 'package:account/src/features/linked_devices/presentation/providers/get_linked_devices_use_case_provider.dart';
|
||||
import 'package:account/src/features/linked_devices/state/linked_devices_view_state.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
// import 'package:sf_localizations/sf_localizations.dart';
|
||||
|
||||
final linkedDevicesViewModelProvider =
|
||||
NotifierProvider.autoDispose<LinkedDevicesViewModel, LinkedDevicesViewState>(
|
||||
LinkedDevicesViewModel.new,
|
||||
);
|
||||
|
||||
class LinkedDevicesViewModel extends Notifier<LinkedDevicesViewState> {
|
||||
late final GetLinkedDevicesUseCase _getLinkedDevicesUseCase;
|
||||
|
||||
late final TextEditingController deviceNameController;
|
||||
|
||||
@override
|
||||
LinkedDevicesViewState build() {
|
||||
_getLinkedDevicesUseCase = ref.read(getLinkedDevicesUseCaseProvider);
|
||||
|
||||
deviceNameController = TextEditingController();
|
||||
deviceNameController.addListener(_onDeviceNameChanged);
|
||||
|
||||
_getLinkedDevicesUseCase.getLinkedDevices(userId: 'test')
|
||||
.then(setLinkedDevices);
|
||||
|
||||
ref.onDispose(disposeControllers);
|
||||
|
||||
return const LinkedDevicesViewState();
|
||||
}
|
||||
|
||||
void setLinkedDevices(List<DeviceEntity> linkedDevices) {
|
||||
state = state.copyWith(linkedDevices: linkedDevices);
|
||||
}
|
||||
|
||||
void toggleIsEditing() {
|
||||
state = state.copyWith(isEditing: !state.isEditing);
|
||||
}
|
||||
|
||||
void _onDeviceNameChanged() {
|
||||
final value = deviceNameController.text;
|
||||
|
||||
if (value == state.deviceName) return;
|
||||
|
||||
state = state.copyWith(
|
||||
deviceName: value,
|
||||
);
|
||||
}
|
||||
|
||||
void disposeControllers() {
|
||||
deviceNameController.removeListener(_onDeviceNameChanged);
|
||||
deviceNameController.dispose();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
import 'package:account/src/features/linked_devices/domain/entities/device_entity.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
part 'linked_devices_view_state.freezed.dart';
|
||||
|
||||
@freezed
|
||||
abstract class LinkedDevicesViewState with _$LinkedDevicesViewState {
|
||||
const factory LinkedDevicesViewState({
|
||||
@Default(false) bool isLoading,
|
||||
@Default([]) List<DeviceEntity> linkedDevices,
|
||||
@Default(false) bool isEditing,
|
||||
@Default('') String deviceName
|
||||
}) = _LinkedDevicesViewState;
|
||||
}
|
||||
@@ -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 'linked_devices_view_state.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// FreezedGenerator
|
||||
// **************************************************************************
|
||||
|
||||
// dart format off
|
||||
T _$identity<T>(T value) => value;
|
||||
/// @nodoc
|
||||
mixin _$LinkedDevicesViewState {
|
||||
|
||||
bool get isLoading; List<DeviceEntity> get linkedDevices; bool get isEditing; String get deviceName;
|
||||
/// Create a copy of LinkedDevicesViewState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
$LinkedDevicesViewStateCopyWith<LinkedDevicesViewState> get copyWith => _$LinkedDevicesViewStateCopyWithImpl<LinkedDevicesViewState>(this as LinkedDevicesViewState, _$identity);
|
||||
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is LinkedDevicesViewState&&(identical(other.isLoading, isLoading) || other.isLoading == isLoading)&&const DeepCollectionEquality().equals(other.linkedDevices, linkedDevices)&&(identical(other.isEditing, isEditing) || other.isEditing == isEditing)&&(identical(other.deviceName, deviceName) || other.deviceName == deviceName));
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,isLoading,const DeepCollectionEquality().hash(linkedDevices),isEditing,deviceName);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'LinkedDevicesViewState(isLoading: $isLoading, linkedDevices: $linkedDevices, isEditing: $isEditing, deviceName: $deviceName)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class $LinkedDevicesViewStateCopyWith<$Res> {
|
||||
factory $LinkedDevicesViewStateCopyWith(LinkedDevicesViewState value, $Res Function(LinkedDevicesViewState) _then) = _$LinkedDevicesViewStateCopyWithImpl;
|
||||
@useResult
|
||||
$Res call({
|
||||
bool isLoading, List<DeviceEntity> linkedDevices, bool isEditing, String deviceName
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class _$LinkedDevicesViewStateCopyWithImpl<$Res>
|
||||
implements $LinkedDevicesViewStateCopyWith<$Res> {
|
||||
_$LinkedDevicesViewStateCopyWithImpl(this._self, this._then);
|
||||
|
||||
final LinkedDevicesViewState _self;
|
||||
final $Res Function(LinkedDevicesViewState) _then;
|
||||
|
||||
/// Create a copy of LinkedDevicesViewState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline') @override $Res call({Object? isLoading = null,Object? linkedDevices = null,Object? isEditing = null,Object? deviceName = null,}) {
|
||||
return _then(_self.copyWith(
|
||||
isLoading: null == isLoading ? _self.isLoading : isLoading // ignore: cast_nullable_to_non_nullable
|
||||
as bool,linkedDevices: null == linkedDevices ? _self.linkedDevices : linkedDevices // ignore: cast_nullable_to_non_nullable
|
||||
as List<DeviceEntity>,isEditing: null == isEditing ? _self.isEditing : isEditing // ignore: cast_nullable_to_non_nullable
|
||||
as bool,deviceName: null == deviceName ? _self.deviceName : deviceName // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// Adds pattern-matching-related methods to [LinkedDevicesViewState].
|
||||
extension LinkedDevicesViewStatePatterns on LinkedDevicesViewState {
|
||||
/// 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( _LinkedDevicesViewState value)? $default,{required TResult orElse(),}){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _LinkedDevicesViewState() 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( _LinkedDevicesViewState value) $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _LinkedDevicesViewState():
|
||||
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( _LinkedDevicesViewState value)? $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _LinkedDevicesViewState() 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<DeviceEntity> linkedDevices, bool isEditing, String deviceName)? $default,{required TResult orElse(),}) {final _that = this;
|
||||
switch (_that) {
|
||||
case _LinkedDevicesViewState() when $default != null:
|
||||
return $default(_that.isLoading,_that.linkedDevices,_that.isEditing,_that.deviceName);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<DeviceEntity> linkedDevices, bool isEditing, String deviceName) $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _LinkedDevicesViewState():
|
||||
return $default(_that.isLoading,_that.linkedDevices,_that.isEditing,_that.deviceName);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<DeviceEntity> linkedDevices, bool isEditing, String deviceName)? $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _LinkedDevicesViewState() when $default != null:
|
||||
return $default(_that.isLoading,_that.linkedDevices,_that.isEditing,_that.deviceName);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
|
||||
|
||||
class _LinkedDevicesViewState implements LinkedDevicesViewState {
|
||||
const _LinkedDevicesViewState({this.isLoading = false, final List<DeviceEntity> linkedDevices = const [], this.isEditing = false, this.deviceName = ''}): _linkedDevices = linkedDevices;
|
||||
|
||||
|
||||
@override@JsonKey() final bool isLoading;
|
||||
final List<DeviceEntity> _linkedDevices;
|
||||
@override@JsonKey() List<DeviceEntity> get linkedDevices {
|
||||
if (_linkedDevices is EqualUnmodifiableListView) return _linkedDevices;
|
||||
// ignore: implicit_dynamic_type
|
||||
return EqualUnmodifiableListView(_linkedDevices);
|
||||
}
|
||||
|
||||
@override@JsonKey() final bool isEditing;
|
||||
@override@JsonKey() final String deviceName;
|
||||
|
||||
/// Create a copy of LinkedDevicesViewState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
_$LinkedDevicesViewStateCopyWith<_LinkedDevicesViewState> get copyWith => __$LinkedDevicesViewStateCopyWithImpl<_LinkedDevicesViewState>(this, _$identity);
|
||||
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _LinkedDevicesViewState&&(identical(other.isLoading, isLoading) || other.isLoading == isLoading)&&const DeepCollectionEquality().equals(other._linkedDevices, _linkedDevices)&&(identical(other.isEditing, isEditing) || other.isEditing == isEditing)&&(identical(other.deviceName, deviceName) || other.deviceName == deviceName));
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,isLoading,const DeepCollectionEquality().hash(_linkedDevices),isEditing,deviceName);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'LinkedDevicesViewState(isLoading: $isLoading, linkedDevices: $linkedDevices, isEditing: $isEditing, deviceName: $deviceName)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class _$LinkedDevicesViewStateCopyWith<$Res> implements $LinkedDevicesViewStateCopyWith<$Res> {
|
||||
factory _$LinkedDevicesViewStateCopyWith(_LinkedDevicesViewState value, $Res Function(_LinkedDevicesViewState) _then) = __$LinkedDevicesViewStateCopyWithImpl;
|
||||
@override @useResult
|
||||
$Res call({
|
||||
bool isLoading, List<DeviceEntity> linkedDevices, bool isEditing, String deviceName
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class __$LinkedDevicesViewStateCopyWithImpl<$Res>
|
||||
implements _$LinkedDevicesViewStateCopyWith<$Res> {
|
||||
__$LinkedDevicesViewStateCopyWithImpl(this._self, this._then);
|
||||
|
||||
final _LinkedDevicesViewState _self;
|
||||
final $Res Function(_LinkedDevicesViewState) _then;
|
||||
|
||||
/// Create a copy of LinkedDevicesViewState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @pragma('vm:prefer-inline') $Res call({Object? isLoading = null,Object? linkedDevices = null,Object? isEditing = null,Object? deviceName = null,}) {
|
||||
return _then(_LinkedDevicesViewState(
|
||||
isLoading: null == isLoading ? _self.isLoading : isLoading // ignore: cast_nullable_to_non_nullable
|
||||
as bool,linkedDevices: null == linkedDevices ? _self._linkedDevices : linkedDevices // ignore: cast_nullable_to_non_nullable
|
||||
as List<DeviceEntity>,isEditing: null == isEditing ? _self.isEditing : isEditing // ignore: cast_nullable_to_non_nullable
|
||||
as bool,deviceName: null == deviceName ? _self.deviceName : deviceName // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// dart format on
|
||||
@@ -1 +0,0 @@
|
||||
// TODO Implement this library.
|
||||
@@ -66,7 +66,7 @@ class HubScreen extends ConsumerWidget {
|
||||
text: I18n.functions),
|
||||
SizedBox(height: SizeUtils.getByScreen(small: 8, big: 7)),
|
||||
AppSectionButton(
|
||||
onPressed: (){},
|
||||
onPressed: (){navigationContract.pushTo(AppRoutes.accountSettings);},
|
||||
icon: Icons.manage_accounts_outlined,
|
||||
text: I18n.accountSettings),
|
||||
SizedBox(height: SizeUtils.getByScreen(small: 8, big: 7)),
|
||||
|
||||
140
packages/design_system/lib/fonts/config.json → packages/design_system/fonts/config.json
Executable file → Normal file
140
packages/design_system/lib/fonts/config.json → packages/design_system/fonts/config.json
Executable file → Normal file
File diff suppressed because one or more lines are too long
@@ -17,6 +17,7 @@ class AppRoutes {
|
||||
|
||||
static const legacy = '/legacy';
|
||||
|
||||
static const accountSettings = '$legacy/account_settings';
|
||||
static const legacyDashboard = '$legacy/dashboard';
|
||||
|
||||
static const dashboardHub = '$legacyDashboard/hub';
|
||||
|
||||
Reference in New Issue
Block a user