diff --git a/lib/application/customer/customer_point_loader/customer_point_loader_bloc.dart b/lib/application/customer/customer_point_loader/customer_point_loader_bloc.dart new file mode 100644 index 0000000..f64dab9 --- /dev/null +++ b/lib/application/customer/customer_point_loader/customer_point_loader_bloc.dart @@ -0,0 +1,42 @@ +import 'package:bloc/bloc.dart'; +import 'package:dartz/dartz.dart'; +import 'package:freezed_annotation/freezed_annotation.dart'; +import 'package:injectable/injectable.dart'; + +import '../../../domain/customer/customer.dart'; + +part 'customer_point_loader_event.dart'; +part 'customer_point_loader_state.dart'; +part 'customer_point_loader_bloc.freezed.dart'; + +@injectable +class CustomerPointLoaderBloc + extends Bloc { + final ICustomerRepository _repository; + CustomerPointLoaderBloc(this._repository) + : super(CustomerPointLoaderState.initial()) { + on(_onCustomerPointLoaderEvent); + } + + Future _onCustomerPointLoaderEvent( + CustomerPointLoaderEvent event, + Emitter emit, + ) { + return event.map( + fetched: (e) async { + emit( + state.copyWith(isFetching: true, failureOptionCustomerPoint: none()), + ); + + final result = await _repository.getPoints(); + + var data = result.fold( + (f) => state.copyWith(failureOptionCustomerPoint: optionOf(f)), + (customerPoint) => state.copyWith(customerPoint: customerPoint), + ); + + emit(data.copyWith(isFetching: false)); + }, + ); + } +} diff --git a/lib/application/customer/customer_point_loader/customer_point_loader_bloc.freezed.dart b/lib/application/customer/customer_point_loader/customer_point_loader_bloc.freezed.dart new file mode 100644 index 0000000..3588ac7 --- /dev/null +++ b/lib/application/customer/customer_point_loader/customer_point_loader_bloc.freezed.dart @@ -0,0 +1,391 @@ +// 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 'customer_point_loader_bloc.dart'; + +// ************************************************************************** +// FreezedGenerator +// ************************************************************************** + +T _$identity(T value) => value; + +final _privateConstructorUsedError = UnsupportedError( + 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models', +); + +/// @nodoc +mixin _$CustomerPointLoaderEvent { + @optionalTypeArgs + TResult when({ + required TResult Function() fetched, + }) => throw _privateConstructorUsedError; + @optionalTypeArgs + TResult? whenOrNull({ + TResult? Function()? fetched, + }) => throw _privateConstructorUsedError; + @optionalTypeArgs + TResult maybeWhen({ + TResult Function()? fetched, + required TResult orElse(), + }) => throw _privateConstructorUsedError; + @optionalTypeArgs + TResult map({ + required TResult Function(_Fetched value) fetched, + }) => throw _privateConstructorUsedError; + @optionalTypeArgs + TResult? mapOrNull({ + TResult? Function(_Fetched value)? fetched, + }) => throw _privateConstructorUsedError; + @optionalTypeArgs + TResult maybeMap({ + TResult Function(_Fetched value)? fetched, + required TResult orElse(), + }) => throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class $CustomerPointLoaderEventCopyWith<$Res> { + factory $CustomerPointLoaderEventCopyWith( + CustomerPointLoaderEvent value, + $Res Function(CustomerPointLoaderEvent) then, + ) = _$CustomerPointLoaderEventCopyWithImpl<$Res, CustomerPointLoaderEvent>; +} + +/// @nodoc +class _$CustomerPointLoaderEventCopyWithImpl< + $Res, + $Val extends CustomerPointLoaderEvent +> + implements $CustomerPointLoaderEventCopyWith<$Res> { + _$CustomerPointLoaderEventCopyWithImpl(this._value, this._then); + + // ignore: unused_field + final $Val _value; + // ignore: unused_field + final $Res Function($Val) _then; + + /// Create a copy of CustomerPointLoaderEvent + /// with the given fields replaced by the non-null parameter values. +} + +/// @nodoc +abstract class _$$FetchedImplCopyWith<$Res> { + factory _$$FetchedImplCopyWith( + _$FetchedImpl value, + $Res Function(_$FetchedImpl) then, + ) = __$$FetchedImplCopyWithImpl<$Res>; +} + +/// @nodoc +class __$$FetchedImplCopyWithImpl<$Res> + extends _$CustomerPointLoaderEventCopyWithImpl<$Res, _$FetchedImpl> + implements _$$FetchedImplCopyWith<$Res> { + __$$FetchedImplCopyWithImpl( + _$FetchedImpl _value, + $Res Function(_$FetchedImpl) _then, + ) : super(_value, _then); + + /// Create a copy of CustomerPointLoaderEvent + /// with the given fields replaced by the non-null parameter values. +} + +/// @nodoc + +class _$FetchedImpl implements _Fetched { + const _$FetchedImpl(); + + @override + String toString() { + return 'CustomerPointLoaderEvent.fetched()'; + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && other is _$FetchedImpl); + } + + @override + int get hashCode => runtimeType.hashCode; + + @override + @optionalTypeArgs + TResult when({required TResult Function() fetched}) { + return fetched(); + } + + @override + @optionalTypeArgs + TResult? whenOrNull({TResult? Function()? fetched}) { + return fetched?.call(); + } + + @override + @optionalTypeArgs + TResult maybeWhen({ + TResult Function()? fetched, + required TResult orElse(), + }) { + if (fetched != null) { + return fetched(); + } + return orElse(); + } + + @override + @optionalTypeArgs + TResult map({ + required TResult Function(_Fetched value) fetched, + }) { + return fetched(this); + } + + @override + @optionalTypeArgs + TResult? mapOrNull({ + TResult? Function(_Fetched value)? fetched, + }) { + return fetched?.call(this); + } + + @override + @optionalTypeArgs + TResult maybeMap({ + TResult Function(_Fetched value)? fetched, + required TResult orElse(), + }) { + if (fetched != null) { + return fetched(this); + } + return orElse(); + } +} + +abstract class _Fetched implements CustomerPointLoaderEvent { + const factory _Fetched() = _$FetchedImpl; +} + +/// @nodoc +mixin _$CustomerPointLoaderState { + CustomerPoint get customerPoint => throw _privateConstructorUsedError; + Option get failureOptionCustomerPoint => + throw _privateConstructorUsedError; + bool get isFetching => throw _privateConstructorUsedError; + + /// Create a copy of CustomerPointLoaderState + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + $CustomerPointLoaderStateCopyWith get copyWith => + throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class $CustomerPointLoaderStateCopyWith<$Res> { + factory $CustomerPointLoaderStateCopyWith( + CustomerPointLoaderState value, + $Res Function(CustomerPointLoaderState) then, + ) = _$CustomerPointLoaderStateCopyWithImpl<$Res, CustomerPointLoaderState>; + @useResult + $Res call({ + CustomerPoint customerPoint, + Option failureOptionCustomerPoint, + bool isFetching, + }); + + $CustomerPointCopyWith<$Res> get customerPoint; +} + +/// @nodoc +class _$CustomerPointLoaderStateCopyWithImpl< + $Res, + $Val extends CustomerPointLoaderState +> + implements $CustomerPointLoaderStateCopyWith<$Res> { + _$CustomerPointLoaderStateCopyWithImpl(this._value, this._then); + + // ignore: unused_field + final $Val _value; + // ignore: unused_field + final $Res Function($Val) _then; + + /// Create a copy of CustomerPointLoaderState + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? customerPoint = null, + Object? failureOptionCustomerPoint = null, + Object? isFetching = null, + }) { + return _then( + _value.copyWith( + customerPoint: null == customerPoint + ? _value.customerPoint + : customerPoint // ignore: cast_nullable_to_non_nullable + as CustomerPoint, + failureOptionCustomerPoint: null == failureOptionCustomerPoint + ? _value.failureOptionCustomerPoint + : failureOptionCustomerPoint // ignore: cast_nullable_to_non_nullable + as Option, + isFetching: null == isFetching + ? _value.isFetching + : isFetching // ignore: cast_nullable_to_non_nullable + as bool, + ) + as $Val, + ); + } + + /// Create a copy of CustomerPointLoaderState + /// with the given fields replaced by the non-null parameter values. + @override + @pragma('vm:prefer-inline') + $CustomerPointCopyWith<$Res> get customerPoint { + return $CustomerPointCopyWith<$Res>(_value.customerPoint, (value) { + return _then(_value.copyWith(customerPoint: value) as $Val); + }); + } +} + +/// @nodoc +abstract class _$$CustomerPointLoaderStateImplCopyWith<$Res> + implements $CustomerPointLoaderStateCopyWith<$Res> { + factory _$$CustomerPointLoaderStateImplCopyWith( + _$CustomerPointLoaderStateImpl value, + $Res Function(_$CustomerPointLoaderStateImpl) then, + ) = __$$CustomerPointLoaderStateImplCopyWithImpl<$Res>; + @override + @useResult + $Res call({ + CustomerPoint customerPoint, + Option failureOptionCustomerPoint, + bool isFetching, + }); + + @override + $CustomerPointCopyWith<$Res> get customerPoint; +} + +/// @nodoc +class __$$CustomerPointLoaderStateImplCopyWithImpl<$Res> + extends + _$CustomerPointLoaderStateCopyWithImpl< + $Res, + _$CustomerPointLoaderStateImpl + > + implements _$$CustomerPointLoaderStateImplCopyWith<$Res> { + __$$CustomerPointLoaderStateImplCopyWithImpl( + _$CustomerPointLoaderStateImpl _value, + $Res Function(_$CustomerPointLoaderStateImpl) _then, + ) : super(_value, _then); + + /// Create a copy of CustomerPointLoaderState + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? customerPoint = null, + Object? failureOptionCustomerPoint = null, + Object? isFetching = null, + }) { + return _then( + _$CustomerPointLoaderStateImpl( + customerPoint: null == customerPoint + ? _value.customerPoint + : customerPoint // ignore: cast_nullable_to_non_nullable + as CustomerPoint, + failureOptionCustomerPoint: null == failureOptionCustomerPoint + ? _value.failureOptionCustomerPoint + : failureOptionCustomerPoint // ignore: cast_nullable_to_non_nullable + as Option, + isFetching: null == isFetching + ? _value.isFetching + : isFetching // ignore: cast_nullable_to_non_nullable + as bool, + ), + ); + } +} + +/// @nodoc + +class _$CustomerPointLoaderStateImpl implements _CustomerPointLoaderState { + const _$CustomerPointLoaderStateImpl({ + required this.customerPoint, + required this.failureOptionCustomerPoint, + this.isFetching = false, + }); + + @override + final CustomerPoint customerPoint; + @override + final Option failureOptionCustomerPoint; + @override + @JsonKey() + final bool isFetching; + + @override + String toString() { + return 'CustomerPointLoaderState(customerPoint: $customerPoint, failureOptionCustomerPoint: $failureOptionCustomerPoint, isFetching: $isFetching)'; + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _$CustomerPointLoaderStateImpl && + (identical(other.customerPoint, customerPoint) || + other.customerPoint == customerPoint) && + (identical( + other.failureOptionCustomerPoint, + failureOptionCustomerPoint, + ) || + other.failureOptionCustomerPoint == + failureOptionCustomerPoint) && + (identical(other.isFetching, isFetching) || + other.isFetching == isFetching)); + } + + @override + int get hashCode => Object.hash( + runtimeType, + customerPoint, + failureOptionCustomerPoint, + isFetching, + ); + + /// Create a copy of CustomerPointLoaderState + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + @override + @pragma('vm:prefer-inline') + _$$CustomerPointLoaderStateImplCopyWith<_$CustomerPointLoaderStateImpl> + get copyWith => + __$$CustomerPointLoaderStateImplCopyWithImpl< + _$CustomerPointLoaderStateImpl + >(this, _$identity); +} + +abstract class _CustomerPointLoaderState implements CustomerPointLoaderState { + const factory _CustomerPointLoaderState({ + required final CustomerPoint customerPoint, + required final Option failureOptionCustomerPoint, + final bool isFetching, + }) = _$CustomerPointLoaderStateImpl; + + @override + CustomerPoint get customerPoint; + @override + Option get failureOptionCustomerPoint; + @override + bool get isFetching; + + /// Create a copy of CustomerPointLoaderState + /// with the given fields replaced by the non-null parameter values. + @override + @JsonKey(includeFromJson: false, includeToJson: false) + _$$CustomerPointLoaderStateImplCopyWith<_$CustomerPointLoaderStateImpl> + get copyWith => throw _privateConstructorUsedError; +} diff --git a/lib/application/customer/customer_point_loader/customer_point_loader_event.dart b/lib/application/customer/customer_point_loader/customer_point_loader_event.dart new file mode 100644 index 0000000..6e45f9c --- /dev/null +++ b/lib/application/customer/customer_point_loader/customer_point_loader_event.dart @@ -0,0 +1,6 @@ +part of 'customer_point_loader_bloc.dart'; + +@freezed +class CustomerPointLoaderEvent with _$CustomerPointLoaderEvent { + const factory CustomerPointLoaderEvent.fetched() = _Fetched; +} diff --git a/lib/application/customer/customer_point_loader/customer_point_loader_state.dart b/lib/application/customer/customer_point_loader/customer_point_loader_state.dart new file mode 100644 index 0000000..b5ab295 --- /dev/null +++ b/lib/application/customer/customer_point_loader/customer_point_loader_state.dart @@ -0,0 +1,15 @@ +part of 'customer_point_loader_bloc.dart'; + +@freezed +class CustomerPointLoaderState with _$CustomerPointLoaderState { + const factory CustomerPointLoaderState({ + required CustomerPoint customerPoint, + required Option failureOptionCustomerPoint, + @Default(false) bool isFetching, + }) = _CustomerPointLoaderState; + + factory CustomerPointLoaderState.initial() => CustomerPointLoaderState( + customerPoint: CustomerPoint.empty(), + failureOptionCustomerPoint: none(), + ); +} diff --git a/lib/common/url/api_path.dart b/lib/common/url/api_path.dart index 7b839fb..6ab7556 100644 --- a/lib/common/url/api_path.dart +++ b/lib/common/url/api_path.dart @@ -8,4 +8,6 @@ class ApiPath { // Marketing static String gamePrizeByGameId = '/api/v1/marketing/game-prizes/game'; + // Customer + static String customerPoint = '/api/v1/customer/points'; } diff --git a/lib/domain/customer/customer.dart b/lib/domain/customer/customer.dart new file mode 100644 index 0000000..571a2d6 --- /dev/null +++ b/lib/domain/customer/customer.dart @@ -0,0 +1,10 @@ +import 'package:dartz/dartz.dart'; +import 'package:freezed_annotation/freezed_annotation.dart'; + +import '../../common/api/api_failure.dart'; + +part 'customer.freezed.dart'; + +part 'entities/customer_point_entity.dart'; +part 'failures/customer_failures.dart'; +part 'repositories/i_customer_repository.dart'; diff --git a/lib/domain/customer/customer.freezed.dart b/lib/domain/customer/customer.freezed.dart new file mode 100644 index 0000000..6ff1ab3 --- /dev/null +++ b/lib/domain/customer/customer.freezed.dart @@ -0,0 +1,713 @@ +// 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 'customer.dart'; + +// ************************************************************************** +// FreezedGenerator +// ************************************************************************** + +T _$identity(T value) => value; + +final _privateConstructorUsedError = UnsupportedError( + 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models', +); + +/// @nodoc +mixin _$CustomerPoint { + String get status => throw _privateConstructorUsedError; + String get message => throw _privateConstructorUsedError; + int get totalPoints => throw _privateConstructorUsedError; + String get lastUpdated => throw _privateConstructorUsedError; + + /// Create a copy of CustomerPoint + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + $CustomerPointCopyWith get copyWith => + throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class $CustomerPointCopyWith<$Res> { + factory $CustomerPointCopyWith( + CustomerPoint value, + $Res Function(CustomerPoint) then, + ) = _$CustomerPointCopyWithImpl<$Res, CustomerPoint>; + @useResult + $Res call({ + String status, + String message, + int totalPoints, + String lastUpdated, + }); +} + +/// @nodoc +class _$CustomerPointCopyWithImpl<$Res, $Val extends CustomerPoint> + implements $CustomerPointCopyWith<$Res> { + _$CustomerPointCopyWithImpl(this._value, this._then); + + // ignore: unused_field + final $Val _value; + // ignore: unused_field + final $Res Function($Val) _then; + + /// Create a copy of CustomerPoint + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? status = null, + Object? message = null, + Object? totalPoints = null, + Object? lastUpdated = null, + }) { + return _then( + _value.copyWith( + status: null == status + ? _value.status + : status // ignore: cast_nullable_to_non_nullable + as String, + message: null == message + ? _value.message + : message // ignore: cast_nullable_to_non_nullable + as String, + totalPoints: null == totalPoints + ? _value.totalPoints + : totalPoints // ignore: cast_nullable_to_non_nullable + as int, + lastUpdated: null == lastUpdated + ? _value.lastUpdated + : lastUpdated // ignore: cast_nullable_to_non_nullable + as String, + ) + as $Val, + ); + } +} + +/// @nodoc +abstract class _$$CustomerPointImplCopyWith<$Res> + implements $CustomerPointCopyWith<$Res> { + factory _$$CustomerPointImplCopyWith( + _$CustomerPointImpl value, + $Res Function(_$CustomerPointImpl) then, + ) = __$$CustomerPointImplCopyWithImpl<$Res>; + @override + @useResult + $Res call({ + String status, + String message, + int totalPoints, + String lastUpdated, + }); +} + +/// @nodoc +class __$$CustomerPointImplCopyWithImpl<$Res> + extends _$CustomerPointCopyWithImpl<$Res, _$CustomerPointImpl> + implements _$$CustomerPointImplCopyWith<$Res> { + __$$CustomerPointImplCopyWithImpl( + _$CustomerPointImpl _value, + $Res Function(_$CustomerPointImpl) _then, + ) : super(_value, _then); + + /// Create a copy of CustomerPoint + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? status = null, + Object? message = null, + Object? totalPoints = null, + Object? lastUpdated = null, + }) { + return _then( + _$CustomerPointImpl( + status: null == status + ? _value.status + : status // ignore: cast_nullable_to_non_nullable + as String, + message: null == message + ? _value.message + : message // ignore: cast_nullable_to_non_nullable + as String, + totalPoints: null == totalPoints + ? _value.totalPoints + : totalPoints // ignore: cast_nullable_to_non_nullable + as int, + lastUpdated: null == lastUpdated + ? _value.lastUpdated + : lastUpdated // ignore: cast_nullable_to_non_nullable + as String, + ), + ); + } +} + +/// @nodoc + +class _$CustomerPointImpl implements _CustomerPoint { + const _$CustomerPointImpl({ + required this.status, + required this.message, + required this.totalPoints, + required this.lastUpdated, + }); + + @override + final String status; + @override + final String message; + @override + final int totalPoints; + @override + final String lastUpdated; + + @override + String toString() { + return 'CustomerPoint(status: $status, message: $message, totalPoints: $totalPoints, lastUpdated: $lastUpdated)'; + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _$CustomerPointImpl && + (identical(other.status, status) || other.status == status) && + (identical(other.message, message) || other.message == message) && + (identical(other.totalPoints, totalPoints) || + other.totalPoints == totalPoints) && + (identical(other.lastUpdated, lastUpdated) || + other.lastUpdated == lastUpdated)); + } + + @override + int get hashCode => + Object.hash(runtimeType, status, message, totalPoints, lastUpdated); + + /// Create a copy of CustomerPoint + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + @override + @pragma('vm:prefer-inline') + _$$CustomerPointImplCopyWith<_$CustomerPointImpl> get copyWith => + __$$CustomerPointImplCopyWithImpl<_$CustomerPointImpl>(this, _$identity); +} + +abstract class _CustomerPoint implements CustomerPoint { + const factory _CustomerPoint({ + required final String status, + required final String message, + required final int totalPoints, + required final String lastUpdated, + }) = _$CustomerPointImpl; + + @override + String get status; + @override + String get message; + @override + int get totalPoints; + @override + String get lastUpdated; + + /// Create a copy of CustomerPoint + /// with the given fields replaced by the non-null parameter values. + @override + @JsonKey(includeFromJson: false, includeToJson: false) + _$$CustomerPointImplCopyWith<_$CustomerPointImpl> get copyWith => + throw _privateConstructorUsedError; +} + +/// @nodoc +mixin _$CustomerFailure { + @optionalTypeArgs + TResult when({ + required TResult Function(ApiFailure failure) serverError, + required TResult Function() unexpectedError, + required TResult Function(String erroMessage) dynamicErrorMessage, + }) => throw _privateConstructorUsedError; + @optionalTypeArgs + TResult? whenOrNull({ + TResult? Function(ApiFailure failure)? serverError, + TResult? Function()? unexpectedError, + TResult? Function(String erroMessage)? dynamicErrorMessage, + }) => throw _privateConstructorUsedError; + @optionalTypeArgs + TResult maybeWhen({ + TResult Function(ApiFailure failure)? serverError, + TResult Function()? unexpectedError, + TResult Function(String erroMessage)? dynamicErrorMessage, + required TResult orElse(), + }) => throw _privateConstructorUsedError; + @optionalTypeArgs + TResult map({ + required TResult Function(_ServerError value) serverError, + required TResult Function(_UnexpectedError value) unexpectedError, + required TResult Function(_DynamicErrorMessage value) dynamicErrorMessage, + }) => throw _privateConstructorUsedError; + @optionalTypeArgs + TResult? mapOrNull({ + TResult? Function(_ServerError value)? serverError, + TResult? Function(_UnexpectedError value)? unexpectedError, + TResult? Function(_DynamicErrorMessage value)? dynamicErrorMessage, + }) => throw _privateConstructorUsedError; + @optionalTypeArgs + TResult maybeMap({ + TResult Function(_ServerError value)? serverError, + TResult Function(_UnexpectedError value)? unexpectedError, + TResult Function(_DynamicErrorMessage value)? dynamicErrorMessage, + required TResult orElse(), + }) => throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class $CustomerFailureCopyWith<$Res> { + factory $CustomerFailureCopyWith( + CustomerFailure value, + $Res Function(CustomerFailure) then, + ) = _$CustomerFailureCopyWithImpl<$Res, CustomerFailure>; +} + +/// @nodoc +class _$CustomerFailureCopyWithImpl<$Res, $Val extends CustomerFailure> + implements $CustomerFailureCopyWith<$Res> { + _$CustomerFailureCopyWithImpl(this._value, this._then); + + // ignore: unused_field + final $Val _value; + // ignore: unused_field + final $Res Function($Val) _then; + + /// Create a copy of CustomerFailure + /// with the given fields replaced by the non-null parameter values. +} + +/// @nodoc +abstract class _$$ServerErrorImplCopyWith<$Res> { + factory _$$ServerErrorImplCopyWith( + _$ServerErrorImpl value, + $Res Function(_$ServerErrorImpl) then, + ) = __$$ServerErrorImplCopyWithImpl<$Res>; + @useResult + $Res call({ApiFailure failure}); + + $ApiFailureCopyWith<$Res> get failure; +} + +/// @nodoc +class __$$ServerErrorImplCopyWithImpl<$Res> + extends _$CustomerFailureCopyWithImpl<$Res, _$ServerErrorImpl> + implements _$$ServerErrorImplCopyWith<$Res> { + __$$ServerErrorImplCopyWithImpl( + _$ServerErrorImpl _value, + $Res Function(_$ServerErrorImpl) _then, + ) : super(_value, _then); + + /// Create a copy of CustomerFailure + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({Object? failure = null}) { + return _then( + _$ServerErrorImpl( + null == failure + ? _value.failure + : failure // ignore: cast_nullable_to_non_nullable + as ApiFailure, + ), + ); + } + + /// Create a copy of CustomerFailure + /// with the given fields replaced by the non-null parameter values. + @override + @pragma('vm:prefer-inline') + $ApiFailureCopyWith<$Res> get failure { + return $ApiFailureCopyWith<$Res>(_value.failure, (value) { + return _then(_value.copyWith(failure: value)); + }); + } +} + +/// @nodoc + +class _$ServerErrorImpl implements _ServerError { + const _$ServerErrorImpl(this.failure); + + @override + final ApiFailure failure; + + @override + String toString() { + return 'CustomerFailure.serverError(failure: $failure)'; + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _$ServerErrorImpl && + (identical(other.failure, failure) || other.failure == failure)); + } + + @override + int get hashCode => Object.hash(runtimeType, failure); + + /// Create a copy of CustomerFailure + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + @override + @pragma('vm:prefer-inline') + _$$ServerErrorImplCopyWith<_$ServerErrorImpl> get copyWith => + __$$ServerErrorImplCopyWithImpl<_$ServerErrorImpl>(this, _$identity); + + @override + @optionalTypeArgs + TResult when({ + required TResult Function(ApiFailure failure) serverError, + required TResult Function() unexpectedError, + required TResult Function(String erroMessage) dynamicErrorMessage, + }) { + return serverError(failure); + } + + @override + @optionalTypeArgs + TResult? whenOrNull({ + TResult? Function(ApiFailure failure)? serverError, + TResult? Function()? unexpectedError, + TResult? Function(String erroMessage)? dynamicErrorMessage, + }) { + return serverError?.call(failure); + } + + @override + @optionalTypeArgs + TResult maybeWhen({ + TResult Function(ApiFailure failure)? serverError, + TResult Function()? unexpectedError, + TResult Function(String erroMessage)? dynamicErrorMessage, + required TResult orElse(), + }) { + if (serverError != null) { + return serverError(failure); + } + return orElse(); + } + + @override + @optionalTypeArgs + TResult map({ + required TResult Function(_ServerError value) serverError, + required TResult Function(_UnexpectedError value) unexpectedError, + required TResult Function(_DynamicErrorMessage value) dynamicErrorMessage, + }) { + return serverError(this); + } + + @override + @optionalTypeArgs + TResult? mapOrNull({ + TResult? Function(_ServerError value)? serverError, + TResult? Function(_UnexpectedError value)? unexpectedError, + TResult? Function(_DynamicErrorMessage value)? dynamicErrorMessage, + }) { + return serverError?.call(this); + } + + @override + @optionalTypeArgs + TResult maybeMap({ + TResult Function(_ServerError value)? serverError, + TResult Function(_UnexpectedError value)? unexpectedError, + TResult Function(_DynamicErrorMessage value)? dynamicErrorMessage, + required TResult orElse(), + }) { + if (serverError != null) { + return serverError(this); + } + return orElse(); + } +} + +abstract class _ServerError implements CustomerFailure { + const factory _ServerError(final ApiFailure failure) = _$ServerErrorImpl; + + ApiFailure get failure; + + /// Create a copy of CustomerFailure + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + _$$ServerErrorImplCopyWith<_$ServerErrorImpl> get copyWith => + throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class _$$UnexpectedErrorImplCopyWith<$Res> { + factory _$$UnexpectedErrorImplCopyWith( + _$UnexpectedErrorImpl value, + $Res Function(_$UnexpectedErrorImpl) then, + ) = __$$UnexpectedErrorImplCopyWithImpl<$Res>; +} + +/// @nodoc +class __$$UnexpectedErrorImplCopyWithImpl<$Res> + extends _$CustomerFailureCopyWithImpl<$Res, _$UnexpectedErrorImpl> + implements _$$UnexpectedErrorImplCopyWith<$Res> { + __$$UnexpectedErrorImplCopyWithImpl( + _$UnexpectedErrorImpl _value, + $Res Function(_$UnexpectedErrorImpl) _then, + ) : super(_value, _then); + + /// Create a copy of CustomerFailure + /// with the given fields replaced by the non-null parameter values. +} + +/// @nodoc + +class _$UnexpectedErrorImpl implements _UnexpectedError { + const _$UnexpectedErrorImpl(); + + @override + String toString() { + return 'CustomerFailure.unexpectedError()'; + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && other is _$UnexpectedErrorImpl); + } + + @override + int get hashCode => runtimeType.hashCode; + + @override + @optionalTypeArgs + TResult when({ + required TResult Function(ApiFailure failure) serverError, + required TResult Function() unexpectedError, + required TResult Function(String erroMessage) dynamicErrorMessage, + }) { + return unexpectedError(); + } + + @override + @optionalTypeArgs + TResult? whenOrNull({ + TResult? Function(ApiFailure failure)? serverError, + TResult? Function()? unexpectedError, + TResult? Function(String erroMessage)? dynamicErrorMessage, + }) { + return unexpectedError?.call(); + } + + @override + @optionalTypeArgs + TResult maybeWhen({ + TResult Function(ApiFailure failure)? serverError, + TResult Function()? unexpectedError, + TResult Function(String erroMessage)? dynamicErrorMessage, + required TResult orElse(), + }) { + if (unexpectedError != null) { + return unexpectedError(); + } + return orElse(); + } + + @override + @optionalTypeArgs + TResult map({ + required TResult Function(_ServerError value) serverError, + required TResult Function(_UnexpectedError value) unexpectedError, + required TResult Function(_DynamicErrorMessage value) dynamicErrorMessage, + }) { + return unexpectedError(this); + } + + @override + @optionalTypeArgs + TResult? mapOrNull({ + TResult? Function(_ServerError value)? serverError, + TResult? Function(_UnexpectedError value)? unexpectedError, + TResult? Function(_DynamicErrorMessage value)? dynamicErrorMessage, + }) { + return unexpectedError?.call(this); + } + + @override + @optionalTypeArgs + TResult maybeMap({ + TResult Function(_ServerError value)? serverError, + TResult Function(_UnexpectedError value)? unexpectedError, + TResult Function(_DynamicErrorMessage value)? dynamicErrorMessage, + required TResult orElse(), + }) { + if (unexpectedError != null) { + return unexpectedError(this); + } + return orElse(); + } +} + +abstract class _UnexpectedError implements CustomerFailure { + const factory _UnexpectedError() = _$UnexpectedErrorImpl; +} + +/// @nodoc +abstract class _$$DynamicErrorMessageImplCopyWith<$Res> { + factory _$$DynamicErrorMessageImplCopyWith( + _$DynamicErrorMessageImpl value, + $Res Function(_$DynamicErrorMessageImpl) then, + ) = __$$DynamicErrorMessageImplCopyWithImpl<$Res>; + @useResult + $Res call({String erroMessage}); +} + +/// @nodoc +class __$$DynamicErrorMessageImplCopyWithImpl<$Res> + extends _$CustomerFailureCopyWithImpl<$Res, _$DynamicErrorMessageImpl> + implements _$$DynamicErrorMessageImplCopyWith<$Res> { + __$$DynamicErrorMessageImplCopyWithImpl( + _$DynamicErrorMessageImpl _value, + $Res Function(_$DynamicErrorMessageImpl) _then, + ) : super(_value, _then); + + /// Create a copy of CustomerFailure + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({Object? erroMessage = null}) { + return _then( + _$DynamicErrorMessageImpl( + null == erroMessage + ? _value.erroMessage + : erroMessage // ignore: cast_nullable_to_non_nullable + as String, + ), + ); + } +} + +/// @nodoc + +class _$DynamicErrorMessageImpl implements _DynamicErrorMessage { + const _$DynamicErrorMessageImpl(this.erroMessage); + + @override + final String erroMessage; + + @override + String toString() { + return 'CustomerFailure.dynamicErrorMessage(erroMessage: $erroMessage)'; + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _$DynamicErrorMessageImpl && + (identical(other.erroMessage, erroMessage) || + other.erroMessage == erroMessage)); + } + + @override + int get hashCode => Object.hash(runtimeType, erroMessage); + + /// Create a copy of CustomerFailure + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + @override + @pragma('vm:prefer-inline') + _$$DynamicErrorMessageImplCopyWith<_$DynamicErrorMessageImpl> get copyWith => + __$$DynamicErrorMessageImplCopyWithImpl<_$DynamicErrorMessageImpl>( + this, + _$identity, + ); + + @override + @optionalTypeArgs + TResult when({ + required TResult Function(ApiFailure failure) serverError, + required TResult Function() unexpectedError, + required TResult Function(String erroMessage) dynamicErrorMessage, + }) { + return dynamicErrorMessage(erroMessage); + } + + @override + @optionalTypeArgs + TResult? whenOrNull({ + TResult? Function(ApiFailure failure)? serverError, + TResult? Function()? unexpectedError, + TResult? Function(String erroMessage)? dynamicErrorMessage, + }) { + return dynamicErrorMessage?.call(erroMessage); + } + + @override + @optionalTypeArgs + TResult maybeWhen({ + TResult Function(ApiFailure failure)? serverError, + TResult Function()? unexpectedError, + TResult Function(String erroMessage)? dynamicErrorMessage, + required TResult orElse(), + }) { + if (dynamicErrorMessage != null) { + return dynamicErrorMessage(erroMessage); + } + return orElse(); + } + + @override + @optionalTypeArgs + TResult map({ + required TResult Function(_ServerError value) serverError, + required TResult Function(_UnexpectedError value) unexpectedError, + required TResult Function(_DynamicErrorMessage value) dynamicErrorMessage, + }) { + return dynamicErrorMessage(this); + } + + @override + @optionalTypeArgs + TResult? mapOrNull({ + TResult? Function(_ServerError value)? serverError, + TResult? Function(_UnexpectedError value)? unexpectedError, + TResult? Function(_DynamicErrorMessage value)? dynamicErrorMessage, + }) { + return dynamicErrorMessage?.call(this); + } + + @override + @optionalTypeArgs + TResult maybeMap({ + TResult Function(_ServerError value)? serverError, + TResult Function(_UnexpectedError value)? unexpectedError, + TResult Function(_DynamicErrorMessage value)? dynamicErrorMessage, + required TResult orElse(), + }) { + if (dynamicErrorMessage != null) { + return dynamicErrorMessage(this); + } + return orElse(); + } +} + +abstract class _DynamicErrorMessage implements CustomerFailure { + const factory _DynamicErrorMessage(final String erroMessage) = + _$DynamicErrorMessageImpl; + + String get erroMessage; + + /// Create a copy of CustomerFailure + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + _$$DynamicErrorMessageImplCopyWith<_$DynamicErrorMessageImpl> get copyWith => + throw _privateConstructorUsedError; +} diff --git a/lib/domain/customer/entities/customer_point_entity.dart b/lib/domain/customer/entities/customer_point_entity.dart new file mode 100644 index 0000000..fc1750e --- /dev/null +++ b/lib/domain/customer/entities/customer_point_entity.dart @@ -0,0 +1,18 @@ +part of '../customer.dart'; + +@freezed +class CustomerPoint with _$CustomerPoint { + const factory CustomerPoint({ + required String status, + required String message, + required int totalPoints, + required String lastUpdated, + }) = _CustomerPoint; + + factory CustomerPoint.empty() => const CustomerPoint( + status: '', + message: '', + totalPoints: 0, + lastUpdated: '', + ); +} diff --git a/lib/domain/customer/failures/customer_failures.dart b/lib/domain/customer/failures/customer_failures.dart new file mode 100644 index 0000000..e4459ba --- /dev/null +++ b/lib/domain/customer/failures/customer_failures.dart @@ -0,0 +1,9 @@ +part of '../customer.dart'; + +@freezed +sealed class CustomerFailure with _$CustomerFailure { + const factory CustomerFailure.serverError(ApiFailure failure) = _ServerError; + const factory CustomerFailure.unexpectedError() = _UnexpectedError; + const factory CustomerFailure.dynamicErrorMessage(String erroMessage) = + _DynamicErrorMessage; +} diff --git a/lib/domain/customer/repositories/i_customer_repository.dart b/lib/domain/customer/repositories/i_customer_repository.dart new file mode 100644 index 0000000..618a473 --- /dev/null +++ b/lib/domain/customer/repositories/i_customer_repository.dart @@ -0,0 +1,5 @@ +part of '../customer.dart'; + +abstract class ICustomerRepository { + Future> getPoints(); +} diff --git a/lib/infrastructure/customer/customer_dtos.dart b/lib/infrastructure/customer/customer_dtos.dart new file mode 100644 index 0000000..c53f3ec --- /dev/null +++ b/lib/infrastructure/customer/customer_dtos.dart @@ -0,0 +1,8 @@ +import 'package:freezed_annotation/freezed_annotation.dart'; + +import '../../domain/customer/customer.dart'; + +part 'customer_dtos.freezed.dart'; +part 'customer_dtos.g.dart'; + +part 'dtos/customer_point_dto.dart'; diff --git a/lib/infrastructure/customer/customer_dtos.freezed.dart b/lib/infrastructure/customer/customer_dtos.freezed.dart new file mode 100644 index 0000000..86a7403 --- /dev/null +++ b/lib/infrastructure/customer/customer_dtos.freezed.dart @@ -0,0 +1,443 @@ +// 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 'customer_dtos.dart'; + +// ************************************************************************** +// FreezedGenerator +// ************************************************************************** + +T _$identity(T value) => value; + +final _privateConstructorUsedError = UnsupportedError( + 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models', +); + +CustomerPointDto _$CustomerPointDtoFromJson(Map json) { + return _CustomerPointDto.fromJson(json); +} + +/// @nodoc +mixin _$CustomerPointDto { + @JsonKey(name: 'status') + String? get status => throw _privateConstructorUsedError; + @JsonKey(name: 'message') + String? get message => throw _privateConstructorUsedError; + @JsonKey(name: 'data') + CustomerPointDataDto? get data => throw _privateConstructorUsedError; + + /// Serializes this CustomerPointDto to a JSON map. + Map toJson() => throw _privateConstructorUsedError; + + /// Create a copy of CustomerPointDto + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + $CustomerPointDtoCopyWith get copyWith => + throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class $CustomerPointDtoCopyWith<$Res> { + factory $CustomerPointDtoCopyWith( + CustomerPointDto value, + $Res Function(CustomerPointDto) then, + ) = _$CustomerPointDtoCopyWithImpl<$Res, CustomerPointDto>; + @useResult + $Res call({ + @JsonKey(name: 'status') String? status, + @JsonKey(name: 'message') String? message, + @JsonKey(name: 'data') CustomerPointDataDto? data, + }); + + $CustomerPointDataDtoCopyWith<$Res>? get data; +} + +/// @nodoc +class _$CustomerPointDtoCopyWithImpl<$Res, $Val extends CustomerPointDto> + implements $CustomerPointDtoCopyWith<$Res> { + _$CustomerPointDtoCopyWithImpl(this._value, this._then); + + // ignore: unused_field + final $Val _value; + // ignore: unused_field + final $Res Function($Val) _then; + + /// Create a copy of CustomerPointDto + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? status = freezed, + Object? message = freezed, + Object? data = freezed, + }) { + return _then( + _value.copyWith( + status: freezed == status + ? _value.status + : status // ignore: cast_nullable_to_non_nullable + as String?, + message: freezed == message + ? _value.message + : message // ignore: cast_nullable_to_non_nullable + as String?, + data: freezed == data + ? _value.data + : data // ignore: cast_nullable_to_non_nullable + as CustomerPointDataDto?, + ) + as $Val, + ); + } + + /// Create a copy of CustomerPointDto + /// with the given fields replaced by the non-null parameter values. + @override + @pragma('vm:prefer-inline') + $CustomerPointDataDtoCopyWith<$Res>? get data { + if (_value.data == null) { + return null; + } + + return $CustomerPointDataDtoCopyWith<$Res>(_value.data!, (value) { + return _then(_value.copyWith(data: value) as $Val); + }); + } +} + +/// @nodoc +abstract class _$$CustomerPointDtoImplCopyWith<$Res> + implements $CustomerPointDtoCopyWith<$Res> { + factory _$$CustomerPointDtoImplCopyWith( + _$CustomerPointDtoImpl value, + $Res Function(_$CustomerPointDtoImpl) then, + ) = __$$CustomerPointDtoImplCopyWithImpl<$Res>; + @override + @useResult + $Res call({ + @JsonKey(name: 'status') String? status, + @JsonKey(name: 'message') String? message, + @JsonKey(name: 'data') CustomerPointDataDto? data, + }); + + @override + $CustomerPointDataDtoCopyWith<$Res>? get data; +} + +/// @nodoc +class __$$CustomerPointDtoImplCopyWithImpl<$Res> + extends _$CustomerPointDtoCopyWithImpl<$Res, _$CustomerPointDtoImpl> + implements _$$CustomerPointDtoImplCopyWith<$Res> { + __$$CustomerPointDtoImplCopyWithImpl( + _$CustomerPointDtoImpl _value, + $Res Function(_$CustomerPointDtoImpl) _then, + ) : super(_value, _then); + + /// Create a copy of CustomerPointDto + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? status = freezed, + Object? message = freezed, + Object? data = freezed, + }) { + return _then( + _$CustomerPointDtoImpl( + status: freezed == status + ? _value.status + : status // ignore: cast_nullable_to_non_nullable + as String?, + message: freezed == message + ? _value.message + : message // ignore: cast_nullable_to_non_nullable + as String?, + data: freezed == data + ? _value.data + : data // ignore: cast_nullable_to_non_nullable + as CustomerPointDataDto?, + ), + ); + } +} + +/// @nodoc +@JsonSerializable() +class _$CustomerPointDtoImpl extends _CustomerPointDto { + const _$CustomerPointDtoImpl({ + @JsonKey(name: 'status') this.status, + @JsonKey(name: 'message') this.message, + @JsonKey(name: 'data') this.data, + }) : super._(); + + factory _$CustomerPointDtoImpl.fromJson(Map json) => + _$$CustomerPointDtoImplFromJson(json); + + @override + @JsonKey(name: 'status') + final String? status; + @override + @JsonKey(name: 'message') + final String? message; + @override + @JsonKey(name: 'data') + final CustomerPointDataDto? data; + + @override + String toString() { + return 'CustomerPointDto(status: $status, message: $message, data: $data)'; + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _$CustomerPointDtoImpl && + (identical(other.status, status) || other.status == status) && + (identical(other.message, message) || other.message == message) && + (identical(other.data, data) || other.data == data)); + } + + @JsonKey(includeFromJson: false, includeToJson: false) + @override + int get hashCode => Object.hash(runtimeType, status, message, data); + + /// Create a copy of CustomerPointDto + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + @override + @pragma('vm:prefer-inline') + _$$CustomerPointDtoImplCopyWith<_$CustomerPointDtoImpl> get copyWith => + __$$CustomerPointDtoImplCopyWithImpl<_$CustomerPointDtoImpl>( + this, + _$identity, + ); + + @override + Map toJson() { + return _$$CustomerPointDtoImplToJson(this); + } +} + +abstract class _CustomerPointDto extends CustomerPointDto { + const factory _CustomerPointDto({ + @JsonKey(name: 'status') final String? status, + @JsonKey(name: 'message') final String? message, + @JsonKey(name: 'data') final CustomerPointDataDto? data, + }) = _$CustomerPointDtoImpl; + const _CustomerPointDto._() : super._(); + + factory _CustomerPointDto.fromJson(Map json) = + _$CustomerPointDtoImpl.fromJson; + + @override + @JsonKey(name: 'status') + String? get status; + @override + @JsonKey(name: 'message') + String? get message; + @override + @JsonKey(name: 'data') + CustomerPointDataDto? get data; + + /// Create a copy of CustomerPointDto + /// with the given fields replaced by the non-null parameter values. + @override + @JsonKey(includeFromJson: false, includeToJson: false) + _$$CustomerPointDtoImplCopyWith<_$CustomerPointDtoImpl> get copyWith => + throw _privateConstructorUsedError; +} + +CustomerPointDataDto _$CustomerPointDataDtoFromJson(Map json) { + return _CustomerPointDataDto.fromJson(json); +} + +/// @nodoc +mixin _$CustomerPointDataDto { + @JsonKey(name: 'total_points') + int? get totalPoints => throw _privateConstructorUsedError; + @JsonKey(name: 'last_updated') + String? get lastUpdated => throw _privateConstructorUsedError; + + /// Serializes this CustomerPointDataDto to a JSON map. + Map toJson() => throw _privateConstructorUsedError; + + /// Create a copy of CustomerPointDataDto + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + $CustomerPointDataDtoCopyWith get copyWith => + throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class $CustomerPointDataDtoCopyWith<$Res> { + factory $CustomerPointDataDtoCopyWith( + CustomerPointDataDto value, + $Res Function(CustomerPointDataDto) then, + ) = _$CustomerPointDataDtoCopyWithImpl<$Res, CustomerPointDataDto>; + @useResult + $Res call({ + @JsonKey(name: 'total_points') int? totalPoints, + @JsonKey(name: 'last_updated') String? lastUpdated, + }); +} + +/// @nodoc +class _$CustomerPointDataDtoCopyWithImpl< + $Res, + $Val extends CustomerPointDataDto +> + implements $CustomerPointDataDtoCopyWith<$Res> { + _$CustomerPointDataDtoCopyWithImpl(this._value, this._then); + + // ignore: unused_field + final $Val _value; + // ignore: unused_field + final $Res Function($Val) _then; + + /// Create a copy of CustomerPointDataDto + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({Object? totalPoints = freezed, Object? lastUpdated = freezed}) { + return _then( + _value.copyWith( + totalPoints: freezed == totalPoints + ? _value.totalPoints + : totalPoints // ignore: cast_nullable_to_non_nullable + as int?, + lastUpdated: freezed == lastUpdated + ? _value.lastUpdated + : lastUpdated // ignore: cast_nullable_to_non_nullable + as String?, + ) + as $Val, + ); + } +} + +/// @nodoc +abstract class _$$CustomerPointDataDtoImplCopyWith<$Res> + implements $CustomerPointDataDtoCopyWith<$Res> { + factory _$$CustomerPointDataDtoImplCopyWith( + _$CustomerPointDataDtoImpl value, + $Res Function(_$CustomerPointDataDtoImpl) then, + ) = __$$CustomerPointDataDtoImplCopyWithImpl<$Res>; + @override + @useResult + $Res call({ + @JsonKey(name: 'total_points') int? totalPoints, + @JsonKey(name: 'last_updated') String? lastUpdated, + }); +} + +/// @nodoc +class __$$CustomerPointDataDtoImplCopyWithImpl<$Res> + extends _$CustomerPointDataDtoCopyWithImpl<$Res, _$CustomerPointDataDtoImpl> + implements _$$CustomerPointDataDtoImplCopyWith<$Res> { + __$$CustomerPointDataDtoImplCopyWithImpl( + _$CustomerPointDataDtoImpl _value, + $Res Function(_$CustomerPointDataDtoImpl) _then, + ) : super(_value, _then); + + /// Create a copy of CustomerPointDataDto + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({Object? totalPoints = freezed, Object? lastUpdated = freezed}) { + return _then( + _$CustomerPointDataDtoImpl( + totalPoints: freezed == totalPoints + ? _value.totalPoints + : totalPoints // ignore: cast_nullable_to_non_nullable + as int?, + lastUpdated: freezed == lastUpdated + ? _value.lastUpdated + : lastUpdated // ignore: cast_nullable_to_non_nullable + as String?, + ), + ); + } +} + +/// @nodoc +@JsonSerializable() +class _$CustomerPointDataDtoImpl implements _CustomerPointDataDto { + const _$CustomerPointDataDtoImpl({ + @JsonKey(name: 'total_points') this.totalPoints, + @JsonKey(name: 'last_updated') this.lastUpdated, + }); + + factory _$CustomerPointDataDtoImpl.fromJson(Map json) => + _$$CustomerPointDataDtoImplFromJson(json); + + @override + @JsonKey(name: 'total_points') + final int? totalPoints; + @override + @JsonKey(name: 'last_updated') + final String? lastUpdated; + + @override + String toString() { + return 'CustomerPointDataDto(totalPoints: $totalPoints, lastUpdated: $lastUpdated)'; + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _$CustomerPointDataDtoImpl && + (identical(other.totalPoints, totalPoints) || + other.totalPoints == totalPoints) && + (identical(other.lastUpdated, lastUpdated) || + other.lastUpdated == lastUpdated)); + } + + @JsonKey(includeFromJson: false, includeToJson: false) + @override + int get hashCode => Object.hash(runtimeType, totalPoints, lastUpdated); + + /// Create a copy of CustomerPointDataDto + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + @override + @pragma('vm:prefer-inline') + _$$CustomerPointDataDtoImplCopyWith<_$CustomerPointDataDtoImpl> + get copyWith => + __$$CustomerPointDataDtoImplCopyWithImpl<_$CustomerPointDataDtoImpl>( + this, + _$identity, + ); + + @override + Map toJson() { + return _$$CustomerPointDataDtoImplToJson(this); + } +} + +abstract class _CustomerPointDataDto implements CustomerPointDataDto { + const factory _CustomerPointDataDto({ + @JsonKey(name: 'total_points') final int? totalPoints, + @JsonKey(name: 'last_updated') final String? lastUpdated, + }) = _$CustomerPointDataDtoImpl; + + factory _CustomerPointDataDto.fromJson(Map json) = + _$CustomerPointDataDtoImpl.fromJson; + + @override + @JsonKey(name: 'total_points') + int? get totalPoints; + @override + @JsonKey(name: 'last_updated') + String? get lastUpdated; + + /// Create a copy of CustomerPointDataDto + /// with the given fields replaced by the non-null parameter values. + @override + @JsonKey(includeFromJson: false, includeToJson: false) + _$$CustomerPointDataDtoImplCopyWith<_$CustomerPointDataDtoImpl> + get copyWith => throw _privateConstructorUsedError; +} diff --git a/lib/infrastructure/customer/customer_dtos.g.dart b/lib/infrastructure/customer/customer_dtos.g.dart new file mode 100644 index 0000000..2a573d1 --- /dev/null +++ b/lib/infrastructure/customer/customer_dtos.g.dart @@ -0,0 +1,39 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'customer_dtos.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +_$CustomerPointDtoImpl _$$CustomerPointDtoImplFromJson( + Map json, +) => _$CustomerPointDtoImpl( + status: json['status'] as String?, + message: json['message'] as String?, + data: json['data'] == null + ? null + : CustomerPointDataDto.fromJson(json['data'] as Map), +); + +Map _$$CustomerPointDtoImplToJson( + _$CustomerPointDtoImpl instance, +) => { + 'status': instance.status, + 'message': instance.message, + 'data': instance.data, +}; + +_$CustomerPointDataDtoImpl _$$CustomerPointDataDtoImplFromJson( + Map json, +) => _$CustomerPointDataDtoImpl( + totalPoints: (json['total_points'] as num?)?.toInt(), + lastUpdated: json['last_updated'] as String?, +); + +Map _$$CustomerPointDataDtoImplToJson( + _$CustomerPointDataDtoImpl instance, +) => { + 'total_points': instance.totalPoints, + 'last_updated': instance.lastUpdated, +}; diff --git a/lib/infrastructure/customer/datasources/remote_data_provider.dart b/lib/infrastructure/customer/datasources/remote_data_provider.dart new file mode 100644 index 0000000..1af9a17 --- /dev/null +++ b/lib/infrastructure/customer/datasources/remote_data_provider.dart @@ -0,0 +1,50 @@ +import 'dart:developer'; + +import 'package:data_channel/data_channel.dart'; +import 'package:injectable/injectable.dart'; + +import '../../../common/api/api_client.dart'; +import '../../../common/api/api_failure.dart'; +import '../../../common/function/app_function.dart'; +import '../../../common/url/api_path.dart'; +import '../../../domain/customer/customer.dart'; +import '../customer_dtos.dart'; + +@injectable +class CustomerRemoteDataProvider { + final ApiClient _apiClient; + final String _logName = "CustomerRemoteDataProvider"; + + CustomerRemoteDataProvider(this._apiClient); + + Future> fetchCustomerPoint() async { + try { + final response = await _apiClient.get( + ApiPath.customerPoint, + headers: getAuthorizationHeader(), + ); + + if (response.data['code'] == 401) { + return DC.error( + CustomerFailure.serverError( + ApiFailure.unauthorized('Session Expired'), + ), + ); + } + + if (response.data['status'] == false) { + return DC.error( + CustomerFailure.dynamicErrorMessage( + 'Terjadi kesalahan coba lagi nanti', + ), + ); + } + + final dto = CustomerPointDto.fromJson(response.data['data']); + return DC.data(dto); + } on ApiFailure catch (e, s) { + log('fetchCustomerPoint', name: _logName, error: e, stackTrace: s); + return DC.error(CustomerFailure.serverError(e)); + } + } +} diff --git a/lib/infrastructure/customer/dtos/customer_point_dto.dart b/lib/infrastructure/customer/dtos/customer_point_dto.dart new file mode 100644 index 0000000..9d9515e --- /dev/null +++ b/lib/infrastructure/customer/dtos/customer_point_dto.dart @@ -0,0 +1,34 @@ +part of '../customer_dtos.dart'; + +@freezed +class CustomerPointDto with _$CustomerPointDto { + const factory CustomerPointDto({ + @JsonKey(name: 'status') String? status, + @JsonKey(name: 'message') String? message, + @JsonKey(name: 'data') CustomerPointDataDto? data, + }) = _CustomerPointDto; + + factory CustomerPointDto.fromJson(Map json) => + _$CustomerPointDtoFromJson(json); + + const CustomerPointDto._(); + + /// mapping ke domain + CustomerPoint toDomain() => CustomerPoint( + status: status ?? '', + message: message ?? '', + totalPoints: data?.totalPoints ?? 0, + lastUpdated: data?.lastUpdated ?? '', + ); +} + +@freezed +class CustomerPointDataDto with _$CustomerPointDataDto { + const factory CustomerPointDataDto({ + @JsonKey(name: 'total_points') int? totalPoints, + @JsonKey(name: 'last_updated') String? lastUpdated, + }) = _CustomerPointDataDto; + + factory CustomerPointDataDto.fromJson(Map json) => + _$CustomerPointDataDtoFromJson(json); +} diff --git a/lib/infrastructure/customer/repositories/customer_repository.dart b/lib/infrastructure/customer/repositories/customer_repository.dart new file mode 100644 index 0000000..18cebfe --- /dev/null +++ b/lib/infrastructure/customer/repositories/customer_repository.dart @@ -0,0 +1,33 @@ +import 'dart:developer'; + +import 'package:dartz/dartz.dart'; +import 'package:injectable/injectable.dart'; + +import '../../../domain/customer/customer.dart'; +import '../datasources/remote_data_provider.dart'; + +@Injectable(as: ICustomerRepository) +class CustomerRepository implements ICustomerRepository { + final CustomerRemoteDataProvider _remoteDataProvider; + + final String _logName = 'CustomerRepository'; + + CustomerRepository(this._remoteDataProvider); + + @override + Future> getPoints() async { + try { + final result = await _remoteDataProvider.fetchCustomerPoint(); + + if (result.hasError) { + return left(result.error!); + } + + final data = result.data!.toDomain(); + return right(data); + } catch (e, s) { + log('getPoints', name: _logName, error: e, stackTrace: s); + return left(const CustomerFailure.unexpectedError()); + } + } +} diff --git a/lib/injection.config.dart b/lib/injection.config.dart index 4d195d5..ded36e4 100644 --- a/lib/injection.config.dart +++ b/lib/injection.config.dart @@ -26,6 +26,8 @@ import 'package:enaklo/application/auth/set_password/set_password_form_bloc.dart as _i174; import 'package:enaklo/application/auth/verify_form/verify_form_bloc.dart' as _i521; +import 'package:enaklo/application/customer/customer_point_loader/customer_point_loader_bloc.dart' + as _i497; import 'package:enaklo/application/game/game_price_loader/game_prize_loader_bloc.dart' as _i925; import 'package:enaklo/common/api/api_client.dart' as _i842; @@ -35,6 +37,7 @@ import 'package:enaklo/common/di/di_dio.dart' as _i842; import 'package:enaklo/common/di/di_shared_preferences.dart' as _i672; import 'package:enaklo/common/network/network_client.dart' as _i109; import 'package:enaklo/domain/auth/auth.dart' as _i995; +import 'package:enaklo/domain/customer/customer.dart' as _i898; import 'package:enaklo/domain/game/game.dart' as _i96; import 'package:enaklo/env.dart' as _i372; import 'package:enaklo/infrastructure/auth/datasources/local_data_provider.dart' @@ -43,6 +46,10 @@ import 'package:enaklo/infrastructure/auth/datasources/remote_data_provider.dart as _i818; import 'package:enaklo/infrastructure/auth/repositories/auth_repository.dart' as _i879; +import 'package:enaklo/infrastructure/customer/datasources/remote_data_provider.dart' + as _i89; +import 'package:enaklo/infrastructure/customer/repositories/customer_repository.dart' + as _i118; import 'package:enaklo/infrastructure/game/datasources/remote_data_provider.dart' as _i143; import 'package:enaklo/infrastructure/game/repositories/game_repository.dart' @@ -90,6 +97,9 @@ extension GetItInjectableX on _i174.GetIt { gh.factory<_i143.GameRemoteDataProvider>( () => _i143.GameRemoteDataProvider(gh<_i842.ApiClient>()), ); + gh.factory<_i89.CustomerRemoteDataProvider>( + () => _i89.CustomerRemoteDataProvider(gh<_i842.ApiClient>()), + ); gh.factory<_i96.IGameRepository>( () => _i547.GameRepository(gh<_i143.GameRemoteDataProvider>()), ); @@ -123,9 +133,15 @@ extension GetItInjectableX on _i174.GetIt { gh.factory<_i216.LogoutFormBloc>( () => _i216.LogoutFormBloc(gh<_i995.IAuthRepository>()), ); + gh.factory<_i898.ICustomerRepository>( + () => _i118.CustomerRepository(gh<_i89.CustomerRemoteDataProvider>()), + ); gh.factory<_i510.LoginFormBloc>( () => _i510.LoginFormBloc(gh<_i995.IAuthRepository>()), ); + gh.factory<_i497.CustomerPointLoaderBloc>( + () => _i497.CustomerPointLoaderBloc(gh<_i898.ICustomerRepository>()), + ); return this; } } diff --git a/lib/presentation/app_widget.dart b/lib/presentation/app_widget.dart index fec381f..049e39a 100644 --- a/lib/presentation/app_widget.dart +++ b/lib/presentation/app_widget.dart @@ -3,6 +3,7 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import '../application/auth/auth_bloc.dart'; import '../application/auth/logout_form/logout_form_bloc.dart'; +import '../application/customer/customer_point_loader/customer_point_loader_bloc.dart'; import '../common/theme/theme.dart'; import '../common/constant/app_constant.dart'; import '../injection.dart'; @@ -25,6 +26,7 @@ class _AppWidgetState extends State { providers: [ BlocProvider(create: (context) => getIt()), BlocProvider(create: (context) => getIt()), + BlocProvider(create: (context) => getIt()), ], child: MaterialApp.router( debugShowCheckedModeBanner: false, diff --git a/lib/presentation/pages/main/pages/home/home_page.dart b/lib/presentation/pages/main/pages/home/home_page.dart index 7f8db99..d92a23c 100644 --- a/lib/presentation/pages/main/pages/home/home_page.dart +++ b/lib/presentation/pages/main/pages/home/home_page.dart @@ -1,7 +1,10 @@ import 'package:auto_route/auto_route.dart'; import 'package:flutter/material.dart'; import 'package:carousel_slider/carousel_slider.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import '../../../../../application/auth/auth_bloc.dart'; +import '../../../../../application/customer/customer_point_loader/customer_point_loader_bloc.dart'; import '../../../../../common/theme/theme.dart'; import '../../../../components/image/image.dart'; import '../../../../router/app_router.gr.dart'; @@ -30,6 +33,16 @@ class _HomePageState extends State { 'https://images.unsplash.com/photo-1574848794584-c740d6a5595f?w=800&h=400&fit=crop', ]; + @override + void initState() { + super.initState(); + if (context.read().state.isAuthenticated) { + context.read().add( + CustomerPointLoaderEvent.fetched(), + ); + } + } + @override Widget build(BuildContext context) { return Scaffold( @@ -61,7 +74,19 @@ class _HomePageState extends State { top: 225, child: _buildCarouselIndicators(), ), - Positioned(left: 16, right: 16, top: 240, child: HomePointCard()), + Positioned( + left: 16, + right: 16, + top: 240, + child: HomePointCard( + point: context + .read() + .state + .customerPoint + .totalPoints + .toString(), + ), + ), ], ); } diff --git a/lib/presentation/pages/main/pages/home/widgets/point_card.dart b/lib/presentation/pages/main/pages/home/widgets/point_card.dart index 2a77af3..779276a 100644 --- a/lib/presentation/pages/main/pages/home/widgets/point_card.dart +++ b/lib/presentation/pages/main/pages/home/widgets/point_card.dart @@ -7,7 +7,8 @@ import '../../../../../../common/theme/theme.dart'; import '../../../../../router/app_router.gr.dart'; class HomePointCard extends StatelessWidget { - const HomePointCard({super.key}); + final String point; + const HomePointCard({super.key, required this.point}); @override Widget build(BuildContext context) { @@ -75,7 +76,7 @@ class HomePointCard extends StatelessWidget { ), SizedBox(width: 8), Text( - '148 Poin', + '$point Poin', style: AppStyle.md.copyWith( color: AppColor.white, fontWeight: FontWeight.w600, @@ -86,7 +87,7 @@ class HomePointCard extends StatelessWidget { ), const SizedBox(height: 4), Text( - 'Kamu punya 148 poin', + 'Kamu punya $point poin', style: AppStyle.sm.copyWith( color: AppColor.textSecondary, fontSize: 11, diff --git a/lib/presentation/pages/poin/poin_page.dart b/lib/presentation/pages/poin/poin_page.dart index 035da8c..b94665a 100644 --- a/lib/presentation/pages/poin/poin_page.dart +++ b/lib/presentation/pages/poin/poin_page.dart @@ -1,6 +1,8 @@ import 'package:auto_route/auto_route.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import '../../../application/customer/customer_point_loader/customer_point_loader_bloc.dart'; import '../../../common/theme/theme.dart'; import '../../router/app_router.gr.dart'; @@ -201,6 +203,9 @@ class _PoinPageState extends State { super.initState(); activeCategoryId = categories.first.id; // Set first category as active _initializeCategoryKeys(); + context.read().add( + CustomerPointLoaderEvent.fetched(), + ); } void _initializeCategoryKeys() { @@ -304,110 +309,115 @@ class _PoinPageState extends State { } Widget _buildPointCard() { - return Container( - margin: EdgeInsets.all(16), - padding: EdgeInsets.all(20), - decoration: BoxDecoration( - gradient: LinearGradient( - colors: [AppColor.primary, AppColor.primaryDark], - begin: Alignment.topLeft, - end: Alignment.bottomRight, - ), - borderRadius: BorderRadius.circular(16), - boxShadow: [ - BoxShadow( - color: AppColor.primary.withOpacity(0.3), - blurRadius: 12, - offset: Offset(0, 6), + return BlocBuilder( + builder: (context, state) { + return Container( + margin: EdgeInsets.all(16), + padding: EdgeInsets.all(20), + decoration: BoxDecoration( + gradient: LinearGradient( + colors: [AppColor.primary, AppColor.primaryDark], + begin: Alignment.topLeft, + end: Alignment.bottomRight, + ), + borderRadius: BorderRadius.circular(16), + boxShadow: [ + BoxShadow( + color: AppColor.primary.withOpacity(0.3), + blurRadius: 12, + offset: Offset(0, 6), + ), + ], ), - ], - ), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, children: [ - Column( - crossAxisAlignment: CrossAxisAlignment.start, + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Text( - pointCard.membershipLevel, - style: AppStyle.sm.copyWith( - color: AppColor.textWhite.withOpacity(0.9), - fontWeight: FontWeight.w500, - ), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // Text( + // "", + // style: AppStyle.sm.copyWith( + // color: AppColor.textWhite.withOpacity(0.9), + // fontWeight: FontWeight.w500, + // ), + // ), + // SizedBox(height: 4), + Text( + "${state.customerPoint.totalPoints}", + style: AppStyle.h2.copyWith( + color: AppColor.textWhite, + fontWeight: FontWeight.w700, + ), + ), + Text( + "Poin Tersedia", + style: AppStyle.sm.copyWith( + color: AppColor.textWhite.withOpacity(0.9), + ), + ), + ], ), - SizedBox(height: 4), - Text( - "${pointCard.availablePoints}", - style: AppStyle.h2.copyWith( + Container( + padding: EdgeInsets.all(12), + decoration: BoxDecoration( + color: AppColor.white.withOpacity(0.2), + borderRadius: BorderRadius.circular(12), + ), + child: Icon( + Icons.stars_rounded, color: AppColor.textWhite, - fontWeight: FontWeight.w700, - ), - ), - Text( - "Poin Tersedia", - style: AppStyle.sm.copyWith( - color: AppColor.textWhite.withOpacity(0.9), + size: 32, ), ), ], ), - Container( - padding: EdgeInsets.all(12), - decoration: BoxDecoration( - color: AppColor.white.withOpacity(0.2), - borderRadius: BorderRadius.circular(12), - ), - child: Icon( - Icons.stars_rounded, - color: AppColor.textWhite, - size: 32, - ), - ), + + // SizedBox(height: 16), + // Container( + // height: 8, + // decoration: BoxDecoration( + // color: AppColor.white.withOpacity(0.3), + // borderRadius: BorderRadius.circular(4), + // ), + // child: FractionallySizedBox( + // widthFactor: + // (pointCard.totalPoints - pointCard.usedPoints) / + // pointCard.totalPoints, + // alignment: Alignment.centerLeft, + // child: Container( + // decoration: BoxDecoration( + // color: AppColor.textWhite, + // borderRadius: BorderRadius.circular(4), + // ), + // ), + // ), + // ), + // SizedBox(height: 8), + // Row( + // mainAxisAlignment: MainAxisAlignment.spaceBetween, + // children: [ + // Text( + // "Terpakai: ${pointCard.usedPoints}", + // style: AppStyle.xs.copyWith( + // color: AppColor.textWhite.withOpacity(0.8), + // ), + // ), + // Text( + // "Total: ${pointCard.totalPoints}", + // style: AppStyle.xs.copyWith( + // color: AppColor.textWhite.withOpacity(0.8), + // ), + // ), + // ], + // ), ], ), - SizedBox(height: 16), - Container( - height: 8, - decoration: BoxDecoration( - color: AppColor.white.withOpacity(0.3), - borderRadius: BorderRadius.circular(4), - ), - child: FractionallySizedBox( - widthFactor: - (pointCard.totalPoints - pointCard.usedPoints) / - pointCard.totalPoints, - alignment: Alignment.centerLeft, - child: Container( - decoration: BoxDecoration( - color: AppColor.textWhite, - borderRadius: BorderRadius.circular(4), - ), - ), - ), - ), - SizedBox(height: 8), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text( - "Terpakai: ${pointCard.usedPoints}", - style: AppStyle.xs.copyWith( - color: AppColor.textWhite.withOpacity(0.8), - ), - ), - Text( - "Total: ${pointCard.totalPoints}", - style: AppStyle.xs.copyWith( - color: AppColor.textWhite.withOpacity(0.8), - ), - ), - ], - ), - ], - ), + ); + }, ); } diff --git a/lib/presentation/router/app_router.gr.dart b/lib/presentation/router/app_router.gr.dart index 8e71cda..af27992 100644 --- a/lib/presentation/router/app_router.gr.dart +++ b/lib/presentation/router/app_router.gr.dart @@ -693,7 +693,7 @@ class ProfileRoute extends _i33.PageRouteInfo { static _i33.PageInfo page = _i33.PageInfo( name, builder: (data) { - return const _i27.ProfilePage(); + return _i33.WrappedRoute(child: const _i27.ProfilePage()); }, ); }