From 9ec761e6eb54e8f24f633e1e868cf8295847ceca Mon Sep 17 00:00:00 2001 From: "mr.mojtaba" Date: Sun, 11 May 2025 11:49:51 +0330 Subject: [PATCH] feat : auth package --- .../local_storage/hive/hive_provider.dart | 12 - .../local_storage/hive/hive_types.dart | 1 - .../i_local_storage_provider.dart | 3 - .../user/user_local_storage.dart | 19 -- lib/data/model/user/user_model.dart | 17 -- .../repository/user/user_repository.dart | 17 -- lib/domain/service/user/user_service.dart | 17 -- lib/main.dart | 7 +- .../dto/auth_response/auth_response_dto.dart | 23 ++ .../login_request/login_request_model.dart | 21 ++ .../login_request_model.freezed.dart | 157 +++++++++++ .../login_request/login_request_model.g.dart | 23 ++ .../models/user_local/user_local_model.dart | 41 +++ .../domain/entity/auth_response_entity.dart | 12 + .../domain/repositories/auth_repository.dart | 7 + .../{auth_with_use_and_pass => }/logic.dart | 2 +- .../{auth_with_use_and_pass => }/view.dart | 6 +- .../src/presentation/pages/splash/logic.dart | 68 ----- .../src/presentation/pages/splash/view.dart | 47 ---- .../pages/system_design/system_design.dart | 255 ------------------ packages/auth/pubspec.yaml | 20 +- packages/core/lib/core.dart | 8 + packages/core/lib/data/utils.dart | 12 +- .../local/hive_local_storage.dart | 61 +++++ .../infrastructure/local/i_local_storage.dart | 11 + .../infrastructure/remote/dio_form_data.dart | 23 ++ .../lib/infrastructure/remote/dio_remote.dart | 126 +++++++++ .../infrastructure/remote/dio_response.dart | 21 ++ .../remote/interfaces/i_form_data.dart | 6 + .../remote/interfaces/i_http_client.dart | 51 ++++ .../remote/interfaces/i_http_response.dart | 6 + .../remote/interfaces/i_remote.dart | 4 + packages/core/pubspec.lock | 24 ++ packages/core/pubspec.yaml | 12 +- 34 files changed, 665 insertions(+), 475 deletions(-) delete mode 100644 lib/data/data_provider/local_storage/hive/hive_provider.dart delete mode 100644 lib/data/data_provider/local_storage/hive/hive_types.dart delete mode 100644 lib/data/data_provider/local_storage/i_local_storage_provider.dart delete mode 100644 lib/data/data_source/local_storage/user/user_local_storage.dart delete mode 100644 lib/data/model/user/user_model.dart delete mode 100644 lib/domain/repository/user/user_repository.dart delete mode 100644 lib/domain/service/user/user_service.dart create mode 100644 packages/auth/lib/src/data/dto/auth_response/auth_response_dto.dart create mode 100644 packages/auth/lib/src/data/models/login_request/login_request_model.dart create mode 100644 packages/auth/lib/src/data/models/login_request/login_request_model.freezed.dart create mode 100644 packages/auth/lib/src/data/models/login_request/login_request_model.g.dart create mode 100644 packages/auth/lib/src/data/models/user_local/user_local_model.dart create mode 100644 packages/auth/lib/src/domain/entity/auth_response_entity.dart create mode 100644 packages/auth/lib/src/domain/repositories/auth_repository.dart rename packages/auth/lib/src/presentation/pages/auth/{auth_with_use_and_pass => }/logic.dart (97%) rename packages/auth/lib/src/presentation/pages/auth/{auth_with_use_and_pass => }/view.dart (99%) delete mode 100644 packages/auth/lib/src/presentation/pages/splash/logic.dart delete mode 100644 packages/auth/lib/src/presentation/pages/splash/view.dart delete mode 100644 packages/auth/lib/src/presentation/pages/system_design/system_design.dart create mode 100644 packages/core/lib/infrastructure/local/hive_local_storage.dart create mode 100644 packages/core/lib/infrastructure/local/i_local_storage.dart create mode 100644 packages/core/lib/infrastructure/remote/dio_form_data.dart create mode 100644 packages/core/lib/infrastructure/remote/dio_remote.dart create mode 100644 packages/core/lib/infrastructure/remote/dio_response.dart create mode 100644 packages/core/lib/infrastructure/remote/interfaces/i_form_data.dart create mode 100644 packages/core/lib/infrastructure/remote/interfaces/i_http_client.dart create mode 100644 packages/core/lib/infrastructure/remote/interfaces/i_http_response.dart create mode 100644 packages/core/lib/infrastructure/remote/interfaces/i_remote.dart diff --git a/lib/data/data_provider/local_storage/hive/hive_provider.dart b/lib/data/data_provider/local_storage/hive/hive_provider.dart deleted file mode 100644 index c97f027..0000000 --- a/lib/data/data_provider/local_storage/hive/hive_provider.dart +++ /dev/null @@ -1,12 +0,0 @@ -import 'package:hive_ce_flutter/hive_flutter.dart'; -import 'package:rasadyar_app/data/data_provider/local_storage/i_local_storage_provider.dart'; - - -enum HiveBoxNames { user, settings, auth } - -class HiveProvider extends ILocalStorageProvider { - @override - Future init() async { - await Hive.initFlutter(); - } -} diff --git a/lib/data/data_provider/local_storage/hive/hive_types.dart b/lib/data/data_provider/local_storage/hive/hive_types.dart deleted file mode 100644 index eff0bf2..0000000 --- a/lib/data/data_provider/local_storage/hive/hive_types.dart +++ /dev/null @@ -1 +0,0 @@ -const int userTypeId = 0; diff --git a/lib/data/data_provider/local_storage/i_local_storage_provider.dart b/lib/data/data_provider/local_storage/i_local_storage_provider.dart deleted file mode 100644 index 2ccacf8..0000000 --- a/lib/data/data_provider/local_storage/i_local_storage_provider.dart +++ /dev/null @@ -1,3 +0,0 @@ -abstract class ILocalStorageProvider { - Future init(); -} diff --git a/lib/data/data_source/local_storage/user/user_local_storage.dart b/lib/data/data_source/local_storage/user/user_local_storage.dart deleted file mode 100644 index 0648a2d..0000000 --- a/lib/data/data_source/local_storage/user/user_local_storage.dart +++ /dev/null @@ -1,19 +0,0 @@ -import 'package:hive_ce_flutter/hive_flutter.dart'; -import 'package:rasadyar_app/data/data_provider/local_storage/hive/hive_provider.dart'; - -abstract class IUserLocalStorage { - Future userAuthed(); -} - -class UserLocalStorage extends IUserLocalStorage { - final user = Hive.box(HiveBoxNames.user.name); - - @override - Future userAuthed() async { - if (user.isNotEmpty ) { - return true; - } else { - return false; - } - } -} diff --git a/lib/data/model/user/user_model.dart b/lib/data/model/user/user_model.dart deleted file mode 100644 index 37f2b3b..0000000 --- a/lib/data/model/user/user_model.dart +++ /dev/null @@ -1,17 +0,0 @@ -import 'package:hive_ce/hive.dart'; - -import '../../data_provider/local_storage/hive/hive_types.dart'; - - -part 'user_model.g.dart'; - -@HiveType(typeId: userTypeId) -class UserModel extends HiveObject{ - @HiveField(0) - String? token; - - @HiveField(1) - String? refreshToken; - - UserModel({this.token, this.refreshToken}); -} diff --git a/lib/domain/repository/user/user_repository.dart b/lib/domain/repository/user/user_repository.dart deleted file mode 100644 index 3f90c41..0000000 --- a/lib/domain/repository/user/user_repository.dart +++ /dev/null @@ -1,17 +0,0 @@ -import 'package:rasadyar_app/data/data_source/local_storage/user/user_local_storage.dart'; - -abstract class IUserRepository { - Future userAuthed(); - -} - -class UserRepository implements IUserRepository { - final IUserLocalStorage _userLocalStorage; - - UserRepository(this._userLocalStorage); - - @override - Future userAuthed() async { - return await _userLocalStorage.userAuthed(); - } -} diff --git a/lib/domain/service/user/user_service.dart b/lib/domain/service/user/user_service.dart deleted file mode 100644 index 3c4b464..0000000 --- a/lib/domain/service/user/user_service.dart +++ /dev/null @@ -1,17 +0,0 @@ -import 'package:get/get.dart'; -import 'package:rasadyar_app/domain/repository/user/user_repository.dart'; -import 'package:rasadyar_app/infrastructure/di/di.dart'; - -class UserService extends GetxService { - late IUserRepository _userLocalStorage; - - @override - void onInit() { - return super.onInit(); - // _userLocalStorage = di.get(); - } - - Future isUserAuthed() async { - return await _userLocalStorage.userAuthed(); - } -} diff --git a/lib/main.dart b/lib/main.dart index 4eeebaa..148e4fe 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,15 +1,10 @@ import 'package:flutter/material.dart'; -import 'package:rasadyar_app/domain/service/user/user_service.dart'; import 'package:rasadyar_app/presentation/routes/app_pages.dart'; import 'package:rasadyar_core/core.dart'; -import 'package:rasadyar_core/infrastructure/di/di.dart'; void main() async { WidgetsFlutterBinding.ensureInitialized(); - setupInjection(); - await setupAllProvider(); - runApp(MyApp()); // runApp(DevicePreview(builder: (context) => ForDevicePreview(),)); } @@ -46,7 +41,7 @@ class MyApp extends StatelessWidget { colorScheme: ColorScheme.fromSeed(seedColor: AppColor.blueNormal), ), initialRoute: AppPages.initRoutes, - initialBinding: BindingsBuilder.put(() => UserService()), + // initialBinding: BindingsBuilder.put(() => UserService()), getPages: AppPages.pages, locale: const Locale("fa", "IR"), supportedLocales: const [ diff --git a/packages/auth/lib/src/data/dto/auth_response/auth_response_dto.dart b/packages/auth/lib/src/data/dto/auth_response/auth_response_dto.dart new file mode 100644 index 0000000..1f259f5 --- /dev/null +++ b/packages/auth/lib/src/data/dto/auth_response/auth_response_dto.dart @@ -0,0 +1,23 @@ +import 'package:auth/src/domain/entity/auth_response_entity.dart'; +import 'package:freezed_annotation/freezed_annotation.dart'; + +part 'auth_response_dto.freezed.dart'; +part 'auth_response_dto.g.dart'; + +@freezed +abstract class AuthResponseDto with _$AuthResponseDto { + const factory AuthResponseDto({ + String? refresh, + String? access, + @JsonKey(name: 'otp_status') bool? otpStatus, + }) = _AuthResponseDto; + + factory AuthResponseDto.fromJson(Map json) => + _$AuthResponseDtoFromJson(json); + + AuthResponseEntity toEntity() => AuthResponseEntity( + access: access, + otpStatus: otpStatus, + refresh: refresh, + ); +} diff --git a/packages/auth/lib/src/data/models/login_request/login_request_model.dart b/packages/auth/lib/src/data/models/login_request/login_request_model.dart new file mode 100644 index 0000000..0e4791c --- /dev/null +++ b/packages/auth/lib/src/data/models/login_request/login_request_model.dart @@ -0,0 +1,21 @@ +import 'package:rasadyar_core/core.dart'; + +part 'login_request_model.freezed.dart'; +part 'login_request_model.g.dart'; + +@freezed +abstract class LoginRequestModel with _$LoginRequestModel { + const factory LoginRequestModel({ + required String username, + required String password, + required String captchaCode, + required String captchaKey, + }) = _LoginRequestModel; + + factory LoginRequestModel.fromJson(Map json) => + _$LoginRequestModelFromJson(json); + + const LoginRequestModel._(); + + String get formattedCaptchaKey => 'rest_captcha_$captchaKey.0'; +} diff --git a/packages/auth/lib/src/data/models/login_request/login_request_model.freezed.dart b/packages/auth/lib/src/data/models/login_request/login_request_model.freezed.dart new file mode 100644 index 0000000..bf3b549 --- /dev/null +++ b/packages/auth/lib/src/data/models/login_request/login_request_model.freezed.dart @@ -0,0 +1,157 @@ +// dart format width=80 +// coverage:ignore-file +// GENERATED CODE - DO NOT MODIFY BY HAND +// 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 'login_request_model.dart'; + +// ************************************************************************** +// FreezedGenerator +// ************************************************************************** + +// dart format off +T _$identity(T value) => value; + +/// @nodoc +mixin _$LoginRequestModel { + + String get username; String get password; String get captchaCode; String get captchaKey; +/// Create a copy of LoginRequestModel +/// with the given fields replaced by the non-null parameter values. +@JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +$LoginRequestModelCopyWith get copyWith => _$LoginRequestModelCopyWithImpl(this as LoginRequestModel, _$identity); + + /// Serializes this LoginRequestModel to a JSON map. + Map toJson(); + + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is LoginRequestModel&&(identical(other.username, username) || other.username == username)&&(identical(other.password, password) || other.password == password)&&(identical(other.captchaCode, captchaCode) || other.captchaCode == captchaCode)&&(identical(other.captchaKey, captchaKey) || other.captchaKey == captchaKey)); +} + +@JsonKey(includeFromJson: false, includeToJson: false) +@override +int get hashCode => Object.hash(runtimeType,username,password,captchaCode,captchaKey); + +@override +String toString() { + return 'LoginRequestModel(username: $username, password: $password, captchaCode: $captchaCode, captchaKey: $captchaKey)'; +} + + +} + +/// @nodoc +abstract mixin class $LoginRequestModelCopyWith<$Res> { + factory $LoginRequestModelCopyWith(LoginRequestModel value, $Res Function(LoginRequestModel) _then) = _$LoginRequestModelCopyWithImpl; +@useResult +$Res call({ + String username, String password, String captchaCode, String captchaKey +}); + + + + +} +/// @nodoc +class _$LoginRequestModelCopyWithImpl<$Res> + implements $LoginRequestModelCopyWith<$Res> { + _$LoginRequestModelCopyWithImpl(this._self, this._then); + + final LoginRequestModel _self; + final $Res Function(LoginRequestModel) _then; + +/// Create a copy of LoginRequestModel +/// with the given fields replaced by the non-null parameter values. +@pragma('vm:prefer-inline') @override $Res call({Object? username = null,Object? password = null,Object? captchaCode = null,Object? captchaKey = null,}) { + return _then(_self.copyWith( +username: null == username ? _self.username : username // ignore: cast_nullable_to_non_nullable +as String,password: null == password ? _self.password : password // ignore: cast_nullable_to_non_nullable +as String,captchaCode: null == captchaCode ? _self.captchaCode : captchaCode // ignore: cast_nullable_to_non_nullable +as String,captchaKey: null == captchaKey ? _self.captchaKey : captchaKey // ignore: cast_nullable_to_non_nullable +as String, + )); +} + +} + + +/// @nodoc +@JsonSerializable() + +class _LoginRequestModel extends LoginRequestModel { + const _LoginRequestModel({required this.username, required this.password, required this.captchaCode, required this.captchaKey}): super._(); + factory _LoginRequestModel.fromJson(Map json) => _$LoginRequestModelFromJson(json); + +@override final String username; +@override final String password; +@override final String captchaCode; +@override final String captchaKey; + +/// Create a copy of LoginRequestModel +/// with the given fields replaced by the non-null parameter values. +@override @JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +_$LoginRequestModelCopyWith<_LoginRequestModel> get copyWith => __$LoginRequestModelCopyWithImpl<_LoginRequestModel>(this, _$identity); + +@override +Map toJson() { + return _$LoginRequestModelToJson(this, ); +} + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is _LoginRequestModel&&(identical(other.username, username) || other.username == username)&&(identical(other.password, password) || other.password == password)&&(identical(other.captchaCode, captchaCode) || other.captchaCode == captchaCode)&&(identical(other.captchaKey, captchaKey) || other.captchaKey == captchaKey)); +} + +@JsonKey(includeFromJson: false, includeToJson: false) +@override +int get hashCode => Object.hash(runtimeType,username,password,captchaCode,captchaKey); + +@override +String toString() { + return 'LoginRequestModel(username: $username, password: $password, captchaCode: $captchaCode, captchaKey: $captchaKey)'; +} + + +} + +/// @nodoc +abstract mixin class _$LoginRequestModelCopyWith<$Res> implements $LoginRequestModelCopyWith<$Res> { + factory _$LoginRequestModelCopyWith(_LoginRequestModel value, $Res Function(_LoginRequestModel) _then) = __$LoginRequestModelCopyWithImpl; +@override @useResult +$Res call({ + String username, String password, String captchaCode, String captchaKey +}); + + + + +} +/// @nodoc +class __$LoginRequestModelCopyWithImpl<$Res> + implements _$LoginRequestModelCopyWith<$Res> { + __$LoginRequestModelCopyWithImpl(this._self, this._then); + + final _LoginRequestModel _self; + final $Res Function(_LoginRequestModel) _then; + +/// Create a copy of LoginRequestModel +/// with the given fields replaced by the non-null parameter values. +@override @pragma('vm:prefer-inline') $Res call({Object? username = null,Object? password = null,Object? captchaCode = null,Object? captchaKey = null,}) { + return _then(_LoginRequestModel( +username: null == username ? _self.username : username // ignore: cast_nullable_to_non_nullable +as String,password: null == password ? _self.password : password // ignore: cast_nullable_to_non_nullable +as String,captchaCode: null == captchaCode ? _self.captchaCode : captchaCode // ignore: cast_nullable_to_non_nullable +as String,captchaKey: null == captchaKey ? _self.captchaKey : captchaKey // ignore: cast_nullable_to_non_nullable +as String, + )); +} + + +} + +// dart format on diff --git a/packages/auth/lib/src/data/models/login_request/login_request_model.g.dart b/packages/auth/lib/src/data/models/login_request/login_request_model.g.dart new file mode 100644 index 0000000..e92c1b4 --- /dev/null +++ b/packages/auth/lib/src/data/models/login_request/login_request_model.g.dart @@ -0,0 +1,23 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'login_request_model.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +_LoginRequestModel _$LoginRequestModelFromJson(Map json) => + _LoginRequestModel( + username: json['username'] as String, + password: json['password'] as String, + captchaCode: json['captchaCode'] as String, + captchaKey: json['captchaKey'] as String, + ); + +Map _$LoginRequestModelToJson(_LoginRequestModel instance) => + { + 'username': instance.username, + 'password': instance.password, + 'captchaCode': instance.captchaCode, + 'captchaKey': instance.captchaKey, + }; diff --git a/packages/auth/lib/src/data/models/user_local/user_local_model.dart b/packages/auth/lib/src/data/models/user_local/user_local_model.dart new file mode 100644 index 0000000..403f762 --- /dev/null +++ b/packages/auth/lib/src/data/models/user_local/user_local_model.dart @@ -0,0 +1,41 @@ +import 'package:rasadyar_core/core.dart'; + +part 'user_local_model.g.dart'; + +@HiveType(typeId: 0) +class UserLocalModel extends HiveObject { + @HiveField(0) + String? username; + @HiveField(1) + String? password; + @HiveField(2) + String? token; + @HiveField(3) + String? refreshToken; + @HiveField(4) + String? name; + + UserLocalModel({ + this.username, + this.password, + this.token, + this.refreshToken, + this.name, + }); + + UserLocalModel copyWith({ + String? username, + String? password, + String? token, + String? refreshToken, + String? name, + }) { + return UserLocalModel( + username: username ?? this.username, + password: password ?? this.password, + token: token ?? this.token, + refreshToken: refreshToken ?? this.refreshToken, + name: name ?? this.name, + ); + } +} diff --git a/packages/auth/lib/src/domain/entity/auth_response_entity.dart b/packages/auth/lib/src/domain/entity/auth_response_entity.dart new file mode 100644 index 0000000..a2cf7a9 --- /dev/null +++ b/packages/auth/lib/src/domain/entity/auth_response_entity.dart @@ -0,0 +1,12 @@ +class AuthResponseEntity { + final String? access; + final String? refresh; + final bool? otpStatus; + + AuthResponseEntity({this.access, this.refresh, this.otpStatus}); + + @override + String toString() { + return 'AuthResponseEntity{accessToken: $access, refreshToken: $refresh, expiresIn: $otpStatus}'; + } +} diff --git a/packages/auth/lib/src/domain/repositories/auth_repository.dart b/packages/auth/lib/src/domain/repositories/auth_repository.dart new file mode 100644 index 0000000..1d7748c --- /dev/null +++ b/packages/auth/lib/src/domain/repositories/auth_repository.dart @@ -0,0 +1,7 @@ +import 'package:auth/src/domain/entity/auth_response_entity.dart'; + +abstract class AuthRepository { + Future signIn({ + required Map authRequest, + }); +} diff --git a/packages/auth/lib/src/presentation/pages/auth/auth_with_use_and_pass/logic.dart b/packages/auth/lib/src/presentation/pages/auth/logic.dart similarity index 97% rename from packages/auth/lib/src/presentation/pages/auth/auth_with_use_and_pass/logic.dart rename to packages/auth/lib/src/presentation/pages/auth/logic.dart index 580413d..505e224 100644 --- a/packages/auth/lib/src/presentation/pages/auth/auth_with_use_and_pass/logic.dart +++ b/packages/auth/lib/src/presentation/pages/auth/logic.dart @@ -9,7 +9,7 @@ enum AuthStatus { init } enum OtpStatus { init, sent, verified, reSend } -class AuthWithUseAndPassLogic extends GetxController { +class AuthLogic extends GetxController { Rx> formKey = GlobalKey().obs; Rx> formKeyOtp = GlobalKey().obs; Rx> formKeySentOtp = GlobalKey().obs; diff --git a/packages/auth/lib/src/presentation/pages/auth/auth_with_use_and_pass/view.dart b/packages/auth/lib/src/presentation/pages/auth/view.dart similarity index 99% rename from packages/auth/lib/src/presentation/pages/auth/auth_with_use_and_pass/view.dart rename to packages/auth/lib/src/presentation/pages/auth/view.dart index f6cd2d7..6bb6af6 100644 --- a/packages/auth/lib/src/presentation/pages/auth/auth_with_use_and_pass/view.dart +++ b/packages/auth/lib/src/presentation/pages/auth/view.dart @@ -5,8 +5,10 @@ import 'package:rasadyar_core/core.dart'; import 'logic.dart'; -class AuthWithUseAndPassPage extends GetView { - const AuthWithUseAndPassPage({super.key}); + + +class AuthPage extends GetView { + const AuthPage({super.key}); @override Widget build(BuildContext context) { diff --git a/packages/auth/lib/src/presentation/pages/splash/logic.dart b/packages/auth/lib/src/presentation/pages/splash/logic.dart deleted file mode 100644 index 7542f46..0000000 --- a/packages/auth/lib/src/presentation/pages/splash/logic.dart +++ /dev/null @@ -1,68 +0,0 @@ -import 'package:flutter/animation.dart'; -import 'package:get/get.dart'; -import 'package:rasadyar_app/presentation/routes/app_pages.dart'; -import 'package:inspection/inspection.dart'; - -class SplashLogic extends GetxController with GetTickerProviderStateMixin { - late final AnimationController scaleController; - late final AnimationController rotateController; - Rxn> scaleAnimation = Rxn(); - Rxn> rotationAnimation = Rxn(); - - @override - void onInit() { - super.onInit(); - scaleController = AnimationController( - vsync: this, - duration: const Duration(milliseconds: 1500), - ); - - rotateController = AnimationController( - vsync: this, - duration: const Duration(milliseconds: 8000), - ); - - scaleAnimation.value = Tween( - begin: 0.8, - end: 1.2, - ).animate(scaleController); - - rotationAnimation.value = Tween( - begin: 0.0, - end: 1, - ).animate(rotateController); - - rotateController.forward(); - rotateController.addStatusListener((status) { - if (status == AnimationStatus.completed) { - rotateController.repeat(); - } else if (status == AnimationStatus.dismissed) { - rotateController.forward(); - } - }); - - scaleController.forward(); - scaleController.addStatusListener((status) { - if (status == AnimationStatus.completed) { - scaleController.reverse(); - } else if (status == AnimationStatus.dismissed) { - scaleController.forward(); - } - }); - } - - @override - void onReady() { - super.onReady(); - Future.delayed(const Duration(seconds: 1), () { - Get.offAllNamed(InspectionRoutes.inspection); - }); - } - - @override - void onClose() { - rotateController.dispose(); - scaleController.dispose(); - super.onClose(); - } -} diff --git a/packages/auth/lib/src/presentation/pages/splash/view.dart b/packages/auth/lib/src/presentation/pages/splash/view.dart deleted file mode 100644 index bffd309..0000000 --- a/packages/auth/lib/src/presentation/pages/splash/view.dart +++ /dev/null @@ -1,47 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:rasadyar_core/core.dart'; - - -import 'logic.dart'; - -class SplashPage extends GetView { - const SplashPage({super.key}); - - @override - Widget build(BuildContext context) { - return Scaffold( - backgroundColor: AppColor.blueDarker, - body: Center( - child: Stack( - alignment: Alignment.center, - children: [ - ObxValue((data) { - return ScaleTransition( - scale: data.value!, - child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 1), - child: Image.asset( - Assets.imagesInnerSplash, - width: 190, - height: 190, - ), - ), - ); - }, controller.scaleAnimation), - - ObxValue((data) { - return RotationTransition( - turns: data.value!, - - child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 1), - child: Image.asset(Assets.imagesOutterSplash), - ), - ); - }, controller.rotationAnimation), - ], - ), - ), - ); - } -} diff --git a/packages/auth/lib/src/presentation/pages/system_design/system_design.dart b/packages/auth/lib/src/presentation/pages/system_design/system_design.dart deleted file mode 100644 index f53eb75..0000000 --- a/packages/auth/lib/src/presentation/pages/system_design/system_design.dart +++ /dev/null @@ -1,255 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:rasadyar_core/core.dart'; - - -class SystemDesignPage extends StatefulWidget { - const SystemDesignPage({super.key}); - - @override - State createState() => _SystemDesignPageState(); -} - -class _SystemDesignPageState extends State { - List _isOpen = [false, false, false, false, false, false]; - - void _handleAdd() { - print("Add FAB pressed"); - } - - void _handleEdit() { - print("Edit FAB pressed"); - } - - void _handleDelete() { - print("Delete FAB pressed"); - } - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar(title: Text("System design"), centerTitle: true), - body: SingleChildScrollView( - child: Padding( - padding: const EdgeInsets.all(8.0), - child: ExpansionPanelList( - expansionCallback: (panelIndex, isExpanded) { - setState(() { - _isOpen[panelIndex] = isExpanded; - }); - }, - children: [ - buttonWidget(), - fabWidget(), - outlinedFabWidget(), - paginationWidget(), - tabWidget(), - inputsWidget(), - ], - ), - ), - ), - ); - } - - ExpansionPanel inputsWidget() { - return ExpansionPanel( - isExpanded: _isOpen[5], - headerBuilder: (context, isExpanded) { - return ListTile( - title: Text( - "inputs", - style: AppFonts.yekan20.copyWith(color: Colors.red), - ), - ); - }, - body: Padding( - padding: const EdgeInsets.all(8.0), - child: Column( - spacing: 14, - children: [ - RTextField( - hintText: 'حجم کشتار را در روز به قطعه وارد کنید', - hintStyle: AppFonts.yekan13, - ), - RTextField( - label: 'تلفن مرغداری', - labelStyle: AppFonts.yekan10, - ), - ], - ), - ), - ); - } - - ExpansionPanel tabWidget() { - return ExpansionPanel( - isExpanded: _isOpen[4], - headerBuilder: (context, isExpanded) { - return ListTile( - title: Text( - "tab", - style: AppFonts.yekan20.copyWith(color: Colors.red), - ), - ); - }, - body: Column( - spacing: 14, - children: [ - CupertinoSegmentedControlDemo(), - CupertinoSegmentedControlDemo2(), - ], - ), - ); - } - - ExpansionPanel paginationWidget() { - return ExpansionPanel( - isExpanded: _isOpen[3], - headerBuilder: (context, isExpanded) { - return ListTile( - title: Text( - "پیجینیشن", - style: AppFonts.yekan20.copyWith(color: Colors.red), - ), - ); - }, - body: Column(spacing: 14, children: [RShowMore(), PaginationFromUntil()]), - ); - } - - ExpansionPanel outlinedFabWidget() { - return ExpansionPanel( - isExpanded: _isOpen[2], - headerBuilder: (context, isExpanded) { - return ListTile( - title: Text( - "Outlined Fab ", - style: AppFonts.yekan20.copyWith(color: Colors.green), - ), - ); - }, - body: Column( - spacing: 14, - children: [ - Row(), -/* - RFabOutlined.smallAdd(onPressed: () {}), - RFabOutlined.smallAdd(onPressed: null), - - RFabOutlined.smallAddNoBorder(onPressed: () {}), - RFabOutlined.smallAddNoBorder(onPressed: null), - - RFabOutlined.add(onPressed: () {}), - RFabOutlined.add(onPressed: null), - - RFabOutlined.addNoBorder(onPressed: () {}), - RFabOutlined.addNoBorder(onPressed: null),*/ - ], - ), - ); - } - - ExpansionPanel fabWidget() { - return ExpansionPanel( - isExpanded: _isOpen[1], - headerBuilder: (context, isExpanded) { - return ListTile( - title: Text( - "Fab", - style: AppFonts.yekan20.copyWith(color: Colors.green), - ), - ); - }, - body: Column( - spacing: 14, - children: [ - Row(), - - /* RFab.smallAdd(onPressed: () {}), - RFab.smallAdd(onPressed: null), - - RFab.add(onPressed: () {}), - RFab.add(onPressed: null), - - RFab.smallEdit(onPressed: null), - RFab.smallEdit(onPressed: () {}), - - RFab.edit(onPressed: () {}), - RFab.edit(onPressed: null), - - RFab.smallDelete(onPressed: () {}), - RFab.smallDelete(onPressed: null), - - RFab.delete(onPressed: () {}), - RFab.delete(onPressed: null), - - RFab.smallAction(onPressed: () {}), - RFab.smallAction(onPressed: null), - - RFab.action(onPressed: () {}), - RFab.action(onPressed: null), - - RFab.smallFilter(onPressed: () {}), - RFab.smallFilter(onPressed: null), - - RFab.filter(onPressed: () {}), - RFab.filter(onPressed: null), - - RFab.smallDownload(onPressed: () {}), - RFab.smallDownload(onPressed: null), - - RFab.download(onPressed: () {}), - RFab.download(onPressed: null), - - RFab.smallExcel(onPressed: () {}), - RFab.smallExcel(onPressed: null), - - RFab.excel(onPressed: () {}), - RFab.excel(onPressed: null), - - RFab.smallBack(onPressed: () {}), - RFab.smallBack(onPressed: null), - - RFab.back(onPressed: () {}), - RFab.back(onPressed: null),*/ - ], - ), - ); - } - - ExpansionPanel buttonWidget() { - return ExpansionPanel( - isExpanded: _isOpen[0], - headerBuilder: (context, isExpanded) { - return ListTile( - title: Text( - "دکمه ها", - style: AppFonts.yekan20.copyWith(color: Colors.green), - ), - ); - }, - body: Column( - spacing: 14, - children: [ - Row(), - - RElevated(text: 'ثبت', onPressed: () {}), - - RElevated(text: 'ثبت', onPressed: null), - - ROutlinedElevated(text: 'ثبت', onPressed: () {}), - ROutlinedElevated( - text: 'ثبتwwww', - onPressed: () {}, - backgroundColor: AppColor.blueNormal.disabledColor, - pressedBackgroundColor: AppColor.blueNormal, - ), - ROutlinedElevated(text: 'ثبت', onPressed: null), - - RTextButton(text: 'ثبت', onPressed: () {}), - RTextButton(text: 'ثبت', onPressed: null), - ], - ), - ); - } -} diff --git a/packages/auth/pubspec.yaml b/packages/auth/pubspec.yaml index 2179965..e6f65ab 100644 --- a/packages/auth/pubspec.yaml +++ b/packages/auth/pubspec.yaml @@ -1,15 +1,33 @@ name: auth description: A starting point for Dart libraries or applications. +publish_to: 'none' version: 1.0.0 + # repository: https://github.com/my_org/my_repo environment: sdk: ^3.7.2 -# Add regular dependencies here. dependencies: # path: ^1.8.0 + rasadyar_core: + path: ../core dev_dependencies: lints: ^5.0.0 test: ^1.24.0 + flutter_test: + sdk: flutter + flutter_lints: ^5.0.0 + ##code generation + build_runner: ^2.4.15 + hive_ce_generator: ^1.9.1 + freezed: ^3.0.3 + json_serializable: ^6.9.4 + + ##test + mocktail: ^1.0.4 + get_test: ^4.0.1 + +flutter: + uses-material-design: true \ No newline at end of file diff --git a/packages/core/lib/core.dart b/packages/core/lib/core.dart index f6d3b76..0aa727e 100644 --- a/packages/core/lib/core.dart +++ b/packages/core/lib/core.dart @@ -11,6 +11,13 @@ export 'package:flutter_slidable/flutter_slidable.dart'; export 'package:font_awesome_flutter/font_awesome_flutter.dart'; export 'package:flutter_rating_bar/flutter_rating_bar.dart'; export 'package:persian_datetime_picker/persian_datetime_picker.dart'; + +//freezed +export 'package:freezed_annotation/freezed_annotation.dart'; + +//local storage +export 'package:hive_ce_flutter/hive_flutter.dart'; + //Map and location export 'package:latlong2/latlong.dart'; export 'package:flutter_map/flutter_map.dart'; @@ -19,3 +26,4 @@ export 'package:flutter_map_animations/flutter_map_animations.dart'; + diff --git a/packages/core/lib/data/utils.dart b/packages/core/lib/data/utils.dart index c7a1250..4edf8a0 100644 --- a/packages/core/lib/data/utils.dart +++ b/packages/core/lib/data/utils.dart @@ -1,37 +1,37 @@ import 'package:flutter/foundation.dart'; import 'package:logger/logger.dart'; -import 'package:rasadyar_core/infrastructure/di/di.dart'; +import 'package:rasadyar_core/injection/di.dart'; void iLog(dynamic message) { if(kDebugMode){ - di.get().i(message.toString()); + diCore.get().i(message.toString()); } } void eLog(dynamic message) { if(kDebugMode){ - di.get().e(message.toString()); + diCore.get().e(message.toString()); } } void dLog(dynamic message) { if(kDebugMode){ - di.get().d(message.toString()); + diCore.get().d(message.toString()); } } void fLog(dynamic message){ if(kDebugMode){ - di.get().f(message.toString()); + diCore.get().f(message.toString()); } } void tLog(dynamic message) { if(kDebugMode){ - di.get().t(message.toString()); + diCore.get().t(message.toString()); } } diff --git a/packages/core/lib/infrastructure/local/hive_local_storage.dart b/packages/core/lib/infrastructure/local/hive_local_storage.dart new file mode 100644 index 0000000..c63e7f3 --- /dev/null +++ b/packages/core/lib/infrastructure/local/hive_local_storage.dart @@ -0,0 +1,61 @@ +import 'package:hive_ce_flutter/hive_flutter.dart'; + +import 'i_local_storage.dart'; + +class HiveLocalStorage implements ILocalStorage { + HiveLocalStorage() { + Hive.initFlutter(); + } + + final Map _boxes = {}; + + @override + Future init() async => await Hive.initFlutter(); + + @override + Future openBox(String boxName) async { + if (!_boxes.containsKey(boxName)) { + final box = await Hive.openBox(boxName); + _boxes[boxName] = box; + } + } + + @override + Future delete(String boxName, String key) async { + Box? box = await getBox(boxName); + await box.delete(key); + } + + @override + Future read(String boxName, String key) async { + Box? box = await getBox(boxName); + return box.get(key) as T?; + } + + @override + Future save(String boxName, String key, value) async { + Box? box = await getBox(boxName); + await box.put(key, value); + } + + @override + Future add(String boxName, value) async { + Box? box = await getBox(boxName); + await box.add(value); + } + + @override + Future addAll(String boxName, Iterable values) async { + Box? box = await getBox(boxName); + await box.addAll(values); + } + + Future> getBox(String boxName) async { + final box = _boxes[boxName]; + if (box is Box) { + return box; + } else { + throw Exception('Box $boxName is not of expected type $T'); + } + } +} diff --git a/packages/core/lib/infrastructure/local/i_local_storage.dart b/packages/core/lib/infrastructure/local/i_local_storage.dart new file mode 100644 index 0000000..2b0a7f4 --- /dev/null +++ b/packages/core/lib/infrastructure/local/i_local_storage.dart @@ -0,0 +1,11 @@ +abstract class ILocalStorage{ + Future init(); + Future openBox(String boxName); + Future save(String boxName, String key, dynamic value); + Future read(String boxName, String key); + Future delete(String boxName, String key); + + Future add(String boxName, E value); + Future addAll(String boxName, Iterable values); + +} \ No newline at end of file diff --git a/packages/core/lib/infrastructure/remote/dio_form_data.dart b/packages/core/lib/infrastructure/remote/dio_form_data.dart new file mode 100644 index 0000000..8e74832 --- /dev/null +++ b/packages/core/lib/infrastructure/remote/dio_form_data.dart @@ -0,0 +1,23 @@ +import 'package:dio/dio.dart'; +import 'package:flutter/foundation.dart'; + +import 'interfaces/i_form_data.dart'; + +class DioFormData implements IFormData { + final FormData _formData = FormData(); + + @override + void addFile(String field, Uint8List bytes, String filename) { + _formData.files.add(MapEntry( + field, + MultipartFile.fromBytes(bytes, filename: filename), + )); + } + + @override + void addField(String key, String value) { + _formData.fields.add(MapEntry(key, value)); + } + + FormData get raw => _formData; +} diff --git a/packages/core/lib/infrastructure/remote/dio_remote.dart b/packages/core/lib/infrastructure/remote/dio_remote.dart new file mode 100644 index 0000000..6b8ac08 --- /dev/null +++ b/packages/core/lib/infrastructure/remote/dio_remote.dart @@ -0,0 +1,126 @@ +import 'dart:typed_data'; + +import 'package:dio/dio.dart'; +import 'package:pretty_dio_logger/pretty_dio_logger.dart'; +import 'package:rasadyar_core/infrastructure/remote/interfaces/i_form_data.dart'; +import 'package:rasadyar_core/infrastructure/remote/interfaces/i_http_response.dart'; +import 'package:rasadyar_core/infrastructure/remote/interfaces/i_remote.dart'; + +import 'dio_form_data.dart'; +import 'dio_response.dart'; +import 'interfaces/i_http_client.dart'; + +class DioRemote implements IRemote, IHttpClient { + final String baseUrl; + late final Dio _dio; + + DioRemote(this.baseUrl); + + @override + Future init() async { + final dio = Dio(BaseOptions(baseUrl: baseUrl)); + dio.interceptors.add(PrettyDioLogger()); + _dio = dio; + } + + @override + Future get( + String path, { + Map? queryParameters, + Map? headers, + ProgressCallback? onReceiveProgress, + }) async { + final response = await _dio.get( + path, + queryParameters: queryParameters, + options: Options(headers: headers), + onReceiveProgress: onReceiveProgress, + ); + return DioHttpResponse(response); + } + + @override + Future post( + String path, { + dynamic data, + Map? queryParameters, + Map? headers, + ProgressCallback? onSendProgress, + ProgressCallback? onReceiveProgress, + }) async { + final response = await _dio.post( + path, + data: data, + queryParameters: queryParameters, + options: Options(headers: headers), + onSendProgress: onSendProgress, + onReceiveProgress: onReceiveProgress, + ); + return DioHttpResponse(response); + } + + @override + Future put( + String path, { + dynamic data, + Map? queryParameters, + Map? headers, + ProgressCallback? onSendProgress, + ProgressCallback? onReceiveProgress, + }) async { + final response = await _dio.put( + path, + data: data, + queryParameters: queryParameters, + options: Options(headers: headers), + onSendProgress: onSendProgress, + onReceiveProgress: onReceiveProgress, + ); + return DioHttpResponse(response); + } + + @override + Future delete( + String path, { + dynamic data, + Map? queryParameters, + Map? headers, + }) async { + final response = await _dio.delete( + path, + data: data, + queryParameters: queryParameters, + options: Options(headers: headers), + ); + return DioHttpResponse(response); + } + + @override + Future> download( + String url, { + ProgressCallback? onReceiveProgress, + }) async { + final response = await _dio.get( + url, + options: Options(responseType: ResponseType.bytes), + onReceiveProgress: onReceiveProgress, + ); + return DioHttpResponse(response); + } + + @override + Future upload( + String path, { + required IFormData formData, + Map? headers, + ProgressCallback? onSendProgress, + }) async { + final response = await _dio.post( + path, + data: (formData as DioFormData).raw, + options: Options(headers: headers, contentType: 'multipart/form-data'), + onSendProgress: onSendProgress, + ); + return DioHttpResponse(response); + } +} diff --git a/packages/core/lib/infrastructure/remote/dio_response.dart b/packages/core/lib/infrastructure/remote/dio_response.dart new file mode 100644 index 0000000..0a42eea --- /dev/null +++ b/packages/core/lib/infrastructure/remote/dio_response.dart @@ -0,0 +1,21 @@ +import 'interfaces/i_http_response.dart'; +import 'package:dio/dio.dart'; + +class DioHttpResponse implements IHttpResponse { + final Response _response; + + DioHttpResponse(this._response); + + @override + T? get data => _response.data; + + @override + int get statusCode => _response.statusCode ?? 0; + + @override + Map> get headers => + _response.headers.map.map((k, v) => MapEntry(k, v)); + + @override + bool get isSuccessful => statusCode >= 200 && statusCode < 300; +} diff --git a/packages/core/lib/infrastructure/remote/interfaces/i_form_data.dart b/packages/core/lib/infrastructure/remote/interfaces/i_form_data.dart new file mode 100644 index 0000000..ddbda85 --- /dev/null +++ b/packages/core/lib/infrastructure/remote/interfaces/i_form_data.dart @@ -0,0 +1,6 @@ +import 'package:flutter/foundation.dart'; + +abstract class IFormData{ + void addFile(String field, Uint8List bytes, String filename); + void addField(String key, String value); +} \ No newline at end of file diff --git a/packages/core/lib/infrastructure/remote/interfaces/i_http_client.dart b/packages/core/lib/infrastructure/remote/interfaces/i_http_client.dart new file mode 100644 index 0000000..253130a --- /dev/null +++ b/packages/core/lib/infrastructure/remote/interfaces/i_http_client.dart @@ -0,0 +1,51 @@ +import 'dart:typed_data'; +import 'package:dio/dio.dart'; +import 'package:rasadyar_core/infrastructure/remote/dio_form_data.dart'; +import 'i_http_response.dart'; +import 'i_form_data.dart'; + +abstract class IHttpClient { + Future get( + String path, { + Map? queryParameters, + Map? headers, + ProgressCallback? onReceiveProgress, + }); + + Future post( + String path, { + dynamic data, + Map? queryParameters, + Map? headers, + ProgressCallback? onSendProgress, + ProgressCallback? onReceiveProgress, + }); + + Future put( + String path, { + dynamic data, + Map? queryParameters, + Map? headers, + ProgressCallback? onSendProgress, + ProgressCallback? onReceiveProgress, + }); + + Future delete( + String path, { + dynamic data, + Map? queryParameters, + Map? headers, + }); + + Future> download( + String url, { + ProgressCallback? onReceiveProgress, + }); + + Future upload( + String path, { + required IFormData formData, + Map? headers, + ProgressCallback? onSendProgress, + }); +} diff --git a/packages/core/lib/infrastructure/remote/interfaces/i_http_response.dart b/packages/core/lib/infrastructure/remote/interfaces/i_http_response.dart new file mode 100644 index 0000000..14dd20a --- /dev/null +++ b/packages/core/lib/infrastructure/remote/interfaces/i_http_response.dart @@ -0,0 +1,6 @@ +abstract class IHttpResponse { + T? get data; + int get statusCode; + Map> get headers; + bool get isSuccessful; +} diff --git a/packages/core/lib/infrastructure/remote/interfaces/i_remote.dart b/packages/core/lib/infrastructure/remote/interfaces/i_remote.dart new file mode 100644 index 0000000..648883b --- /dev/null +++ b/packages/core/lib/infrastructure/remote/interfaces/i_remote.dart @@ -0,0 +1,4 @@ +abstract class IRemote{ + Future init(); +} + diff --git a/packages/core/pubspec.lock b/packages/core/pubspec.lock index 6b71ba8..a7deeac 100644 --- a/packages/core/pubspec.lock +++ b/packages/core/pubspec.lock @@ -193,6 +193,22 @@ packages: url: "https://pub.dev" source: hosted version: "1.2.0" + dio: + dependency: "direct main" + description: + name: dio + sha256: "253a18bbd4851fecba42f7343a1df3a9a4c1d31a2c1b37e221086b4fa8c8dbc9" + url: "https://pub.dev" + source: hosted + version: "5.8.0+1" + dio_web_adapter: + dependency: transitive + description: + name: dio_web_adapter + sha256: "7586e476d70caecaf1686d21eee7247ea43ef5c345eab9e0cc3583ff13378d78" + url: "https://pub.dev" + source: hosted + version: "2.1.1" fake_async: dependency: transitive description: @@ -797,6 +813,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.5.1" + pretty_dio_logger: + dependency: "direct main" + description: + name: pretty_dio_logger + sha256: "36f2101299786d567869493e2f5731de61ce130faa14679473b26905a92b6407" + url: "https://pub.dev" + source: hosted + version: "1.4.0" proj4dart: dependency: transitive description: diff --git a/packages/core/pubspec.yaml b/packages/core/pubspec.yaml index b3d4712..ce7312c 100644 --- a/packages/core/pubspec.yaml +++ b/packages/core/pubspec.yaml @@ -26,8 +26,8 @@ dependencies: rxdart: ^0.28.0 ## local storage - hive_ce: ^2.10.1 - hive_ce_flutter: ^2.2.0 + hive_ce: ^2.11.1 + hive_ce_flutter: ^2.3.0 ##code generation freezed_annotation: ^3.0.0 @@ -58,7 +58,11 @@ dependencies: #location latlong2: ^0.9.1 geolocator: ^14.0.0 + #network + dio: ^5.8.0+1 + #networkLogger + pretty_dio_logger: ^1.4.0 dev_dependencies: flutter_test: @@ -66,7 +70,7 @@ dev_dependencies: flutter_lints: ^5.0.0 ##code generation build_runner: ^2.4.15 - hive_ce_generator: ^1.8.2 + hive_ce_generator: ^1.9.1 freezed: ^3.0.3 json_serializable: ^6.9.4 @@ -75,5 +79,7 @@ dev_dependencies: get_test: ^4.0.1 + + flutter: uses-material-design: true