Compare commits
No commits in common. "577adb7964bdc7f22c87ef130cd7dbdb8ad4d502" and "5387d7b7a6ae12eefed1f57bb11961b50ab419f2" have entirely different histories.
577adb7964
...
5387d7b7a6
@ -1,51 +0,0 @@
|
|||||||
import 'package:dartz/dartz.dart';
|
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
|
||||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
|
||||||
import 'package:injectable/injectable.dart';
|
|
||||||
|
|
||||||
import '../../../domain/analytic/analytic.dart';
|
|
||||||
import '../../../domain/analytic/repositories/i_analytic_repository.dart';
|
|
||||||
|
|
||||||
part 'category_analytic_loader_event.dart';
|
|
||||||
part 'category_analytic_loader_state.dart';
|
|
||||||
part 'category_analytic_loader_bloc.freezed.dart';
|
|
||||||
|
|
||||||
@injectable
|
|
||||||
class CategoryAnalyticLoaderBloc
|
|
||||||
extends Bloc<CategoryAnalyticLoaderEvent, CategoryAnalyticLoaderState> {
|
|
||||||
final IAnalyticRepository _repository;
|
|
||||||
|
|
||||||
CategoryAnalyticLoaderBloc(this._repository)
|
|
||||||
: super(CategoryAnalyticLoaderState.initial()) {
|
|
||||||
on<CategoryAnalyticLoaderEvent>(_onCategoryAnalyticLoaderEvent);
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> _onCategoryAnalyticLoaderEvent(
|
|
||||||
CategoryAnalyticLoaderEvent event,
|
|
||||||
Emitter<CategoryAnalyticLoaderState> emit,
|
|
||||||
) {
|
|
||||||
return event.map(
|
|
||||||
fetched: (e) async {
|
|
||||||
emit(
|
|
||||||
state.copyWith(
|
|
||||||
isFetching: true,
|
|
||||||
failureOptionCategoryAnalytic: none(),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
final result = await _repository.getCategory(
|
|
||||||
dateFrom: DateTime.now().subtract(const Duration(days: 30)),
|
|
||||||
dateTo: DateTime.now(),
|
|
||||||
);
|
|
||||||
|
|
||||||
var data = result.fold(
|
|
||||||
(f) => state.copyWith(failureOptionCategoryAnalytic: optionOf(f)),
|
|
||||||
(categoryAnalytic) =>
|
|
||||||
state.copyWith(categoryAnalytic: categoryAnalytic),
|
|
||||||
);
|
|
||||||
|
|
||||||
emit(data.copyWith(isFetching: false));
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,401 +0,0 @@
|
|||||||
// 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 'category_analytic_loader_bloc.dart';
|
|
||||||
|
|
||||||
// **************************************************************************
|
|
||||||
// FreezedGenerator
|
|
||||||
// **************************************************************************
|
|
||||||
|
|
||||||
T _$identity<T>(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 _$CategoryAnalyticLoaderEvent {
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult when<TResult extends Object?>({
|
|
||||||
required TResult Function() fetched,
|
|
||||||
}) => throw _privateConstructorUsedError;
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult? whenOrNull<TResult extends Object?>({
|
|
||||||
TResult? Function()? fetched,
|
|
||||||
}) => throw _privateConstructorUsedError;
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult maybeWhen<TResult extends Object?>({
|
|
||||||
TResult Function()? fetched,
|
|
||||||
required TResult orElse(),
|
|
||||||
}) => throw _privateConstructorUsedError;
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult map<TResult extends Object?>({
|
|
||||||
required TResult Function(_Fetched value) fetched,
|
|
||||||
}) => throw _privateConstructorUsedError;
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult? mapOrNull<TResult extends Object?>({
|
|
||||||
TResult? Function(_Fetched value)? fetched,
|
|
||||||
}) => throw _privateConstructorUsedError;
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult maybeMap<TResult extends Object?>({
|
|
||||||
TResult Function(_Fetched value)? fetched,
|
|
||||||
required TResult orElse(),
|
|
||||||
}) => throw _privateConstructorUsedError;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
abstract class $CategoryAnalyticLoaderEventCopyWith<$Res> {
|
|
||||||
factory $CategoryAnalyticLoaderEventCopyWith(
|
|
||||||
CategoryAnalyticLoaderEvent value,
|
|
||||||
$Res Function(CategoryAnalyticLoaderEvent) then,
|
|
||||||
) =
|
|
||||||
_$CategoryAnalyticLoaderEventCopyWithImpl<
|
|
||||||
$Res,
|
|
||||||
CategoryAnalyticLoaderEvent
|
|
||||||
>;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
class _$CategoryAnalyticLoaderEventCopyWithImpl<
|
|
||||||
$Res,
|
|
||||||
$Val extends CategoryAnalyticLoaderEvent
|
|
||||||
>
|
|
||||||
implements $CategoryAnalyticLoaderEventCopyWith<$Res> {
|
|
||||||
_$CategoryAnalyticLoaderEventCopyWithImpl(this._value, this._then);
|
|
||||||
|
|
||||||
// ignore: unused_field
|
|
||||||
final $Val _value;
|
|
||||||
// ignore: unused_field
|
|
||||||
final $Res Function($Val) _then;
|
|
||||||
|
|
||||||
/// Create a copy of CategoryAnalyticLoaderEvent
|
|
||||||
/// 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 _$CategoryAnalyticLoaderEventCopyWithImpl<$Res, _$FetchedImpl>
|
|
||||||
implements _$$FetchedImplCopyWith<$Res> {
|
|
||||||
__$$FetchedImplCopyWithImpl(
|
|
||||||
_$FetchedImpl _value,
|
|
||||||
$Res Function(_$FetchedImpl) _then,
|
|
||||||
) : super(_value, _then);
|
|
||||||
|
|
||||||
/// Create a copy of CategoryAnalyticLoaderEvent
|
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
|
|
||||||
class _$FetchedImpl implements _Fetched {
|
|
||||||
const _$FetchedImpl();
|
|
||||||
|
|
||||||
@override
|
|
||||||
String toString() {
|
|
||||||
return 'CategoryAnalyticLoaderEvent.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<TResult extends Object?>({required TResult Function() fetched}) {
|
|
||||||
return fetched();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult? whenOrNull<TResult extends Object?>({TResult? Function()? fetched}) {
|
|
||||||
return fetched?.call();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult maybeWhen<TResult extends Object?>({
|
|
||||||
TResult Function()? fetched,
|
|
||||||
required TResult orElse(),
|
|
||||||
}) {
|
|
||||||
if (fetched != null) {
|
|
||||||
return fetched();
|
|
||||||
}
|
|
||||||
return orElse();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult map<TResult extends Object?>({
|
|
||||||
required TResult Function(_Fetched value) fetched,
|
|
||||||
}) {
|
|
||||||
return fetched(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult? mapOrNull<TResult extends Object?>({
|
|
||||||
TResult? Function(_Fetched value)? fetched,
|
|
||||||
}) {
|
|
||||||
return fetched?.call(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult maybeMap<TResult extends Object?>({
|
|
||||||
TResult Function(_Fetched value)? fetched,
|
|
||||||
required TResult orElse(),
|
|
||||||
}) {
|
|
||||||
if (fetched != null) {
|
|
||||||
return fetched(this);
|
|
||||||
}
|
|
||||||
return orElse();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract class _Fetched implements CategoryAnalyticLoaderEvent {
|
|
||||||
const factory _Fetched() = _$FetchedImpl;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
mixin _$CategoryAnalyticLoaderState {
|
|
||||||
CategoryAnalytic get categoryAnalytic => throw _privateConstructorUsedError;
|
|
||||||
Option<AnalyticFailure> get failureOptionCategoryAnalytic =>
|
|
||||||
throw _privateConstructorUsedError;
|
|
||||||
bool get isFetching => throw _privateConstructorUsedError;
|
|
||||||
|
|
||||||
/// Create a copy of CategoryAnalyticLoaderState
|
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
|
||||||
$CategoryAnalyticLoaderStateCopyWith<CategoryAnalyticLoaderState>
|
|
||||||
get copyWith => throw _privateConstructorUsedError;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
abstract class $CategoryAnalyticLoaderStateCopyWith<$Res> {
|
|
||||||
factory $CategoryAnalyticLoaderStateCopyWith(
|
|
||||||
CategoryAnalyticLoaderState value,
|
|
||||||
$Res Function(CategoryAnalyticLoaderState) then,
|
|
||||||
) =
|
|
||||||
_$CategoryAnalyticLoaderStateCopyWithImpl<
|
|
||||||
$Res,
|
|
||||||
CategoryAnalyticLoaderState
|
|
||||||
>;
|
|
||||||
@useResult
|
|
||||||
$Res call({
|
|
||||||
CategoryAnalytic categoryAnalytic,
|
|
||||||
Option<AnalyticFailure> failureOptionCategoryAnalytic,
|
|
||||||
bool isFetching,
|
|
||||||
});
|
|
||||||
|
|
||||||
$CategoryAnalyticCopyWith<$Res> get categoryAnalytic;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
class _$CategoryAnalyticLoaderStateCopyWithImpl<
|
|
||||||
$Res,
|
|
||||||
$Val extends CategoryAnalyticLoaderState
|
|
||||||
>
|
|
||||||
implements $CategoryAnalyticLoaderStateCopyWith<$Res> {
|
|
||||||
_$CategoryAnalyticLoaderStateCopyWithImpl(this._value, this._then);
|
|
||||||
|
|
||||||
// ignore: unused_field
|
|
||||||
final $Val _value;
|
|
||||||
// ignore: unused_field
|
|
||||||
final $Res Function($Val) _then;
|
|
||||||
|
|
||||||
/// Create a copy of CategoryAnalyticLoaderState
|
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
|
||||||
@pragma('vm:prefer-inline')
|
|
||||||
@override
|
|
||||||
$Res call({
|
|
||||||
Object? categoryAnalytic = null,
|
|
||||||
Object? failureOptionCategoryAnalytic = null,
|
|
||||||
Object? isFetching = null,
|
|
||||||
}) {
|
|
||||||
return _then(
|
|
||||||
_value.copyWith(
|
|
||||||
categoryAnalytic: null == categoryAnalytic
|
|
||||||
? _value.categoryAnalytic
|
|
||||||
: categoryAnalytic // ignore: cast_nullable_to_non_nullable
|
|
||||||
as CategoryAnalytic,
|
|
||||||
failureOptionCategoryAnalytic: null == failureOptionCategoryAnalytic
|
|
||||||
? _value.failureOptionCategoryAnalytic
|
|
||||||
: failureOptionCategoryAnalytic // ignore: cast_nullable_to_non_nullable
|
|
||||||
as Option<AnalyticFailure>,
|
|
||||||
isFetching: null == isFetching
|
|
||||||
? _value.isFetching
|
|
||||||
: isFetching // ignore: cast_nullable_to_non_nullable
|
|
||||||
as bool,
|
|
||||||
)
|
|
||||||
as $Val,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Create a copy of CategoryAnalyticLoaderState
|
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
|
||||||
@override
|
|
||||||
@pragma('vm:prefer-inline')
|
|
||||||
$CategoryAnalyticCopyWith<$Res> get categoryAnalytic {
|
|
||||||
return $CategoryAnalyticCopyWith<$Res>(_value.categoryAnalytic, (value) {
|
|
||||||
return _then(_value.copyWith(categoryAnalytic: value) as $Val);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
abstract class _$$CategoryAnalyticLoaderStateImplCopyWith<$Res>
|
|
||||||
implements $CategoryAnalyticLoaderStateCopyWith<$Res> {
|
|
||||||
factory _$$CategoryAnalyticLoaderStateImplCopyWith(
|
|
||||||
_$CategoryAnalyticLoaderStateImpl value,
|
|
||||||
$Res Function(_$CategoryAnalyticLoaderStateImpl) then,
|
|
||||||
) = __$$CategoryAnalyticLoaderStateImplCopyWithImpl<$Res>;
|
|
||||||
@override
|
|
||||||
@useResult
|
|
||||||
$Res call({
|
|
||||||
CategoryAnalytic categoryAnalytic,
|
|
||||||
Option<AnalyticFailure> failureOptionCategoryAnalytic,
|
|
||||||
bool isFetching,
|
|
||||||
});
|
|
||||||
|
|
||||||
@override
|
|
||||||
$CategoryAnalyticCopyWith<$Res> get categoryAnalytic;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
class __$$CategoryAnalyticLoaderStateImplCopyWithImpl<$Res>
|
|
||||||
extends
|
|
||||||
_$CategoryAnalyticLoaderStateCopyWithImpl<
|
|
||||||
$Res,
|
|
||||||
_$CategoryAnalyticLoaderStateImpl
|
|
||||||
>
|
|
||||||
implements _$$CategoryAnalyticLoaderStateImplCopyWith<$Res> {
|
|
||||||
__$$CategoryAnalyticLoaderStateImplCopyWithImpl(
|
|
||||||
_$CategoryAnalyticLoaderStateImpl _value,
|
|
||||||
$Res Function(_$CategoryAnalyticLoaderStateImpl) _then,
|
|
||||||
) : super(_value, _then);
|
|
||||||
|
|
||||||
/// Create a copy of CategoryAnalyticLoaderState
|
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
|
||||||
@pragma('vm:prefer-inline')
|
|
||||||
@override
|
|
||||||
$Res call({
|
|
||||||
Object? categoryAnalytic = null,
|
|
||||||
Object? failureOptionCategoryAnalytic = null,
|
|
||||||
Object? isFetching = null,
|
|
||||||
}) {
|
|
||||||
return _then(
|
|
||||||
_$CategoryAnalyticLoaderStateImpl(
|
|
||||||
categoryAnalytic: null == categoryAnalytic
|
|
||||||
? _value.categoryAnalytic
|
|
||||||
: categoryAnalytic // ignore: cast_nullable_to_non_nullable
|
|
||||||
as CategoryAnalytic,
|
|
||||||
failureOptionCategoryAnalytic: null == failureOptionCategoryAnalytic
|
|
||||||
? _value.failureOptionCategoryAnalytic
|
|
||||||
: failureOptionCategoryAnalytic // ignore: cast_nullable_to_non_nullable
|
|
||||||
as Option<AnalyticFailure>,
|
|
||||||
isFetching: null == isFetching
|
|
||||||
? _value.isFetching
|
|
||||||
: isFetching // ignore: cast_nullable_to_non_nullable
|
|
||||||
as bool,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
|
|
||||||
class _$CategoryAnalyticLoaderStateImpl
|
|
||||||
implements _CategoryAnalyticLoaderState {
|
|
||||||
const _$CategoryAnalyticLoaderStateImpl({
|
|
||||||
required this.categoryAnalytic,
|
|
||||||
required this.failureOptionCategoryAnalytic,
|
|
||||||
this.isFetching = false,
|
|
||||||
});
|
|
||||||
|
|
||||||
@override
|
|
||||||
final CategoryAnalytic categoryAnalytic;
|
|
||||||
@override
|
|
||||||
final Option<AnalyticFailure> failureOptionCategoryAnalytic;
|
|
||||||
@override
|
|
||||||
@JsonKey()
|
|
||||||
final bool isFetching;
|
|
||||||
|
|
||||||
@override
|
|
||||||
String toString() {
|
|
||||||
return 'CategoryAnalyticLoaderState(categoryAnalytic: $categoryAnalytic, failureOptionCategoryAnalytic: $failureOptionCategoryAnalytic, isFetching: $isFetching)';
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
bool operator ==(Object other) {
|
|
||||||
return identical(this, other) ||
|
|
||||||
(other.runtimeType == runtimeType &&
|
|
||||||
other is _$CategoryAnalyticLoaderStateImpl &&
|
|
||||||
(identical(other.categoryAnalytic, categoryAnalytic) ||
|
|
||||||
other.categoryAnalytic == categoryAnalytic) &&
|
|
||||||
(identical(
|
|
||||||
other.failureOptionCategoryAnalytic,
|
|
||||||
failureOptionCategoryAnalytic,
|
|
||||||
) ||
|
|
||||||
other.failureOptionCategoryAnalytic ==
|
|
||||||
failureOptionCategoryAnalytic) &&
|
|
||||||
(identical(other.isFetching, isFetching) ||
|
|
||||||
other.isFetching == isFetching));
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
int get hashCode => Object.hash(
|
|
||||||
runtimeType,
|
|
||||||
categoryAnalytic,
|
|
||||||
failureOptionCategoryAnalytic,
|
|
||||||
isFetching,
|
|
||||||
);
|
|
||||||
|
|
||||||
/// Create a copy of CategoryAnalyticLoaderState
|
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
|
||||||
@override
|
|
||||||
@pragma('vm:prefer-inline')
|
|
||||||
_$$CategoryAnalyticLoaderStateImplCopyWith<_$CategoryAnalyticLoaderStateImpl>
|
|
||||||
get copyWith =>
|
|
||||||
__$$CategoryAnalyticLoaderStateImplCopyWithImpl<
|
|
||||||
_$CategoryAnalyticLoaderStateImpl
|
|
||||||
>(this, _$identity);
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract class _CategoryAnalyticLoaderState
|
|
||||||
implements CategoryAnalyticLoaderState {
|
|
||||||
const factory _CategoryAnalyticLoaderState({
|
|
||||||
required final CategoryAnalytic categoryAnalytic,
|
|
||||||
required final Option<AnalyticFailure> failureOptionCategoryAnalytic,
|
|
||||||
final bool isFetching,
|
|
||||||
}) = _$CategoryAnalyticLoaderStateImpl;
|
|
||||||
|
|
||||||
@override
|
|
||||||
CategoryAnalytic get categoryAnalytic;
|
|
||||||
@override
|
|
||||||
Option<AnalyticFailure> get failureOptionCategoryAnalytic;
|
|
||||||
@override
|
|
||||||
bool get isFetching;
|
|
||||||
|
|
||||||
/// Create a copy of CategoryAnalyticLoaderState
|
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
|
||||||
@override
|
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
|
||||||
_$$CategoryAnalyticLoaderStateImplCopyWith<_$CategoryAnalyticLoaderStateImpl>
|
|
||||||
get copyWith => throw _privateConstructorUsedError;
|
|
||||||
}
|
|
||||||
@ -1,6 +0,0 @@
|
|||||||
part of 'category_analytic_loader_bloc.dart';
|
|
||||||
|
|
||||||
@freezed
|
|
||||||
class CategoryAnalyticLoaderEvent with _$CategoryAnalyticLoaderEvent {
|
|
||||||
const factory CategoryAnalyticLoaderEvent.fetched() = _Fetched;
|
|
||||||
}
|
|
||||||
@ -1,15 +0,0 @@
|
|||||||
part of 'category_analytic_loader_bloc.dart';
|
|
||||||
|
|
||||||
@freezed
|
|
||||||
class CategoryAnalyticLoaderState with _$CategoryAnalyticLoaderState {
|
|
||||||
const factory CategoryAnalyticLoaderState({
|
|
||||||
required CategoryAnalytic categoryAnalytic,
|
|
||||||
required Option<AnalyticFailure> failureOptionCategoryAnalytic,
|
|
||||||
@Default(false) bool isFetching,
|
|
||||||
}) = _CategoryAnalyticLoaderState;
|
|
||||||
|
|
||||||
factory CategoryAnalyticLoaderState.initial() => CategoryAnalyticLoaderState(
|
|
||||||
categoryAnalytic: CategoryAnalytic.empty(),
|
|
||||||
failureOptionCategoryAnalytic: none(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@ -1,44 +0,0 @@
|
|||||||
import 'package:dartz/dartz.dart';
|
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
|
||||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
|
||||||
import 'package:injectable/injectable.dart';
|
|
||||||
|
|
||||||
import '../../../domain/analytic/analytic.dart';
|
|
||||||
import '../../../domain/analytic/repositories/i_analytic_repository.dart';
|
|
||||||
|
|
||||||
part 'profit_loss_loader_event.dart';
|
|
||||||
part 'profit_loss_loader_state.dart';
|
|
||||||
part 'profit_loss_loader_bloc.freezed.dart';
|
|
||||||
|
|
||||||
@injectable
|
|
||||||
class ProfitLossLoaderBloc
|
|
||||||
extends Bloc<ProfitLossLoaderEvent, ProfitLossLoaderState> {
|
|
||||||
final IAnalyticRepository _repository;
|
|
||||||
ProfitLossLoaderBloc(this._repository)
|
|
||||||
: super(ProfitLossLoaderState.initial()) {
|
|
||||||
on<ProfitLossLoaderEvent>(_onProfitLossLoaderEvent);
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> _onProfitLossLoaderEvent(
|
|
||||||
ProfitLossLoaderEvent event,
|
|
||||||
Emitter<ProfitLossLoaderState> emit,
|
|
||||||
) {
|
|
||||||
return event.map(
|
|
||||||
fetched: (e) async {
|
|
||||||
emit(state.copyWith(isFetching: true, failureOptionProfitLoss: none()));
|
|
||||||
|
|
||||||
final result = await _repository.getProfitLoss(
|
|
||||||
dateFrom: DateTime.now().subtract(const Duration(days: 30)),
|
|
||||||
dateTo: DateTime.now(),
|
|
||||||
);
|
|
||||||
|
|
||||||
var data = result.fold(
|
|
||||||
(f) => state.copyWith(failureOptionProfitLoss: optionOf(f)),
|
|
||||||
(profitLoss) => state.copyWith(profitLoss: profitLoss),
|
|
||||||
);
|
|
||||||
|
|
||||||
emit(data.copyWith(isFetching: false));
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,384 +0,0 @@
|
|||||||
// 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 'profit_loss_loader_bloc.dart';
|
|
||||||
|
|
||||||
// **************************************************************************
|
|
||||||
// FreezedGenerator
|
|
||||||
// **************************************************************************
|
|
||||||
|
|
||||||
T _$identity<T>(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 _$ProfitLossLoaderEvent {
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult when<TResult extends Object?>({
|
|
||||||
required TResult Function() fetched,
|
|
||||||
}) => throw _privateConstructorUsedError;
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult? whenOrNull<TResult extends Object?>({
|
|
||||||
TResult? Function()? fetched,
|
|
||||||
}) => throw _privateConstructorUsedError;
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult maybeWhen<TResult extends Object?>({
|
|
||||||
TResult Function()? fetched,
|
|
||||||
required TResult orElse(),
|
|
||||||
}) => throw _privateConstructorUsedError;
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult map<TResult extends Object?>({
|
|
||||||
required TResult Function(_Fetched value) fetched,
|
|
||||||
}) => throw _privateConstructorUsedError;
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult? mapOrNull<TResult extends Object?>({
|
|
||||||
TResult? Function(_Fetched value)? fetched,
|
|
||||||
}) => throw _privateConstructorUsedError;
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult maybeMap<TResult extends Object?>({
|
|
||||||
TResult Function(_Fetched value)? fetched,
|
|
||||||
required TResult orElse(),
|
|
||||||
}) => throw _privateConstructorUsedError;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
abstract class $ProfitLossLoaderEventCopyWith<$Res> {
|
|
||||||
factory $ProfitLossLoaderEventCopyWith(
|
|
||||||
ProfitLossLoaderEvent value,
|
|
||||||
$Res Function(ProfitLossLoaderEvent) then,
|
|
||||||
) = _$ProfitLossLoaderEventCopyWithImpl<$Res, ProfitLossLoaderEvent>;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
class _$ProfitLossLoaderEventCopyWithImpl<
|
|
||||||
$Res,
|
|
||||||
$Val extends ProfitLossLoaderEvent
|
|
||||||
>
|
|
||||||
implements $ProfitLossLoaderEventCopyWith<$Res> {
|
|
||||||
_$ProfitLossLoaderEventCopyWithImpl(this._value, this._then);
|
|
||||||
|
|
||||||
// ignore: unused_field
|
|
||||||
final $Val _value;
|
|
||||||
// ignore: unused_field
|
|
||||||
final $Res Function($Val) _then;
|
|
||||||
|
|
||||||
/// Create a copy of ProfitLossLoaderEvent
|
|
||||||
/// 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 _$ProfitLossLoaderEventCopyWithImpl<$Res, _$FetchedImpl>
|
|
||||||
implements _$$FetchedImplCopyWith<$Res> {
|
|
||||||
__$$FetchedImplCopyWithImpl(
|
|
||||||
_$FetchedImpl _value,
|
|
||||||
$Res Function(_$FetchedImpl) _then,
|
|
||||||
) : super(_value, _then);
|
|
||||||
|
|
||||||
/// Create a copy of ProfitLossLoaderEvent
|
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
|
|
||||||
class _$FetchedImpl implements _Fetched {
|
|
||||||
const _$FetchedImpl();
|
|
||||||
|
|
||||||
@override
|
|
||||||
String toString() {
|
|
||||||
return 'ProfitLossLoaderEvent.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<TResult extends Object?>({required TResult Function() fetched}) {
|
|
||||||
return fetched();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult? whenOrNull<TResult extends Object?>({TResult? Function()? fetched}) {
|
|
||||||
return fetched?.call();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult maybeWhen<TResult extends Object?>({
|
|
||||||
TResult Function()? fetched,
|
|
||||||
required TResult orElse(),
|
|
||||||
}) {
|
|
||||||
if (fetched != null) {
|
|
||||||
return fetched();
|
|
||||||
}
|
|
||||||
return orElse();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult map<TResult extends Object?>({
|
|
||||||
required TResult Function(_Fetched value) fetched,
|
|
||||||
}) {
|
|
||||||
return fetched(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult? mapOrNull<TResult extends Object?>({
|
|
||||||
TResult? Function(_Fetched value)? fetched,
|
|
||||||
}) {
|
|
||||||
return fetched?.call(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult maybeMap<TResult extends Object?>({
|
|
||||||
TResult Function(_Fetched value)? fetched,
|
|
||||||
required TResult orElse(),
|
|
||||||
}) {
|
|
||||||
if (fetched != null) {
|
|
||||||
return fetched(this);
|
|
||||||
}
|
|
||||||
return orElse();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract class _Fetched implements ProfitLossLoaderEvent {
|
|
||||||
const factory _Fetched() = _$FetchedImpl;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
mixin _$ProfitLossLoaderState {
|
|
||||||
ProfitLossAnalytic get profitLoss => throw _privateConstructorUsedError;
|
|
||||||
Option<AnalyticFailure> get failureOptionProfitLoss =>
|
|
||||||
throw _privateConstructorUsedError;
|
|
||||||
bool get isFetching => throw _privateConstructorUsedError;
|
|
||||||
|
|
||||||
/// Create a copy of ProfitLossLoaderState
|
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
|
||||||
$ProfitLossLoaderStateCopyWith<ProfitLossLoaderState> get copyWith =>
|
|
||||||
throw _privateConstructorUsedError;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
abstract class $ProfitLossLoaderStateCopyWith<$Res> {
|
|
||||||
factory $ProfitLossLoaderStateCopyWith(
|
|
||||||
ProfitLossLoaderState value,
|
|
||||||
$Res Function(ProfitLossLoaderState) then,
|
|
||||||
) = _$ProfitLossLoaderStateCopyWithImpl<$Res, ProfitLossLoaderState>;
|
|
||||||
@useResult
|
|
||||||
$Res call({
|
|
||||||
ProfitLossAnalytic profitLoss,
|
|
||||||
Option<AnalyticFailure> failureOptionProfitLoss,
|
|
||||||
bool isFetching,
|
|
||||||
});
|
|
||||||
|
|
||||||
$ProfitLossAnalyticCopyWith<$Res> get profitLoss;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
class _$ProfitLossLoaderStateCopyWithImpl<
|
|
||||||
$Res,
|
|
||||||
$Val extends ProfitLossLoaderState
|
|
||||||
>
|
|
||||||
implements $ProfitLossLoaderStateCopyWith<$Res> {
|
|
||||||
_$ProfitLossLoaderStateCopyWithImpl(this._value, this._then);
|
|
||||||
|
|
||||||
// ignore: unused_field
|
|
||||||
final $Val _value;
|
|
||||||
// ignore: unused_field
|
|
||||||
final $Res Function($Val) _then;
|
|
||||||
|
|
||||||
/// Create a copy of ProfitLossLoaderState
|
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
|
||||||
@pragma('vm:prefer-inline')
|
|
||||||
@override
|
|
||||||
$Res call({
|
|
||||||
Object? profitLoss = null,
|
|
||||||
Object? failureOptionProfitLoss = null,
|
|
||||||
Object? isFetching = null,
|
|
||||||
}) {
|
|
||||||
return _then(
|
|
||||||
_value.copyWith(
|
|
||||||
profitLoss: null == profitLoss
|
|
||||||
? _value.profitLoss
|
|
||||||
: profitLoss // ignore: cast_nullable_to_non_nullable
|
|
||||||
as ProfitLossAnalytic,
|
|
||||||
failureOptionProfitLoss: null == failureOptionProfitLoss
|
|
||||||
? _value.failureOptionProfitLoss
|
|
||||||
: failureOptionProfitLoss // ignore: cast_nullable_to_non_nullable
|
|
||||||
as Option<AnalyticFailure>,
|
|
||||||
isFetching: null == isFetching
|
|
||||||
? _value.isFetching
|
|
||||||
: isFetching // ignore: cast_nullable_to_non_nullable
|
|
||||||
as bool,
|
|
||||||
)
|
|
||||||
as $Val,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Create a copy of ProfitLossLoaderState
|
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
|
||||||
@override
|
|
||||||
@pragma('vm:prefer-inline')
|
|
||||||
$ProfitLossAnalyticCopyWith<$Res> get profitLoss {
|
|
||||||
return $ProfitLossAnalyticCopyWith<$Res>(_value.profitLoss, (value) {
|
|
||||||
return _then(_value.copyWith(profitLoss: value) as $Val);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
abstract class _$$ProfitLossLoaderStateImplCopyWith<$Res>
|
|
||||||
implements $ProfitLossLoaderStateCopyWith<$Res> {
|
|
||||||
factory _$$ProfitLossLoaderStateImplCopyWith(
|
|
||||||
_$ProfitLossLoaderStateImpl value,
|
|
||||||
$Res Function(_$ProfitLossLoaderStateImpl) then,
|
|
||||||
) = __$$ProfitLossLoaderStateImplCopyWithImpl<$Res>;
|
|
||||||
@override
|
|
||||||
@useResult
|
|
||||||
$Res call({
|
|
||||||
ProfitLossAnalytic profitLoss,
|
|
||||||
Option<AnalyticFailure> failureOptionProfitLoss,
|
|
||||||
bool isFetching,
|
|
||||||
});
|
|
||||||
|
|
||||||
@override
|
|
||||||
$ProfitLossAnalyticCopyWith<$Res> get profitLoss;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
class __$$ProfitLossLoaderStateImplCopyWithImpl<$Res>
|
|
||||||
extends
|
|
||||||
_$ProfitLossLoaderStateCopyWithImpl<$Res, _$ProfitLossLoaderStateImpl>
|
|
||||||
implements _$$ProfitLossLoaderStateImplCopyWith<$Res> {
|
|
||||||
__$$ProfitLossLoaderStateImplCopyWithImpl(
|
|
||||||
_$ProfitLossLoaderStateImpl _value,
|
|
||||||
$Res Function(_$ProfitLossLoaderStateImpl) _then,
|
|
||||||
) : super(_value, _then);
|
|
||||||
|
|
||||||
/// Create a copy of ProfitLossLoaderState
|
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
|
||||||
@pragma('vm:prefer-inline')
|
|
||||||
@override
|
|
||||||
$Res call({
|
|
||||||
Object? profitLoss = null,
|
|
||||||
Object? failureOptionProfitLoss = null,
|
|
||||||
Object? isFetching = null,
|
|
||||||
}) {
|
|
||||||
return _then(
|
|
||||||
_$ProfitLossLoaderStateImpl(
|
|
||||||
profitLoss: null == profitLoss
|
|
||||||
? _value.profitLoss
|
|
||||||
: profitLoss // ignore: cast_nullable_to_non_nullable
|
|
||||||
as ProfitLossAnalytic,
|
|
||||||
failureOptionProfitLoss: null == failureOptionProfitLoss
|
|
||||||
? _value.failureOptionProfitLoss
|
|
||||||
: failureOptionProfitLoss // ignore: cast_nullable_to_non_nullable
|
|
||||||
as Option<AnalyticFailure>,
|
|
||||||
isFetching: null == isFetching
|
|
||||||
? _value.isFetching
|
|
||||||
: isFetching // ignore: cast_nullable_to_non_nullable
|
|
||||||
as bool,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
|
|
||||||
class _$ProfitLossLoaderStateImpl implements _ProfitLossLoaderState {
|
|
||||||
const _$ProfitLossLoaderStateImpl({
|
|
||||||
required this.profitLoss,
|
|
||||||
required this.failureOptionProfitLoss,
|
|
||||||
this.isFetching = false,
|
|
||||||
});
|
|
||||||
|
|
||||||
@override
|
|
||||||
final ProfitLossAnalytic profitLoss;
|
|
||||||
@override
|
|
||||||
final Option<AnalyticFailure> failureOptionProfitLoss;
|
|
||||||
@override
|
|
||||||
@JsonKey()
|
|
||||||
final bool isFetching;
|
|
||||||
|
|
||||||
@override
|
|
||||||
String toString() {
|
|
||||||
return 'ProfitLossLoaderState(profitLoss: $profitLoss, failureOptionProfitLoss: $failureOptionProfitLoss, isFetching: $isFetching)';
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
bool operator ==(Object other) {
|
|
||||||
return identical(this, other) ||
|
|
||||||
(other.runtimeType == runtimeType &&
|
|
||||||
other is _$ProfitLossLoaderStateImpl &&
|
|
||||||
(identical(other.profitLoss, profitLoss) ||
|
|
||||||
other.profitLoss == profitLoss) &&
|
|
||||||
(identical(
|
|
||||||
other.failureOptionProfitLoss,
|
|
||||||
failureOptionProfitLoss,
|
|
||||||
) ||
|
|
||||||
other.failureOptionProfitLoss == failureOptionProfitLoss) &&
|
|
||||||
(identical(other.isFetching, isFetching) ||
|
|
||||||
other.isFetching == isFetching));
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
int get hashCode =>
|
|
||||||
Object.hash(runtimeType, profitLoss, failureOptionProfitLoss, isFetching);
|
|
||||||
|
|
||||||
/// Create a copy of ProfitLossLoaderState
|
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
|
||||||
@override
|
|
||||||
@pragma('vm:prefer-inline')
|
|
||||||
_$$ProfitLossLoaderStateImplCopyWith<_$ProfitLossLoaderStateImpl>
|
|
||||||
get copyWith =>
|
|
||||||
__$$ProfitLossLoaderStateImplCopyWithImpl<_$ProfitLossLoaderStateImpl>(
|
|
||||||
this,
|
|
||||||
_$identity,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract class _ProfitLossLoaderState implements ProfitLossLoaderState {
|
|
||||||
const factory _ProfitLossLoaderState({
|
|
||||||
required final ProfitLossAnalytic profitLoss,
|
|
||||||
required final Option<AnalyticFailure> failureOptionProfitLoss,
|
|
||||||
final bool isFetching,
|
|
||||||
}) = _$ProfitLossLoaderStateImpl;
|
|
||||||
|
|
||||||
@override
|
|
||||||
ProfitLossAnalytic get profitLoss;
|
|
||||||
@override
|
|
||||||
Option<AnalyticFailure> get failureOptionProfitLoss;
|
|
||||||
@override
|
|
||||||
bool get isFetching;
|
|
||||||
|
|
||||||
/// Create a copy of ProfitLossLoaderState
|
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
|
||||||
@override
|
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
|
||||||
_$$ProfitLossLoaderStateImplCopyWith<_$ProfitLossLoaderStateImpl>
|
|
||||||
get copyWith => throw _privateConstructorUsedError;
|
|
||||||
}
|
|
||||||
@ -1,6 +0,0 @@
|
|||||||
part of 'profit_loss_loader_bloc.dart';
|
|
||||||
|
|
||||||
@freezed
|
|
||||||
class ProfitLossLoaderEvent with _$ProfitLossLoaderEvent {
|
|
||||||
const factory ProfitLossLoaderEvent.fetched() = _Fetched;
|
|
||||||
}
|
|
||||||
@ -1,15 +0,0 @@
|
|||||||
part of 'profit_loss_loader_bloc.dart';
|
|
||||||
|
|
||||||
@freezed
|
|
||||||
class ProfitLossLoaderState with _$ProfitLossLoaderState {
|
|
||||||
const factory ProfitLossLoaderState({
|
|
||||||
required ProfitLossAnalytic profitLoss,
|
|
||||||
required Option<AnalyticFailure> failureOptionProfitLoss,
|
|
||||||
@Default(false) bool isFetching,
|
|
||||||
}) = _ProfitLossLoaderState;
|
|
||||||
|
|
||||||
factory ProfitLossLoaderState.initial() => ProfitLossLoaderState(
|
|
||||||
profitLoss: ProfitLossAnalytic.empty(),
|
|
||||||
failureOptionProfitLoss: none(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@ -1,39 +0,0 @@
|
|||||||
import 'package:bloc/bloc.dart';
|
|
||||||
import 'package:dartz/dartz.dart';
|
|
||||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
|
||||||
import 'package:injectable/injectable.dart';
|
|
||||||
|
|
||||||
import '../../../domain/analytic/analytic.dart';
|
|
||||||
import '../../../domain/analytic/repositories/i_analytic_repository.dart';
|
|
||||||
|
|
||||||
part 'sales_loader_event.dart';
|
|
||||||
part 'sales_loader_state.dart';
|
|
||||||
part 'sales_loader_bloc.freezed.dart';
|
|
||||||
|
|
||||||
@injectable
|
|
||||||
class SalesLoaderBloc extends Bloc<SalesLoaderEvent, SalesLoaderState> {
|
|
||||||
final IAnalyticRepository _analyticRepository;
|
|
||||||
SalesLoaderBloc(this._analyticRepository)
|
|
||||||
: super(SalesLoaderState.initial()) {
|
|
||||||
on<SalesLoaderEvent>(_onSalesLoaderEvent);
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> _onSalesLoaderEvent(
|
|
||||||
SalesLoaderEvent event,
|
|
||||||
Emitter<SalesLoaderState> emit,
|
|
||||||
) async {
|
|
||||||
emit(state.copyWith(isFetching: true, failureOptionSales: none()));
|
|
||||||
|
|
||||||
final result = await _analyticRepository.getSales(
|
|
||||||
dateFrom: DateTime.now().subtract(const Duration(days: 30)),
|
|
||||||
dateTo: DateTime.now(),
|
|
||||||
);
|
|
||||||
|
|
||||||
var data = result.fold(
|
|
||||||
(f) => state.copyWith(failureOptionSales: optionOf(f)),
|
|
||||||
(sales) => state.copyWith(sales: sales),
|
|
||||||
);
|
|
||||||
|
|
||||||
emit(data.copyWith(isFetching: false));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,376 +0,0 @@
|
|||||||
// 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 'sales_loader_bloc.dart';
|
|
||||||
|
|
||||||
// **************************************************************************
|
|
||||||
// FreezedGenerator
|
|
||||||
// **************************************************************************
|
|
||||||
|
|
||||||
T _$identity<T>(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 _$SalesLoaderEvent {
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult when<TResult extends Object?>({
|
|
||||||
required TResult Function() fectched,
|
|
||||||
}) => throw _privateConstructorUsedError;
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult? whenOrNull<TResult extends Object?>({
|
|
||||||
TResult? Function()? fectched,
|
|
||||||
}) => throw _privateConstructorUsedError;
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult maybeWhen<TResult extends Object?>({
|
|
||||||
TResult Function()? fectched,
|
|
||||||
required TResult orElse(),
|
|
||||||
}) => throw _privateConstructorUsedError;
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult map<TResult extends Object?>({
|
|
||||||
required TResult Function(_Fectched value) fectched,
|
|
||||||
}) => throw _privateConstructorUsedError;
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult? mapOrNull<TResult extends Object?>({
|
|
||||||
TResult? Function(_Fectched value)? fectched,
|
|
||||||
}) => throw _privateConstructorUsedError;
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult maybeMap<TResult extends Object?>({
|
|
||||||
TResult Function(_Fectched value)? fectched,
|
|
||||||
required TResult orElse(),
|
|
||||||
}) => throw _privateConstructorUsedError;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
abstract class $SalesLoaderEventCopyWith<$Res> {
|
|
||||||
factory $SalesLoaderEventCopyWith(
|
|
||||||
SalesLoaderEvent value,
|
|
||||||
$Res Function(SalesLoaderEvent) then,
|
|
||||||
) = _$SalesLoaderEventCopyWithImpl<$Res, SalesLoaderEvent>;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
class _$SalesLoaderEventCopyWithImpl<$Res, $Val extends SalesLoaderEvent>
|
|
||||||
implements $SalesLoaderEventCopyWith<$Res> {
|
|
||||||
_$SalesLoaderEventCopyWithImpl(this._value, this._then);
|
|
||||||
|
|
||||||
// ignore: unused_field
|
|
||||||
final $Val _value;
|
|
||||||
// ignore: unused_field
|
|
||||||
final $Res Function($Val) _then;
|
|
||||||
|
|
||||||
/// Create a copy of SalesLoaderEvent
|
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
abstract class _$$FectchedImplCopyWith<$Res> {
|
|
||||||
factory _$$FectchedImplCopyWith(
|
|
||||||
_$FectchedImpl value,
|
|
||||||
$Res Function(_$FectchedImpl) then,
|
|
||||||
) = __$$FectchedImplCopyWithImpl<$Res>;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
class __$$FectchedImplCopyWithImpl<$Res>
|
|
||||||
extends _$SalesLoaderEventCopyWithImpl<$Res, _$FectchedImpl>
|
|
||||||
implements _$$FectchedImplCopyWith<$Res> {
|
|
||||||
__$$FectchedImplCopyWithImpl(
|
|
||||||
_$FectchedImpl _value,
|
|
||||||
$Res Function(_$FectchedImpl) _then,
|
|
||||||
) : super(_value, _then);
|
|
||||||
|
|
||||||
/// Create a copy of SalesLoaderEvent
|
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
|
|
||||||
class _$FectchedImpl implements _Fectched {
|
|
||||||
const _$FectchedImpl();
|
|
||||||
|
|
||||||
@override
|
|
||||||
String toString() {
|
|
||||||
return 'SalesLoaderEvent.fectched()';
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
bool operator ==(Object other) {
|
|
||||||
return identical(this, other) ||
|
|
||||||
(other.runtimeType == runtimeType && other is _$FectchedImpl);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
int get hashCode => runtimeType.hashCode;
|
|
||||||
|
|
||||||
@override
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult when<TResult extends Object?>({
|
|
||||||
required TResult Function() fectched,
|
|
||||||
}) {
|
|
||||||
return fectched();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult? whenOrNull<TResult extends Object?>({
|
|
||||||
TResult? Function()? fectched,
|
|
||||||
}) {
|
|
||||||
return fectched?.call();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult maybeWhen<TResult extends Object?>({
|
|
||||||
TResult Function()? fectched,
|
|
||||||
required TResult orElse(),
|
|
||||||
}) {
|
|
||||||
if (fectched != null) {
|
|
||||||
return fectched();
|
|
||||||
}
|
|
||||||
return orElse();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult map<TResult extends Object?>({
|
|
||||||
required TResult Function(_Fectched value) fectched,
|
|
||||||
}) {
|
|
||||||
return fectched(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult? mapOrNull<TResult extends Object?>({
|
|
||||||
TResult? Function(_Fectched value)? fectched,
|
|
||||||
}) {
|
|
||||||
return fectched?.call(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult maybeMap<TResult extends Object?>({
|
|
||||||
TResult Function(_Fectched value)? fectched,
|
|
||||||
required TResult orElse(),
|
|
||||||
}) {
|
|
||||||
if (fectched != null) {
|
|
||||||
return fectched(this);
|
|
||||||
}
|
|
||||||
return orElse();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract class _Fectched implements SalesLoaderEvent {
|
|
||||||
const factory _Fectched() = _$FectchedImpl;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
mixin _$SalesLoaderState {
|
|
||||||
SalesAnalytic get sales => throw _privateConstructorUsedError;
|
|
||||||
Option<AnalyticFailure> get failureOptionSales =>
|
|
||||||
throw _privateConstructorUsedError;
|
|
||||||
bool get isFetching => throw _privateConstructorUsedError;
|
|
||||||
|
|
||||||
/// Create a copy of SalesLoaderState
|
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
|
||||||
$SalesLoaderStateCopyWith<SalesLoaderState> get copyWith =>
|
|
||||||
throw _privateConstructorUsedError;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
abstract class $SalesLoaderStateCopyWith<$Res> {
|
|
||||||
factory $SalesLoaderStateCopyWith(
|
|
||||||
SalesLoaderState value,
|
|
||||||
$Res Function(SalesLoaderState) then,
|
|
||||||
) = _$SalesLoaderStateCopyWithImpl<$Res, SalesLoaderState>;
|
|
||||||
@useResult
|
|
||||||
$Res call({
|
|
||||||
SalesAnalytic sales,
|
|
||||||
Option<AnalyticFailure> failureOptionSales,
|
|
||||||
bool isFetching,
|
|
||||||
});
|
|
||||||
|
|
||||||
$SalesAnalyticCopyWith<$Res> get sales;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
class _$SalesLoaderStateCopyWithImpl<$Res, $Val extends SalesLoaderState>
|
|
||||||
implements $SalesLoaderStateCopyWith<$Res> {
|
|
||||||
_$SalesLoaderStateCopyWithImpl(this._value, this._then);
|
|
||||||
|
|
||||||
// ignore: unused_field
|
|
||||||
final $Val _value;
|
|
||||||
// ignore: unused_field
|
|
||||||
final $Res Function($Val) _then;
|
|
||||||
|
|
||||||
/// Create a copy of SalesLoaderState
|
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
|
||||||
@pragma('vm:prefer-inline')
|
|
||||||
@override
|
|
||||||
$Res call({
|
|
||||||
Object? sales = null,
|
|
||||||
Object? failureOptionSales = null,
|
|
||||||
Object? isFetching = null,
|
|
||||||
}) {
|
|
||||||
return _then(
|
|
||||||
_value.copyWith(
|
|
||||||
sales: null == sales
|
|
||||||
? _value.sales
|
|
||||||
: sales // ignore: cast_nullable_to_non_nullable
|
|
||||||
as SalesAnalytic,
|
|
||||||
failureOptionSales: null == failureOptionSales
|
|
||||||
? _value.failureOptionSales
|
|
||||||
: failureOptionSales // ignore: cast_nullable_to_non_nullable
|
|
||||||
as Option<AnalyticFailure>,
|
|
||||||
isFetching: null == isFetching
|
|
||||||
? _value.isFetching
|
|
||||||
: isFetching // ignore: cast_nullable_to_non_nullable
|
|
||||||
as bool,
|
|
||||||
)
|
|
||||||
as $Val,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Create a copy of SalesLoaderState
|
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
|
||||||
@override
|
|
||||||
@pragma('vm:prefer-inline')
|
|
||||||
$SalesAnalyticCopyWith<$Res> get sales {
|
|
||||||
return $SalesAnalyticCopyWith<$Res>(_value.sales, (value) {
|
|
||||||
return _then(_value.copyWith(sales: value) as $Val);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
abstract class _$$SalesLoaderStateImplCopyWith<$Res>
|
|
||||||
implements $SalesLoaderStateCopyWith<$Res> {
|
|
||||||
factory _$$SalesLoaderStateImplCopyWith(
|
|
||||||
_$SalesLoaderStateImpl value,
|
|
||||||
$Res Function(_$SalesLoaderStateImpl) then,
|
|
||||||
) = __$$SalesLoaderStateImplCopyWithImpl<$Res>;
|
|
||||||
@override
|
|
||||||
@useResult
|
|
||||||
$Res call({
|
|
||||||
SalesAnalytic sales,
|
|
||||||
Option<AnalyticFailure> failureOptionSales,
|
|
||||||
bool isFetching,
|
|
||||||
});
|
|
||||||
|
|
||||||
@override
|
|
||||||
$SalesAnalyticCopyWith<$Res> get sales;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
class __$$SalesLoaderStateImplCopyWithImpl<$Res>
|
|
||||||
extends _$SalesLoaderStateCopyWithImpl<$Res, _$SalesLoaderStateImpl>
|
|
||||||
implements _$$SalesLoaderStateImplCopyWith<$Res> {
|
|
||||||
__$$SalesLoaderStateImplCopyWithImpl(
|
|
||||||
_$SalesLoaderStateImpl _value,
|
|
||||||
$Res Function(_$SalesLoaderStateImpl) _then,
|
|
||||||
) : super(_value, _then);
|
|
||||||
|
|
||||||
/// Create a copy of SalesLoaderState
|
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
|
||||||
@pragma('vm:prefer-inline')
|
|
||||||
@override
|
|
||||||
$Res call({
|
|
||||||
Object? sales = null,
|
|
||||||
Object? failureOptionSales = null,
|
|
||||||
Object? isFetching = null,
|
|
||||||
}) {
|
|
||||||
return _then(
|
|
||||||
_$SalesLoaderStateImpl(
|
|
||||||
sales: null == sales
|
|
||||||
? _value.sales
|
|
||||||
: sales // ignore: cast_nullable_to_non_nullable
|
|
||||||
as SalesAnalytic,
|
|
||||||
failureOptionSales: null == failureOptionSales
|
|
||||||
? _value.failureOptionSales
|
|
||||||
: failureOptionSales // ignore: cast_nullable_to_non_nullable
|
|
||||||
as Option<AnalyticFailure>,
|
|
||||||
isFetching: null == isFetching
|
|
||||||
? _value.isFetching
|
|
||||||
: isFetching // ignore: cast_nullable_to_non_nullable
|
|
||||||
as bool,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
|
|
||||||
class _$SalesLoaderStateImpl implements _SalesLoaderState {
|
|
||||||
const _$SalesLoaderStateImpl({
|
|
||||||
required this.sales,
|
|
||||||
required this.failureOptionSales,
|
|
||||||
this.isFetching = false,
|
|
||||||
});
|
|
||||||
|
|
||||||
@override
|
|
||||||
final SalesAnalytic sales;
|
|
||||||
@override
|
|
||||||
final Option<AnalyticFailure> failureOptionSales;
|
|
||||||
@override
|
|
||||||
@JsonKey()
|
|
||||||
final bool isFetching;
|
|
||||||
|
|
||||||
@override
|
|
||||||
String toString() {
|
|
||||||
return 'SalesLoaderState(sales: $sales, failureOptionSales: $failureOptionSales, isFetching: $isFetching)';
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
bool operator ==(Object other) {
|
|
||||||
return identical(this, other) ||
|
|
||||||
(other.runtimeType == runtimeType &&
|
|
||||||
other is _$SalesLoaderStateImpl &&
|
|
||||||
(identical(other.sales, sales) || other.sales == sales) &&
|
|
||||||
(identical(other.failureOptionSales, failureOptionSales) ||
|
|
||||||
other.failureOptionSales == failureOptionSales) &&
|
|
||||||
(identical(other.isFetching, isFetching) ||
|
|
||||||
other.isFetching == isFetching));
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
int get hashCode =>
|
|
||||||
Object.hash(runtimeType, sales, failureOptionSales, isFetching);
|
|
||||||
|
|
||||||
/// Create a copy of SalesLoaderState
|
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
|
||||||
@override
|
|
||||||
@pragma('vm:prefer-inline')
|
|
||||||
_$$SalesLoaderStateImplCopyWith<_$SalesLoaderStateImpl> get copyWith =>
|
|
||||||
__$$SalesLoaderStateImplCopyWithImpl<_$SalesLoaderStateImpl>(
|
|
||||||
this,
|
|
||||||
_$identity,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract class _SalesLoaderState implements SalesLoaderState {
|
|
||||||
const factory _SalesLoaderState({
|
|
||||||
required final SalesAnalytic sales,
|
|
||||||
required final Option<AnalyticFailure> failureOptionSales,
|
|
||||||
final bool isFetching,
|
|
||||||
}) = _$SalesLoaderStateImpl;
|
|
||||||
|
|
||||||
@override
|
|
||||||
SalesAnalytic get sales;
|
|
||||||
@override
|
|
||||||
Option<AnalyticFailure> get failureOptionSales;
|
|
||||||
@override
|
|
||||||
bool get isFetching;
|
|
||||||
|
|
||||||
/// Create a copy of SalesLoaderState
|
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
|
||||||
@override
|
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
|
||||||
_$$SalesLoaderStateImplCopyWith<_$SalesLoaderStateImpl> get copyWith =>
|
|
||||||
throw _privateConstructorUsedError;
|
|
||||||
}
|
|
||||||
@ -1,6 +0,0 @@
|
|||||||
part of 'sales_loader_bloc.dart';
|
|
||||||
|
|
||||||
@freezed
|
|
||||||
class SalesLoaderEvent with _$SalesLoaderEvent {
|
|
||||||
const factory SalesLoaderEvent.fectched() = _Fectched;
|
|
||||||
}
|
|
||||||
@ -1,15 +0,0 @@
|
|||||||
part of 'sales_loader_bloc.dart';
|
|
||||||
|
|
||||||
@freezed
|
|
||||||
class SalesLoaderState with _$SalesLoaderState {
|
|
||||||
const factory SalesLoaderState({
|
|
||||||
required SalesAnalytic sales,
|
|
||||||
required Option<AnalyticFailure> failureOptionSales,
|
|
||||||
@Default(false) bool isFetching,
|
|
||||||
}) = _SalesLoaderState;
|
|
||||||
|
|
||||||
factory SalesLoaderState.initial() => SalesLoaderState(
|
|
||||||
sales: SalesAnalytic.empty(),
|
|
||||||
failureOptionSales: none(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@ -1,55 +0,0 @@
|
|||||||
import 'package:dartz/dartz.dart';
|
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
|
||||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
|
||||||
import 'package:injectable/injectable.dart';
|
|
||||||
|
|
||||||
import '../../../domain/category/category.dart';
|
|
||||||
|
|
||||||
part 'category_loader_event.dart';
|
|
||||||
part 'category_loader_state.dart';
|
|
||||||
part 'category_loader_bloc.freezed.dart';
|
|
||||||
|
|
||||||
@injectable
|
|
||||||
class CategoryLoaderBloc
|
|
||||||
extends Bloc<CategoryLoaderEvent, CategoryLoaderState> {
|
|
||||||
final ICategoryRepository _repository;
|
|
||||||
CategoryLoaderBloc(this._repository) : super(CategoryLoaderState.initial()) {
|
|
||||||
on<CategoryLoaderEvent>(_onCategoryLoaderEvent);
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> _onCategoryLoaderEvent(
|
|
||||||
CategoryLoaderEvent event,
|
|
||||||
Emitter<CategoryLoaderState> emit,
|
|
||||||
) {
|
|
||||||
return event.map(
|
|
||||||
fetched: (e) async {
|
|
||||||
emit(state.copyWith(isFetching: true, failureOptionCategory: none()));
|
|
||||||
|
|
||||||
final result = await _repository.get();
|
|
||||||
|
|
||||||
result.fold(
|
|
||||||
(f) {
|
|
||||||
emit(
|
|
||||||
state.copyWith(
|
|
||||||
isFetching: false,
|
|
||||||
failureOptionCategory: optionOf(f),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
(categories) {
|
|
||||||
// tambahkan "All Data" di awal list
|
|
||||||
final updatedCategories = [Category.addAllData(), ...categories];
|
|
||||||
|
|
||||||
emit(
|
|
||||||
state.copyWith(
|
|
||||||
isFetching: false,
|
|
||||||
categories: updatedCategories,
|
|
||||||
failureOptionCategory: none(),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,370 +0,0 @@
|
|||||||
// 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 'category_loader_bloc.dart';
|
|
||||||
|
|
||||||
// **************************************************************************
|
|
||||||
// FreezedGenerator
|
|
||||||
// **************************************************************************
|
|
||||||
|
|
||||||
T _$identity<T>(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 _$CategoryLoaderEvent {
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult when<TResult extends Object?>({
|
|
||||||
required TResult Function() fetched,
|
|
||||||
}) => throw _privateConstructorUsedError;
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult? whenOrNull<TResult extends Object?>({
|
|
||||||
TResult? Function()? fetched,
|
|
||||||
}) => throw _privateConstructorUsedError;
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult maybeWhen<TResult extends Object?>({
|
|
||||||
TResult Function()? fetched,
|
|
||||||
required TResult orElse(),
|
|
||||||
}) => throw _privateConstructorUsedError;
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult map<TResult extends Object?>({
|
|
||||||
required TResult Function(_Fetched value) fetched,
|
|
||||||
}) => throw _privateConstructorUsedError;
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult? mapOrNull<TResult extends Object?>({
|
|
||||||
TResult? Function(_Fetched value)? fetched,
|
|
||||||
}) => throw _privateConstructorUsedError;
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult maybeMap<TResult extends Object?>({
|
|
||||||
TResult Function(_Fetched value)? fetched,
|
|
||||||
required TResult orElse(),
|
|
||||||
}) => throw _privateConstructorUsedError;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
abstract class $CategoryLoaderEventCopyWith<$Res> {
|
|
||||||
factory $CategoryLoaderEventCopyWith(
|
|
||||||
CategoryLoaderEvent value,
|
|
||||||
$Res Function(CategoryLoaderEvent) then,
|
|
||||||
) = _$CategoryLoaderEventCopyWithImpl<$Res, CategoryLoaderEvent>;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
class _$CategoryLoaderEventCopyWithImpl<$Res, $Val extends CategoryLoaderEvent>
|
|
||||||
implements $CategoryLoaderEventCopyWith<$Res> {
|
|
||||||
_$CategoryLoaderEventCopyWithImpl(this._value, this._then);
|
|
||||||
|
|
||||||
// ignore: unused_field
|
|
||||||
final $Val _value;
|
|
||||||
// ignore: unused_field
|
|
||||||
final $Res Function($Val) _then;
|
|
||||||
|
|
||||||
/// Create a copy of CategoryLoaderEvent
|
|
||||||
/// 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 _$CategoryLoaderEventCopyWithImpl<$Res, _$FetchedImpl>
|
|
||||||
implements _$$FetchedImplCopyWith<$Res> {
|
|
||||||
__$$FetchedImplCopyWithImpl(
|
|
||||||
_$FetchedImpl _value,
|
|
||||||
$Res Function(_$FetchedImpl) _then,
|
|
||||||
) : super(_value, _then);
|
|
||||||
|
|
||||||
/// Create a copy of CategoryLoaderEvent
|
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
|
|
||||||
class _$FetchedImpl implements _Fetched {
|
|
||||||
const _$FetchedImpl();
|
|
||||||
|
|
||||||
@override
|
|
||||||
String toString() {
|
|
||||||
return 'CategoryLoaderEvent.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<TResult extends Object?>({required TResult Function() fetched}) {
|
|
||||||
return fetched();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult? whenOrNull<TResult extends Object?>({TResult? Function()? fetched}) {
|
|
||||||
return fetched?.call();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult maybeWhen<TResult extends Object?>({
|
|
||||||
TResult Function()? fetched,
|
|
||||||
required TResult orElse(),
|
|
||||||
}) {
|
|
||||||
if (fetched != null) {
|
|
||||||
return fetched();
|
|
||||||
}
|
|
||||||
return orElse();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult map<TResult extends Object?>({
|
|
||||||
required TResult Function(_Fetched value) fetched,
|
|
||||||
}) {
|
|
||||||
return fetched(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult? mapOrNull<TResult extends Object?>({
|
|
||||||
TResult? Function(_Fetched value)? fetched,
|
|
||||||
}) {
|
|
||||||
return fetched?.call(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult maybeMap<TResult extends Object?>({
|
|
||||||
TResult Function(_Fetched value)? fetched,
|
|
||||||
required TResult orElse(),
|
|
||||||
}) {
|
|
||||||
if (fetched != null) {
|
|
||||||
return fetched(this);
|
|
||||||
}
|
|
||||||
return orElse();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract class _Fetched implements CategoryLoaderEvent {
|
|
||||||
const factory _Fetched() = _$FetchedImpl;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
mixin _$CategoryLoaderState {
|
|
||||||
List<Category> get categories => throw _privateConstructorUsedError;
|
|
||||||
Option<CategoryFailure> get failureOptionCategory =>
|
|
||||||
throw _privateConstructorUsedError;
|
|
||||||
bool get isFetching => throw _privateConstructorUsedError;
|
|
||||||
|
|
||||||
/// Create a copy of CategoryLoaderState
|
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
|
||||||
$CategoryLoaderStateCopyWith<CategoryLoaderState> get copyWith =>
|
|
||||||
throw _privateConstructorUsedError;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
abstract class $CategoryLoaderStateCopyWith<$Res> {
|
|
||||||
factory $CategoryLoaderStateCopyWith(
|
|
||||||
CategoryLoaderState value,
|
|
||||||
$Res Function(CategoryLoaderState) then,
|
|
||||||
) = _$CategoryLoaderStateCopyWithImpl<$Res, CategoryLoaderState>;
|
|
||||||
@useResult
|
|
||||||
$Res call({
|
|
||||||
List<Category> categories,
|
|
||||||
Option<CategoryFailure> failureOptionCategory,
|
|
||||||
bool isFetching,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
class _$CategoryLoaderStateCopyWithImpl<$Res, $Val extends CategoryLoaderState>
|
|
||||||
implements $CategoryLoaderStateCopyWith<$Res> {
|
|
||||||
_$CategoryLoaderStateCopyWithImpl(this._value, this._then);
|
|
||||||
|
|
||||||
// ignore: unused_field
|
|
||||||
final $Val _value;
|
|
||||||
// ignore: unused_field
|
|
||||||
final $Res Function($Val) _then;
|
|
||||||
|
|
||||||
/// Create a copy of CategoryLoaderState
|
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
|
||||||
@pragma('vm:prefer-inline')
|
|
||||||
@override
|
|
||||||
$Res call({
|
|
||||||
Object? categories = null,
|
|
||||||
Object? failureOptionCategory = null,
|
|
||||||
Object? isFetching = null,
|
|
||||||
}) {
|
|
||||||
return _then(
|
|
||||||
_value.copyWith(
|
|
||||||
categories: null == categories
|
|
||||||
? _value.categories
|
|
||||||
: categories // ignore: cast_nullable_to_non_nullable
|
|
||||||
as List<Category>,
|
|
||||||
failureOptionCategory: null == failureOptionCategory
|
|
||||||
? _value.failureOptionCategory
|
|
||||||
: failureOptionCategory // ignore: cast_nullable_to_non_nullable
|
|
||||||
as Option<CategoryFailure>,
|
|
||||||
isFetching: null == isFetching
|
|
||||||
? _value.isFetching
|
|
||||||
: isFetching // ignore: cast_nullable_to_non_nullable
|
|
||||||
as bool,
|
|
||||||
)
|
|
||||||
as $Val,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
abstract class _$$CategoryLoaderStateImplCopyWith<$Res>
|
|
||||||
implements $CategoryLoaderStateCopyWith<$Res> {
|
|
||||||
factory _$$CategoryLoaderStateImplCopyWith(
|
|
||||||
_$CategoryLoaderStateImpl value,
|
|
||||||
$Res Function(_$CategoryLoaderStateImpl) then,
|
|
||||||
) = __$$CategoryLoaderStateImplCopyWithImpl<$Res>;
|
|
||||||
@override
|
|
||||||
@useResult
|
|
||||||
$Res call({
|
|
||||||
List<Category> categories,
|
|
||||||
Option<CategoryFailure> failureOptionCategory,
|
|
||||||
bool isFetching,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
class __$$CategoryLoaderStateImplCopyWithImpl<$Res>
|
|
||||||
extends _$CategoryLoaderStateCopyWithImpl<$Res, _$CategoryLoaderStateImpl>
|
|
||||||
implements _$$CategoryLoaderStateImplCopyWith<$Res> {
|
|
||||||
__$$CategoryLoaderStateImplCopyWithImpl(
|
|
||||||
_$CategoryLoaderStateImpl _value,
|
|
||||||
$Res Function(_$CategoryLoaderStateImpl) _then,
|
|
||||||
) : super(_value, _then);
|
|
||||||
|
|
||||||
/// Create a copy of CategoryLoaderState
|
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
|
||||||
@pragma('vm:prefer-inline')
|
|
||||||
@override
|
|
||||||
$Res call({
|
|
||||||
Object? categories = null,
|
|
||||||
Object? failureOptionCategory = null,
|
|
||||||
Object? isFetching = null,
|
|
||||||
}) {
|
|
||||||
return _then(
|
|
||||||
_$CategoryLoaderStateImpl(
|
|
||||||
categories: null == categories
|
|
||||||
? _value._categories
|
|
||||||
: categories // ignore: cast_nullable_to_non_nullable
|
|
||||||
as List<Category>,
|
|
||||||
failureOptionCategory: null == failureOptionCategory
|
|
||||||
? _value.failureOptionCategory
|
|
||||||
: failureOptionCategory // ignore: cast_nullable_to_non_nullable
|
|
||||||
as Option<CategoryFailure>,
|
|
||||||
isFetching: null == isFetching
|
|
||||||
? _value.isFetching
|
|
||||||
: isFetching // ignore: cast_nullable_to_non_nullable
|
|
||||||
as bool,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
|
|
||||||
class _$CategoryLoaderStateImpl implements _CategoryLoaderState {
|
|
||||||
const _$CategoryLoaderStateImpl({
|
|
||||||
required final List<Category> categories,
|
|
||||||
required this.failureOptionCategory,
|
|
||||||
this.isFetching = false,
|
|
||||||
}) : _categories = categories;
|
|
||||||
|
|
||||||
final List<Category> _categories;
|
|
||||||
@override
|
|
||||||
List<Category> get categories {
|
|
||||||
if (_categories is EqualUnmodifiableListView) return _categories;
|
|
||||||
// ignore: implicit_dynamic_type
|
|
||||||
return EqualUnmodifiableListView(_categories);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
final Option<CategoryFailure> failureOptionCategory;
|
|
||||||
@override
|
|
||||||
@JsonKey()
|
|
||||||
final bool isFetching;
|
|
||||||
|
|
||||||
@override
|
|
||||||
String toString() {
|
|
||||||
return 'CategoryLoaderState(categories: $categories, failureOptionCategory: $failureOptionCategory, isFetching: $isFetching)';
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
bool operator ==(Object other) {
|
|
||||||
return identical(this, other) ||
|
|
||||||
(other.runtimeType == runtimeType &&
|
|
||||||
other is _$CategoryLoaderStateImpl &&
|
|
||||||
const DeepCollectionEquality().equals(
|
|
||||||
other._categories,
|
|
||||||
_categories,
|
|
||||||
) &&
|
|
||||||
(identical(other.failureOptionCategory, failureOptionCategory) ||
|
|
||||||
other.failureOptionCategory == failureOptionCategory) &&
|
|
||||||
(identical(other.isFetching, isFetching) ||
|
|
||||||
other.isFetching == isFetching));
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
int get hashCode => Object.hash(
|
|
||||||
runtimeType,
|
|
||||||
const DeepCollectionEquality().hash(_categories),
|
|
||||||
failureOptionCategory,
|
|
||||||
isFetching,
|
|
||||||
);
|
|
||||||
|
|
||||||
/// Create a copy of CategoryLoaderState
|
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
|
||||||
@override
|
|
||||||
@pragma('vm:prefer-inline')
|
|
||||||
_$$CategoryLoaderStateImplCopyWith<_$CategoryLoaderStateImpl> get copyWith =>
|
|
||||||
__$$CategoryLoaderStateImplCopyWithImpl<_$CategoryLoaderStateImpl>(
|
|
||||||
this,
|
|
||||||
_$identity,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract class _CategoryLoaderState implements CategoryLoaderState {
|
|
||||||
const factory _CategoryLoaderState({
|
|
||||||
required final List<Category> categories,
|
|
||||||
required final Option<CategoryFailure> failureOptionCategory,
|
|
||||||
final bool isFetching,
|
|
||||||
}) = _$CategoryLoaderStateImpl;
|
|
||||||
|
|
||||||
@override
|
|
||||||
List<Category> get categories;
|
|
||||||
@override
|
|
||||||
Option<CategoryFailure> get failureOptionCategory;
|
|
||||||
@override
|
|
||||||
bool get isFetching;
|
|
||||||
|
|
||||||
/// Create a copy of CategoryLoaderState
|
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
|
||||||
@override
|
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
|
||||||
_$$CategoryLoaderStateImplCopyWith<_$CategoryLoaderStateImpl> get copyWith =>
|
|
||||||
throw _privateConstructorUsedError;
|
|
||||||
}
|
|
||||||
@ -1,6 +0,0 @@
|
|||||||
part of 'category_loader_bloc.dart';
|
|
||||||
|
|
||||||
@freezed
|
|
||||||
class CategoryLoaderEvent with _$CategoryLoaderEvent {
|
|
||||||
const factory CategoryLoaderEvent.fetched() = _Fetched;
|
|
||||||
}
|
|
||||||
@ -1,13 +0,0 @@
|
|||||||
part of 'category_loader_bloc.dart';
|
|
||||||
|
|
||||||
@freezed
|
|
||||||
class CategoryLoaderState with _$CategoryLoaderState {
|
|
||||||
const factory CategoryLoaderState({
|
|
||||||
required List<Category> categories,
|
|
||||||
required Option<CategoryFailure> failureOptionCategory,
|
|
||||||
@Default(false) bool isFetching,
|
|
||||||
}) = _CategoryLoaderState;
|
|
||||||
|
|
||||||
factory CategoryLoaderState.initial() =>
|
|
||||||
CategoryLoaderState(categories: [], failureOptionCategory: none());
|
|
||||||
}
|
|
||||||
@ -1,92 +0,0 @@
|
|||||||
import 'package:dartz/dartz.dart';
|
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
|
||||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
|
||||||
import 'package:injectable/injectable.dart';
|
|
||||||
|
|
||||||
import '../../../domain/product/product.dart';
|
|
||||||
|
|
||||||
part 'product_loader_event.dart';
|
|
||||||
part 'product_loader_state.dart';
|
|
||||||
part 'product_loader_bloc.freezed.dart';
|
|
||||||
|
|
||||||
@injectable
|
|
||||||
class ProductLoaderBloc extends Bloc<ProductLoaderEvent, ProductLoaderState> {
|
|
||||||
final IProductRepository _productRepository;
|
|
||||||
|
|
||||||
ProductLoaderBloc(this._productRepository)
|
|
||||||
: super(ProductLoaderState.initial()) {
|
|
||||||
on<ProductLoaderEvent>(_onProductLoaderEvent);
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> _onProductLoaderEvent(
|
|
||||||
ProductLoaderEvent event,
|
|
||||||
Emitter<ProductLoaderState> emit,
|
|
||||||
) {
|
|
||||||
return event.map(
|
|
||||||
categoryIdChanged: (e) async {
|
|
||||||
emit(state.copyWith(categoryId: e.categoryId));
|
|
||||||
},
|
|
||||||
searchChanged: (e) async {
|
|
||||||
emit(state.copyWith(search: e.search));
|
|
||||||
},
|
|
||||||
fetched: (e) async {
|
|
||||||
var newState = state;
|
|
||||||
|
|
||||||
if (e.isRefresh) {
|
|
||||||
newState = state.copyWith(isFetching: true);
|
|
||||||
|
|
||||||
emit(newState);
|
|
||||||
}
|
|
||||||
|
|
||||||
newState = await _mapFetchedToState(state, isRefresh: e.isRefresh);
|
|
||||||
|
|
||||||
emit(newState);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<ProductLoaderState> _mapFetchedToState(
|
|
||||||
ProductLoaderState state, {
|
|
||||||
bool isRefresh = false,
|
|
||||||
}) async {
|
|
||||||
state = state.copyWith(isFetching: false);
|
|
||||||
|
|
||||||
if (state.hasReachedMax && state.products.isNotEmpty && !isRefresh) {
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isRefresh) {
|
|
||||||
state = state.copyWith(
|
|
||||||
page: 1,
|
|
||||||
failureOptionProduct: none(),
|
|
||||||
hasReachedMax: false,
|
|
||||||
products: [],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
final failureOrProduct = await _productRepository.get(
|
|
||||||
categoryId: state.categoryId,
|
|
||||||
page: state.page,
|
|
||||||
search: state.search,
|
|
||||||
);
|
|
||||||
|
|
||||||
state = failureOrProduct.fold(
|
|
||||||
(f) {
|
|
||||||
if (state.products.isNotEmpty) {
|
|
||||||
return state.copyWith(hasReachedMax: true);
|
|
||||||
}
|
|
||||||
return state.copyWith(failureOptionProduct: optionOf(f));
|
|
||||||
},
|
|
||||||
(products) {
|
|
||||||
return state.copyWith(
|
|
||||||
products: List.from(state.products)..addAll(products),
|
|
||||||
failureOptionProduct: none(),
|
|
||||||
page: state.page + 1,
|
|
||||||
hasReachedMax: products.length < 10,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,821 +0,0 @@
|
|||||||
// 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 'product_loader_bloc.dart';
|
|
||||||
|
|
||||||
// **************************************************************************
|
|
||||||
// FreezedGenerator
|
|
||||||
// **************************************************************************
|
|
||||||
|
|
||||||
T _$identity<T>(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 _$ProductLoaderEvent {
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult when<TResult extends Object?>({
|
|
||||||
required TResult Function(String categoryId) categoryIdChanged,
|
|
||||||
required TResult Function(String search) searchChanged,
|
|
||||||
required TResult Function(bool isRefresh) fetched,
|
|
||||||
}) => throw _privateConstructorUsedError;
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult? whenOrNull<TResult extends Object?>({
|
|
||||||
TResult? Function(String categoryId)? categoryIdChanged,
|
|
||||||
TResult? Function(String search)? searchChanged,
|
|
||||||
TResult? Function(bool isRefresh)? fetched,
|
|
||||||
}) => throw _privateConstructorUsedError;
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult maybeWhen<TResult extends Object?>({
|
|
||||||
TResult Function(String categoryId)? categoryIdChanged,
|
|
||||||
TResult Function(String search)? searchChanged,
|
|
||||||
TResult Function(bool isRefresh)? fetched,
|
|
||||||
required TResult orElse(),
|
|
||||||
}) => throw _privateConstructorUsedError;
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult map<TResult extends Object?>({
|
|
||||||
required TResult Function(_CategoryIdChanged value) categoryIdChanged,
|
|
||||||
required TResult Function(_SearchChanged value) searchChanged,
|
|
||||||
required TResult Function(_Fetched value) fetched,
|
|
||||||
}) => throw _privateConstructorUsedError;
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult? mapOrNull<TResult extends Object?>({
|
|
||||||
TResult? Function(_CategoryIdChanged value)? categoryIdChanged,
|
|
||||||
TResult? Function(_SearchChanged value)? searchChanged,
|
|
||||||
TResult? Function(_Fetched value)? fetched,
|
|
||||||
}) => throw _privateConstructorUsedError;
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult maybeMap<TResult extends Object?>({
|
|
||||||
TResult Function(_CategoryIdChanged value)? categoryIdChanged,
|
|
||||||
TResult Function(_SearchChanged value)? searchChanged,
|
|
||||||
TResult Function(_Fetched value)? fetched,
|
|
||||||
required TResult orElse(),
|
|
||||||
}) => throw _privateConstructorUsedError;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
abstract class $ProductLoaderEventCopyWith<$Res> {
|
|
||||||
factory $ProductLoaderEventCopyWith(
|
|
||||||
ProductLoaderEvent value,
|
|
||||||
$Res Function(ProductLoaderEvent) then,
|
|
||||||
) = _$ProductLoaderEventCopyWithImpl<$Res, ProductLoaderEvent>;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
class _$ProductLoaderEventCopyWithImpl<$Res, $Val extends ProductLoaderEvent>
|
|
||||||
implements $ProductLoaderEventCopyWith<$Res> {
|
|
||||||
_$ProductLoaderEventCopyWithImpl(this._value, this._then);
|
|
||||||
|
|
||||||
// ignore: unused_field
|
|
||||||
final $Val _value;
|
|
||||||
// ignore: unused_field
|
|
||||||
final $Res Function($Val) _then;
|
|
||||||
|
|
||||||
/// Create a copy of ProductLoaderEvent
|
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
abstract class _$$CategoryIdChangedImplCopyWith<$Res> {
|
|
||||||
factory _$$CategoryIdChangedImplCopyWith(
|
|
||||||
_$CategoryIdChangedImpl value,
|
|
||||||
$Res Function(_$CategoryIdChangedImpl) then,
|
|
||||||
) = __$$CategoryIdChangedImplCopyWithImpl<$Res>;
|
|
||||||
@useResult
|
|
||||||
$Res call({String categoryId});
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
class __$$CategoryIdChangedImplCopyWithImpl<$Res>
|
|
||||||
extends _$ProductLoaderEventCopyWithImpl<$Res, _$CategoryIdChangedImpl>
|
|
||||||
implements _$$CategoryIdChangedImplCopyWith<$Res> {
|
|
||||||
__$$CategoryIdChangedImplCopyWithImpl(
|
|
||||||
_$CategoryIdChangedImpl _value,
|
|
||||||
$Res Function(_$CategoryIdChangedImpl) _then,
|
|
||||||
) : super(_value, _then);
|
|
||||||
|
|
||||||
/// Create a copy of ProductLoaderEvent
|
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
|
||||||
@pragma('vm:prefer-inline')
|
|
||||||
@override
|
|
||||||
$Res call({Object? categoryId = null}) {
|
|
||||||
return _then(
|
|
||||||
_$CategoryIdChangedImpl(
|
|
||||||
null == categoryId
|
|
||||||
? _value.categoryId
|
|
||||||
: categoryId // ignore: cast_nullable_to_non_nullable
|
|
||||||
as String,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
|
|
||||||
class _$CategoryIdChangedImpl implements _CategoryIdChanged {
|
|
||||||
const _$CategoryIdChangedImpl(this.categoryId);
|
|
||||||
|
|
||||||
@override
|
|
||||||
final String categoryId;
|
|
||||||
|
|
||||||
@override
|
|
||||||
String toString() {
|
|
||||||
return 'ProductLoaderEvent.categoryIdChanged(categoryId: $categoryId)';
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
bool operator ==(Object other) {
|
|
||||||
return identical(this, other) ||
|
|
||||||
(other.runtimeType == runtimeType &&
|
|
||||||
other is _$CategoryIdChangedImpl &&
|
|
||||||
(identical(other.categoryId, categoryId) ||
|
|
||||||
other.categoryId == categoryId));
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
int get hashCode => Object.hash(runtimeType, categoryId);
|
|
||||||
|
|
||||||
/// Create a copy of ProductLoaderEvent
|
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
|
||||||
@override
|
|
||||||
@pragma('vm:prefer-inline')
|
|
||||||
_$$CategoryIdChangedImplCopyWith<_$CategoryIdChangedImpl> get copyWith =>
|
|
||||||
__$$CategoryIdChangedImplCopyWithImpl<_$CategoryIdChangedImpl>(
|
|
||||||
this,
|
|
||||||
_$identity,
|
|
||||||
);
|
|
||||||
|
|
||||||
@override
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult when<TResult extends Object?>({
|
|
||||||
required TResult Function(String categoryId) categoryIdChanged,
|
|
||||||
required TResult Function(String search) searchChanged,
|
|
||||||
required TResult Function(bool isRefresh) fetched,
|
|
||||||
}) {
|
|
||||||
return categoryIdChanged(categoryId);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult? whenOrNull<TResult extends Object?>({
|
|
||||||
TResult? Function(String categoryId)? categoryIdChanged,
|
|
||||||
TResult? Function(String search)? searchChanged,
|
|
||||||
TResult? Function(bool isRefresh)? fetched,
|
|
||||||
}) {
|
|
||||||
return categoryIdChanged?.call(categoryId);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult maybeWhen<TResult extends Object?>({
|
|
||||||
TResult Function(String categoryId)? categoryIdChanged,
|
|
||||||
TResult Function(String search)? searchChanged,
|
|
||||||
TResult Function(bool isRefresh)? fetched,
|
|
||||||
required TResult orElse(),
|
|
||||||
}) {
|
|
||||||
if (categoryIdChanged != null) {
|
|
||||||
return categoryIdChanged(categoryId);
|
|
||||||
}
|
|
||||||
return orElse();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult map<TResult extends Object?>({
|
|
||||||
required TResult Function(_CategoryIdChanged value) categoryIdChanged,
|
|
||||||
required TResult Function(_SearchChanged value) searchChanged,
|
|
||||||
required TResult Function(_Fetched value) fetched,
|
|
||||||
}) {
|
|
||||||
return categoryIdChanged(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult? mapOrNull<TResult extends Object?>({
|
|
||||||
TResult? Function(_CategoryIdChanged value)? categoryIdChanged,
|
|
||||||
TResult? Function(_SearchChanged value)? searchChanged,
|
|
||||||
TResult? Function(_Fetched value)? fetched,
|
|
||||||
}) {
|
|
||||||
return categoryIdChanged?.call(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult maybeMap<TResult extends Object?>({
|
|
||||||
TResult Function(_CategoryIdChanged value)? categoryIdChanged,
|
|
||||||
TResult Function(_SearchChanged value)? searchChanged,
|
|
||||||
TResult Function(_Fetched value)? fetched,
|
|
||||||
required TResult orElse(),
|
|
||||||
}) {
|
|
||||||
if (categoryIdChanged != null) {
|
|
||||||
return categoryIdChanged(this);
|
|
||||||
}
|
|
||||||
return orElse();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract class _CategoryIdChanged implements ProductLoaderEvent {
|
|
||||||
const factory _CategoryIdChanged(final String categoryId) =
|
|
||||||
_$CategoryIdChangedImpl;
|
|
||||||
|
|
||||||
String get categoryId;
|
|
||||||
|
|
||||||
/// Create a copy of ProductLoaderEvent
|
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
|
||||||
_$$CategoryIdChangedImplCopyWith<_$CategoryIdChangedImpl> get copyWith =>
|
|
||||||
throw _privateConstructorUsedError;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
abstract class _$$SearchChangedImplCopyWith<$Res> {
|
|
||||||
factory _$$SearchChangedImplCopyWith(
|
|
||||||
_$SearchChangedImpl value,
|
|
||||||
$Res Function(_$SearchChangedImpl) then,
|
|
||||||
) = __$$SearchChangedImplCopyWithImpl<$Res>;
|
|
||||||
@useResult
|
|
||||||
$Res call({String search});
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
class __$$SearchChangedImplCopyWithImpl<$Res>
|
|
||||||
extends _$ProductLoaderEventCopyWithImpl<$Res, _$SearchChangedImpl>
|
|
||||||
implements _$$SearchChangedImplCopyWith<$Res> {
|
|
||||||
__$$SearchChangedImplCopyWithImpl(
|
|
||||||
_$SearchChangedImpl _value,
|
|
||||||
$Res Function(_$SearchChangedImpl) _then,
|
|
||||||
) : super(_value, _then);
|
|
||||||
|
|
||||||
/// Create a copy of ProductLoaderEvent
|
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
|
||||||
@pragma('vm:prefer-inline')
|
|
||||||
@override
|
|
||||||
$Res call({Object? search = null}) {
|
|
||||||
return _then(
|
|
||||||
_$SearchChangedImpl(
|
|
||||||
null == search
|
|
||||||
? _value.search
|
|
||||||
: search // ignore: cast_nullable_to_non_nullable
|
|
||||||
as String,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
|
|
||||||
class _$SearchChangedImpl implements _SearchChanged {
|
|
||||||
const _$SearchChangedImpl(this.search);
|
|
||||||
|
|
||||||
@override
|
|
||||||
final String search;
|
|
||||||
|
|
||||||
@override
|
|
||||||
String toString() {
|
|
||||||
return 'ProductLoaderEvent.searchChanged(search: $search)';
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
bool operator ==(Object other) {
|
|
||||||
return identical(this, other) ||
|
|
||||||
(other.runtimeType == runtimeType &&
|
|
||||||
other is _$SearchChangedImpl &&
|
|
||||||
(identical(other.search, search) || other.search == search));
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
int get hashCode => Object.hash(runtimeType, search);
|
|
||||||
|
|
||||||
/// Create a copy of ProductLoaderEvent
|
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
|
||||||
@override
|
|
||||||
@pragma('vm:prefer-inline')
|
|
||||||
_$$SearchChangedImplCopyWith<_$SearchChangedImpl> get copyWith =>
|
|
||||||
__$$SearchChangedImplCopyWithImpl<_$SearchChangedImpl>(this, _$identity);
|
|
||||||
|
|
||||||
@override
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult when<TResult extends Object?>({
|
|
||||||
required TResult Function(String categoryId) categoryIdChanged,
|
|
||||||
required TResult Function(String search) searchChanged,
|
|
||||||
required TResult Function(bool isRefresh) fetched,
|
|
||||||
}) {
|
|
||||||
return searchChanged(search);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult? whenOrNull<TResult extends Object?>({
|
|
||||||
TResult? Function(String categoryId)? categoryIdChanged,
|
|
||||||
TResult? Function(String search)? searchChanged,
|
|
||||||
TResult? Function(bool isRefresh)? fetched,
|
|
||||||
}) {
|
|
||||||
return searchChanged?.call(search);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult maybeWhen<TResult extends Object?>({
|
|
||||||
TResult Function(String categoryId)? categoryIdChanged,
|
|
||||||
TResult Function(String search)? searchChanged,
|
|
||||||
TResult Function(bool isRefresh)? fetched,
|
|
||||||
required TResult orElse(),
|
|
||||||
}) {
|
|
||||||
if (searchChanged != null) {
|
|
||||||
return searchChanged(search);
|
|
||||||
}
|
|
||||||
return orElse();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult map<TResult extends Object?>({
|
|
||||||
required TResult Function(_CategoryIdChanged value) categoryIdChanged,
|
|
||||||
required TResult Function(_SearchChanged value) searchChanged,
|
|
||||||
required TResult Function(_Fetched value) fetched,
|
|
||||||
}) {
|
|
||||||
return searchChanged(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult? mapOrNull<TResult extends Object?>({
|
|
||||||
TResult? Function(_CategoryIdChanged value)? categoryIdChanged,
|
|
||||||
TResult? Function(_SearchChanged value)? searchChanged,
|
|
||||||
TResult? Function(_Fetched value)? fetched,
|
|
||||||
}) {
|
|
||||||
return searchChanged?.call(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult maybeMap<TResult extends Object?>({
|
|
||||||
TResult Function(_CategoryIdChanged value)? categoryIdChanged,
|
|
||||||
TResult Function(_SearchChanged value)? searchChanged,
|
|
||||||
TResult Function(_Fetched value)? fetched,
|
|
||||||
required TResult orElse(),
|
|
||||||
}) {
|
|
||||||
if (searchChanged != null) {
|
|
||||||
return searchChanged(this);
|
|
||||||
}
|
|
||||||
return orElse();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract class _SearchChanged implements ProductLoaderEvent {
|
|
||||||
const factory _SearchChanged(final String search) = _$SearchChangedImpl;
|
|
||||||
|
|
||||||
String get search;
|
|
||||||
|
|
||||||
/// Create a copy of ProductLoaderEvent
|
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
|
||||||
_$$SearchChangedImplCopyWith<_$SearchChangedImpl> get copyWith =>
|
|
||||||
throw _privateConstructorUsedError;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
abstract class _$$FetchedImplCopyWith<$Res> {
|
|
||||||
factory _$$FetchedImplCopyWith(
|
|
||||||
_$FetchedImpl value,
|
|
||||||
$Res Function(_$FetchedImpl) then,
|
|
||||||
) = __$$FetchedImplCopyWithImpl<$Res>;
|
|
||||||
@useResult
|
|
||||||
$Res call({bool isRefresh});
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
class __$$FetchedImplCopyWithImpl<$Res>
|
|
||||||
extends _$ProductLoaderEventCopyWithImpl<$Res, _$FetchedImpl>
|
|
||||||
implements _$$FetchedImplCopyWith<$Res> {
|
|
||||||
__$$FetchedImplCopyWithImpl(
|
|
||||||
_$FetchedImpl _value,
|
|
||||||
$Res Function(_$FetchedImpl) _then,
|
|
||||||
) : super(_value, _then);
|
|
||||||
|
|
||||||
/// Create a copy of ProductLoaderEvent
|
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
|
||||||
@pragma('vm:prefer-inline')
|
|
||||||
@override
|
|
||||||
$Res call({Object? isRefresh = null}) {
|
|
||||||
return _then(
|
|
||||||
_$FetchedImpl(
|
|
||||||
isRefresh: null == isRefresh
|
|
||||||
? _value.isRefresh
|
|
||||||
: isRefresh // ignore: cast_nullable_to_non_nullable
|
|
||||||
as bool,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
|
|
||||||
class _$FetchedImpl implements _Fetched {
|
|
||||||
const _$FetchedImpl({this.isRefresh = false});
|
|
||||||
|
|
||||||
@override
|
|
||||||
@JsonKey()
|
|
||||||
final bool isRefresh;
|
|
||||||
|
|
||||||
@override
|
|
||||||
String toString() {
|
|
||||||
return 'ProductLoaderEvent.fetched(isRefresh: $isRefresh)';
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
bool operator ==(Object other) {
|
|
||||||
return identical(this, other) ||
|
|
||||||
(other.runtimeType == runtimeType &&
|
|
||||||
other is _$FetchedImpl &&
|
|
||||||
(identical(other.isRefresh, isRefresh) ||
|
|
||||||
other.isRefresh == isRefresh));
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
int get hashCode => Object.hash(runtimeType, isRefresh);
|
|
||||||
|
|
||||||
/// Create a copy of ProductLoaderEvent
|
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
|
||||||
@override
|
|
||||||
@pragma('vm:prefer-inline')
|
|
||||||
_$$FetchedImplCopyWith<_$FetchedImpl> get copyWith =>
|
|
||||||
__$$FetchedImplCopyWithImpl<_$FetchedImpl>(this, _$identity);
|
|
||||||
|
|
||||||
@override
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult when<TResult extends Object?>({
|
|
||||||
required TResult Function(String categoryId) categoryIdChanged,
|
|
||||||
required TResult Function(String search) searchChanged,
|
|
||||||
required TResult Function(bool isRefresh) fetched,
|
|
||||||
}) {
|
|
||||||
return fetched(isRefresh);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult? whenOrNull<TResult extends Object?>({
|
|
||||||
TResult? Function(String categoryId)? categoryIdChanged,
|
|
||||||
TResult? Function(String search)? searchChanged,
|
|
||||||
TResult? Function(bool isRefresh)? fetched,
|
|
||||||
}) {
|
|
||||||
return fetched?.call(isRefresh);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult maybeWhen<TResult extends Object?>({
|
|
||||||
TResult Function(String categoryId)? categoryIdChanged,
|
|
||||||
TResult Function(String search)? searchChanged,
|
|
||||||
TResult Function(bool isRefresh)? fetched,
|
|
||||||
required TResult orElse(),
|
|
||||||
}) {
|
|
||||||
if (fetched != null) {
|
|
||||||
return fetched(isRefresh);
|
|
||||||
}
|
|
||||||
return orElse();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult map<TResult extends Object?>({
|
|
||||||
required TResult Function(_CategoryIdChanged value) categoryIdChanged,
|
|
||||||
required TResult Function(_SearchChanged value) searchChanged,
|
|
||||||
required TResult Function(_Fetched value) fetched,
|
|
||||||
}) {
|
|
||||||
return fetched(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult? mapOrNull<TResult extends Object?>({
|
|
||||||
TResult? Function(_CategoryIdChanged value)? categoryIdChanged,
|
|
||||||
TResult? Function(_SearchChanged value)? searchChanged,
|
|
||||||
TResult? Function(_Fetched value)? fetched,
|
|
||||||
}) {
|
|
||||||
return fetched?.call(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult maybeMap<TResult extends Object?>({
|
|
||||||
TResult Function(_CategoryIdChanged value)? categoryIdChanged,
|
|
||||||
TResult Function(_SearchChanged value)? searchChanged,
|
|
||||||
TResult Function(_Fetched value)? fetched,
|
|
||||||
required TResult orElse(),
|
|
||||||
}) {
|
|
||||||
if (fetched != null) {
|
|
||||||
return fetched(this);
|
|
||||||
}
|
|
||||||
return orElse();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract class _Fetched implements ProductLoaderEvent {
|
|
||||||
const factory _Fetched({final bool isRefresh}) = _$FetchedImpl;
|
|
||||||
|
|
||||||
bool get isRefresh;
|
|
||||||
|
|
||||||
/// Create a copy of ProductLoaderEvent
|
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
|
||||||
_$$FetchedImplCopyWith<_$FetchedImpl> get copyWith =>
|
|
||||||
throw _privateConstructorUsedError;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
mixin _$ProductLoaderState {
|
|
||||||
List<Product> get products => throw _privateConstructorUsedError;
|
|
||||||
Option<ProductFailure> get failureOptionProduct =>
|
|
||||||
throw _privateConstructorUsedError;
|
|
||||||
String? get categoryId => throw _privateConstructorUsedError;
|
|
||||||
String? get search => throw _privateConstructorUsedError;
|
|
||||||
bool get isFetching => throw _privateConstructorUsedError;
|
|
||||||
bool get hasReachedMax => throw _privateConstructorUsedError;
|
|
||||||
int get page => throw _privateConstructorUsedError;
|
|
||||||
|
|
||||||
/// Create a copy of ProductLoaderState
|
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
|
||||||
$ProductLoaderStateCopyWith<ProductLoaderState> get copyWith =>
|
|
||||||
throw _privateConstructorUsedError;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
abstract class $ProductLoaderStateCopyWith<$Res> {
|
|
||||||
factory $ProductLoaderStateCopyWith(
|
|
||||||
ProductLoaderState value,
|
|
||||||
$Res Function(ProductLoaderState) then,
|
|
||||||
) = _$ProductLoaderStateCopyWithImpl<$Res, ProductLoaderState>;
|
|
||||||
@useResult
|
|
||||||
$Res call({
|
|
||||||
List<Product> products,
|
|
||||||
Option<ProductFailure> failureOptionProduct,
|
|
||||||
String? categoryId,
|
|
||||||
String? search,
|
|
||||||
bool isFetching,
|
|
||||||
bool hasReachedMax,
|
|
||||||
int page,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
class _$ProductLoaderStateCopyWithImpl<$Res, $Val extends ProductLoaderState>
|
|
||||||
implements $ProductLoaderStateCopyWith<$Res> {
|
|
||||||
_$ProductLoaderStateCopyWithImpl(this._value, this._then);
|
|
||||||
|
|
||||||
// ignore: unused_field
|
|
||||||
final $Val _value;
|
|
||||||
// ignore: unused_field
|
|
||||||
final $Res Function($Val) _then;
|
|
||||||
|
|
||||||
/// Create a copy of ProductLoaderState
|
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
|
||||||
@pragma('vm:prefer-inline')
|
|
||||||
@override
|
|
||||||
$Res call({
|
|
||||||
Object? products = null,
|
|
||||||
Object? failureOptionProduct = null,
|
|
||||||
Object? categoryId = freezed,
|
|
||||||
Object? search = freezed,
|
|
||||||
Object? isFetching = null,
|
|
||||||
Object? hasReachedMax = null,
|
|
||||||
Object? page = null,
|
|
||||||
}) {
|
|
||||||
return _then(
|
|
||||||
_value.copyWith(
|
|
||||||
products: null == products
|
|
||||||
? _value.products
|
|
||||||
: products // ignore: cast_nullable_to_non_nullable
|
|
||||||
as List<Product>,
|
|
||||||
failureOptionProduct: null == failureOptionProduct
|
|
||||||
? _value.failureOptionProduct
|
|
||||||
: failureOptionProduct // ignore: cast_nullable_to_non_nullable
|
|
||||||
as Option<ProductFailure>,
|
|
||||||
categoryId: freezed == categoryId
|
|
||||||
? _value.categoryId
|
|
||||||
: categoryId // ignore: cast_nullable_to_non_nullable
|
|
||||||
as String?,
|
|
||||||
search: freezed == search
|
|
||||||
? _value.search
|
|
||||||
: search // ignore: cast_nullable_to_non_nullable
|
|
||||||
as String?,
|
|
||||||
isFetching: null == isFetching
|
|
||||||
? _value.isFetching
|
|
||||||
: isFetching // ignore: cast_nullable_to_non_nullable
|
|
||||||
as bool,
|
|
||||||
hasReachedMax: null == hasReachedMax
|
|
||||||
? _value.hasReachedMax
|
|
||||||
: hasReachedMax // ignore: cast_nullable_to_non_nullable
|
|
||||||
as bool,
|
|
||||||
page: null == page
|
|
||||||
? _value.page
|
|
||||||
: page // ignore: cast_nullable_to_non_nullable
|
|
||||||
as int,
|
|
||||||
)
|
|
||||||
as $Val,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
abstract class _$$ProductLoaderStateImplCopyWith<$Res>
|
|
||||||
implements $ProductLoaderStateCopyWith<$Res> {
|
|
||||||
factory _$$ProductLoaderStateImplCopyWith(
|
|
||||||
_$ProductLoaderStateImpl value,
|
|
||||||
$Res Function(_$ProductLoaderStateImpl) then,
|
|
||||||
) = __$$ProductLoaderStateImplCopyWithImpl<$Res>;
|
|
||||||
@override
|
|
||||||
@useResult
|
|
||||||
$Res call({
|
|
||||||
List<Product> products,
|
|
||||||
Option<ProductFailure> failureOptionProduct,
|
|
||||||
String? categoryId,
|
|
||||||
String? search,
|
|
||||||
bool isFetching,
|
|
||||||
bool hasReachedMax,
|
|
||||||
int page,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
class __$$ProductLoaderStateImplCopyWithImpl<$Res>
|
|
||||||
extends _$ProductLoaderStateCopyWithImpl<$Res, _$ProductLoaderStateImpl>
|
|
||||||
implements _$$ProductLoaderStateImplCopyWith<$Res> {
|
|
||||||
__$$ProductLoaderStateImplCopyWithImpl(
|
|
||||||
_$ProductLoaderStateImpl _value,
|
|
||||||
$Res Function(_$ProductLoaderStateImpl) _then,
|
|
||||||
) : super(_value, _then);
|
|
||||||
|
|
||||||
/// Create a copy of ProductLoaderState
|
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
|
||||||
@pragma('vm:prefer-inline')
|
|
||||||
@override
|
|
||||||
$Res call({
|
|
||||||
Object? products = null,
|
|
||||||
Object? failureOptionProduct = null,
|
|
||||||
Object? categoryId = freezed,
|
|
||||||
Object? search = freezed,
|
|
||||||
Object? isFetching = null,
|
|
||||||
Object? hasReachedMax = null,
|
|
||||||
Object? page = null,
|
|
||||||
}) {
|
|
||||||
return _then(
|
|
||||||
_$ProductLoaderStateImpl(
|
|
||||||
products: null == products
|
|
||||||
? _value._products
|
|
||||||
: products // ignore: cast_nullable_to_non_nullable
|
|
||||||
as List<Product>,
|
|
||||||
failureOptionProduct: null == failureOptionProduct
|
|
||||||
? _value.failureOptionProduct
|
|
||||||
: failureOptionProduct // ignore: cast_nullable_to_non_nullable
|
|
||||||
as Option<ProductFailure>,
|
|
||||||
categoryId: freezed == categoryId
|
|
||||||
? _value.categoryId
|
|
||||||
: categoryId // ignore: cast_nullable_to_non_nullable
|
|
||||||
as String?,
|
|
||||||
search: freezed == search
|
|
||||||
? _value.search
|
|
||||||
: search // ignore: cast_nullable_to_non_nullable
|
|
||||||
as String?,
|
|
||||||
isFetching: null == isFetching
|
|
||||||
? _value.isFetching
|
|
||||||
: isFetching // ignore: cast_nullable_to_non_nullable
|
|
||||||
as bool,
|
|
||||||
hasReachedMax: null == hasReachedMax
|
|
||||||
? _value.hasReachedMax
|
|
||||||
: hasReachedMax // ignore: cast_nullable_to_non_nullable
|
|
||||||
as bool,
|
|
||||||
page: null == page
|
|
||||||
? _value.page
|
|
||||||
: page // ignore: cast_nullable_to_non_nullable
|
|
||||||
as int,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
|
|
||||||
class _$ProductLoaderStateImpl implements _ProductLoaderState {
|
|
||||||
const _$ProductLoaderStateImpl({
|
|
||||||
required final List<Product> products,
|
|
||||||
required this.failureOptionProduct,
|
|
||||||
this.categoryId,
|
|
||||||
this.search,
|
|
||||||
this.isFetching = false,
|
|
||||||
this.hasReachedMax = false,
|
|
||||||
this.page = 1,
|
|
||||||
}) : _products = products;
|
|
||||||
|
|
||||||
final List<Product> _products;
|
|
||||||
@override
|
|
||||||
List<Product> get products {
|
|
||||||
if (_products is EqualUnmodifiableListView) return _products;
|
|
||||||
// ignore: implicit_dynamic_type
|
|
||||||
return EqualUnmodifiableListView(_products);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
final Option<ProductFailure> failureOptionProduct;
|
|
||||||
@override
|
|
||||||
final String? categoryId;
|
|
||||||
@override
|
|
||||||
final String? search;
|
|
||||||
@override
|
|
||||||
@JsonKey()
|
|
||||||
final bool isFetching;
|
|
||||||
@override
|
|
||||||
@JsonKey()
|
|
||||||
final bool hasReachedMax;
|
|
||||||
@override
|
|
||||||
@JsonKey()
|
|
||||||
final int page;
|
|
||||||
|
|
||||||
@override
|
|
||||||
String toString() {
|
|
||||||
return 'ProductLoaderState(products: $products, failureOptionProduct: $failureOptionProduct, categoryId: $categoryId, search: $search, isFetching: $isFetching, hasReachedMax: $hasReachedMax, page: $page)';
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
bool operator ==(Object other) {
|
|
||||||
return identical(this, other) ||
|
|
||||||
(other.runtimeType == runtimeType &&
|
|
||||||
other is _$ProductLoaderStateImpl &&
|
|
||||||
const DeepCollectionEquality().equals(other._products, _products) &&
|
|
||||||
(identical(other.failureOptionProduct, failureOptionProduct) ||
|
|
||||||
other.failureOptionProduct == failureOptionProduct) &&
|
|
||||||
(identical(other.categoryId, categoryId) ||
|
|
||||||
other.categoryId == categoryId) &&
|
|
||||||
(identical(other.search, search) || other.search == search) &&
|
|
||||||
(identical(other.isFetching, isFetching) ||
|
|
||||||
other.isFetching == isFetching) &&
|
|
||||||
(identical(other.hasReachedMax, hasReachedMax) ||
|
|
||||||
other.hasReachedMax == hasReachedMax) &&
|
|
||||||
(identical(other.page, page) || other.page == page));
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
int get hashCode => Object.hash(
|
|
||||||
runtimeType,
|
|
||||||
const DeepCollectionEquality().hash(_products),
|
|
||||||
failureOptionProduct,
|
|
||||||
categoryId,
|
|
||||||
search,
|
|
||||||
isFetching,
|
|
||||||
hasReachedMax,
|
|
||||||
page,
|
|
||||||
);
|
|
||||||
|
|
||||||
/// Create a copy of ProductLoaderState
|
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
|
||||||
@override
|
|
||||||
@pragma('vm:prefer-inline')
|
|
||||||
_$$ProductLoaderStateImplCopyWith<_$ProductLoaderStateImpl> get copyWith =>
|
|
||||||
__$$ProductLoaderStateImplCopyWithImpl<_$ProductLoaderStateImpl>(
|
|
||||||
this,
|
|
||||||
_$identity,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract class _ProductLoaderState implements ProductLoaderState {
|
|
||||||
const factory _ProductLoaderState({
|
|
||||||
required final List<Product> products,
|
|
||||||
required final Option<ProductFailure> failureOptionProduct,
|
|
||||||
final String? categoryId,
|
|
||||||
final String? search,
|
|
||||||
final bool isFetching,
|
|
||||||
final bool hasReachedMax,
|
|
||||||
final int page,
|
|
||||||
}) = _$ProductLoaderStateImpl;
|
|
||||||
|
|
||||||
@override
|
|
||||||
List<Product> get products;
|
|
||||||
@override
|
|
||||||
Option<ProductFailure> get failureOptionProduct;
|
|
||||||
@override
|
|
||||||
String? get categoryId;
|
|
||||||
@override
|
|
||||||
String? get search;
|
|
||||||
@override
|
|
||||||
bool get isFetching;
|
|
||||||
@override
|
|
||||||
bool get hasReachedMax;
|
|
||||||
@override
|
|
||||||
int get page;
|
|
||||||
|
|
||||||
/// Create a copy of ProductLoaderState
|
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
|
||||||
@override
|
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
|
||||||
_$$ProductLoaderStateImplCopyWith<_$ProductLoaderStateImpl> get copyWith =>
|
|
||||||
throw _privateConstructorUsedError;
|
|
||||||
}
|
|
||||||
@ -1,11 +0,0 @@
|
|||||||
part of 'product_loader_bloc.dart';
|
|
||||||
|
|
||||||
@freezed
|
|
||||||
class ProductLoaderEvent with _$ProductLoaderEvent {
|
|
||||||
const factory ProductLoaderEvent.categoryIdChanged(String categoryId) =
|
|
||||||
_CategoryIdChanged;
|
|
||||||
const factory ProductLoaderEvent.searchChanged(String search) =
|
|
||||||
_SearchChanged;
|
|
||||||
const factory ProductLoaderEvent.fetched({@Default(false) bool isRefresh}) =
|
|
||||||
_Fetched;
|
|
||||||
}
|
|
||||||
@ -1,17 +0,0 @@
|
|||||||
part of 'product_loader_bloc.dart';
|
|
||||||
|
|
||||||
@freezed
|
|
||||||
class ProductLoaderState with _$ProductLoaderState {
|
|
||||||
const factory ProductLoaderState({
|
|
||||||
required List<Product> products,
|
|
||||||
required Option<ProductFailure> failureOptionProduct,
|
|
||||||
String? categoryId,
|
|
||||||
String? search,
|
|
||||||
@Default(false) bool isFetching,
|
|
||||||
@Default(false) bool hasReachedMax,
|
|
||||||
@Default(1) int page,
|
|
||||||
}) = _ProductLoaderState;
|
|
||||||
|
|
||||||
factory ProductLoaderState.initial() =>
|
|
||||||
ProductLoaderState(products: [], failureOptionProduct: none());
|
|
||||||
}
|
|
||||||
@ -2,8 +2,10 @@ import 'package:awesome_dio_interceptor/awesome_dio_interceptor.dart';
|
|||||||
import 'package:dio/dio.dart';
|
import 'package:dio/dio.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:injectable/injectable.dart';
|
import 'package:injectable/injectable.dart';
|
||||||
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
|
|
||||||
import '../../env.dart';
|
import '../../env.dart';
|
||||||
|
import '../constant/local_storage_key.dart';
|
||||||
import 'api_failure.dart';
|
import 'api_failure.dart';
|
||||||
import 'errors/bad_network_error.dart';
|
import 'errors/bad_network_error.dart';
|
||||||
import 'errors/bad_request_error.dart';
|
import 'errors/bad_request_error.dart';
|
||||||
@ -22,11 +24,16 @@ import 'interceptors/unauthorized_interceptor.dart';
|
|||||||
class ApiClient {
|
class ApiClient {
|
||||||
final Dio _dio;
|
final Dio _dio;
|
||||||
final Env _env;
|
final Env _env;
|
||||||
|
final SharedPreferences _preferences;
|
||||||
|
|
||||||
ApiClient(this._dio, this._env) {
|
ApiClient(this._dio, this._env, this._preferences) {
|
||||||
_dio.options.baseUrl = _env.baseUrl;
|
_dio.options.baseUrl = _env.baseUrl;
|
||||||
_dio.options.validateStatus = (status) => status! < 500;
|
_dio.options.validateStatus = (status) => status! < 500;
|
||||||
_dio.options.connectTimeout = const Duration(seconds: 20);
|
_dio.options.connectTimeout = const Duration(seconds: 20);
|
||||||
|
_dio.options.headers = {
|
||||||
|
'authorization':
|
||||||
|
'Bearer ${_preferences.getString(LocalStorageKey.token)}',
|
||||||
|
};
|
||||||
_dio.interceptors.add(BadNetworkErrorInterceptor());
|
_dio.interceptors.add(BadNetworkErrorInterceptor());
|
||||||
_dio.interceptors.add(BadRequestErrorInterceptor());
|
_dio.interceptors.add(BadRequestErrorInterceptor());
|
||||||
_dio.interceptors.add(InternalServerErrorInterceptor());
|
_dio.interceptors.add(InternalServerErrorInterceptor());
|
||||||
|
|||||||
@ -1,8 +1,4 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
|
||||||
|
|
||||||
import '../../injection.dart';
|
|
||||||
import '../constant/local_storage_key.dart';
|
|
||||||
|
|
||||||
void dismissKeyboard(BuildContext context) {
|
void dismissKeyboard(BuildContext context) {
|
||||||
final currentFocus = FocusScope.of(context);
|
final currentFocus = FocusScope.of(context);
|
||||||
@ -10,10 +6,3 @@ void dismissKeyboard(BuildContext context) {
|
|||||||
FocusManager.instance.primaryFocus?.unfocus();
|
FocusManager.instance.primaryFocus?.unfocus();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String, dynamic> getAuthorizationHeader() {
|
|
||||||
return {
|
|
||||||
'Authorization':
|
|
||||||
'Bearer ${getIt<SharedPreferences>().getString(LocalStorageKey.token)}',
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|||||||
@ -2,15 +2,4 @@ class ApiPath {
|
|||||||
// Auth
|
// Auth
|
||||||
static const String login = '/api/v1/auth/login';
|
static const String login = '/api/v1/auth/login';
|
||||||
static const String logout = '/api/v1/auth/logout';
|
static const String logout = '/api/v1/auth/logout';
|
||||||
|
|
||||||
// Analytic
|
|
||||||
static const String salesAnalytic = '/api/v1/analytics/sales';
|
|
||||||
static const String profitLossAnalytic = '/api/v1/analytics/profit-loss';
|
|
||||||
static const String categoryAnalytic = '/api/v1/analytics/categories';
|
|
||||||
|
|
||||||
// Category
|
|
||||||
static const String category = '/api/v1/categories';
|
|
||||||
|
|
||||||
// Product
|
|
||||||
static const String product = '/api/v1/products';
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,10 +0,0 @@
|
|||||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
|
||||||
|
|
||||||
import '../../common/api/api_failure.dart';
|
|
||||||
|
|
||||||
part 'analytic.freezed.dart';
|
|
||||||
|
|
||||||
part 'entities/sales_analytic_entity.dart';
|
|
||||||
part 'entities/profit_loss_analytic_entity.dart';
|
|
||||||
part 'entities/category_analytic_entity.dart';
|
|
||||||
part 'failures/analytic_failure.dart';
|
|
||||||
File diff suppressed because it is too large
Load Diff
@ -1,41 +0,0 @@
|
|||||||
part of '../analytic.dart';
|
|
||||||
|
|
||||||
@freezed
|
|
||||||
class CategoryAnalytic with _$CategoryAnalytic {
|
|
||||||
const factory CategoryAnalytic({
|
|
||||||
required String organizationId,
|
|
||||||
required String outletId,
|
|
||||||
required String dateFrom,
|
|
||||||
required String dateTo,
|
|
||||||
required List<CategoryAnalyticItem> data,
|
|
||||||
}) = _CategoryAnalytic;
|
|
||||||
|
|
||||||
factory CategoryAnalytic.empty() => const CategoryAnalytic(
|
|
||||||
organizationId: "",
|
|
||||||
outletId: "",
|
|
||||||
dateFrom: "",
|
|
||||||
dateTo: "",
|
|
||||||
data: [],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@freezed
|
|
||||||
class CategoryAnalyticItem with _$CategoryAnalyticItem {
|
|
||||||
const factory CategoryAnalyticItem({
|
|
||||||
required String categoryId,
|
|
||||||
required String categoryName,
|
|
||||||
required int totalRevenue,
|
|
||||||
required int totalQuantity,
|
|
||||||
required int productCount,
|
|
||||||
required int orderCount,
|
|
||||||
}) = _CategoryAnalyticItem;
|
|
||||||
|
|
||||||
factory CategoryAnalyticItem.empty() => const CategoryAnalyticItem(
|
|
||||||
categoryId: "",
|
|
||||||
categoryName: "",
|
|
||||||
totalRevenue: 0,
|
|
||||||
totalQuantity: 0,
|
|
||||||
productCount: 0,
|
|
||||||
orderCount: 0,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@ -1,117 +0,0 @@
|
|||||||
part of '../analytic.dart';
|
|
||||||
|
|
||||||
@freezed
|
|
||||||
class ProfitLossAnalytic with _$ProfitLossAnalytic {
|
|
||||||
const factory ProfitLossAnalytic({
|
|
||||||
required String organizationId,
|
|
||||||
required String dateFrom,
|
|
||||||
required String dateTo,
|
|
||||||
required String groupBy,
|
|
||||||
required ProfitLossSummary summary,
|
|
||||||
required List<ProfitLossDailyData> data,
|
|
||||||
required List<ProfitLossProductData> productData,
|
|
||||||
}) = _ProfitLossAnalytic;
|
|
||||||
|
|
||||||
factory ProfitLossAnalytic.empty() => ProfitLossAnalytic(
|
|
||||||
organizationId: '',
|
|
||||||
dateFrom: '',
|
|
||||||
dateTo: '',
|
|
||||||
groupBy: '',
|
|
||||||
summary: ProfitLossSummary.empty(),
|
|
||||||
data: [],
|
|
||||||
productData: [],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@freezed
|
|
||||||
class ProfitLossSummary with _$ProfitLossSummary {
|
|
||||||
const factory ProfitLossSummary({
|
|
||||||
required int totalRevenue,
|
|
||||||
required int totalCost,
|
|
||||||
required int grossProfit,
|
|
||||||
required double grossProfitMargin,
|
|
||||||
required int totalTax,
|
|
||||||
required int totalDiscount,
|
|
||||||
required int netProfit,
|
|
||||||
required double netProfitMargin,
|
|
||||||
required int totalOrders,
|
|
||||||
required double averageProfit,
|
|
||||||
required double profitabilityRatio,
|
|
||||||
}) = _ProfitLossSummary;
|
|
||||||
|
|
||||||
factory ProfitLossSummary.empty() => ProfitLossSummary(
|
|
||||||
totalRevenue: 0,
|
|
||||||
totalCost: 0,
|
|
||||||
grossProfit: 0,
|
|
||||||
grossProfitMargin: 0,
|
|
||||||
totalTax: 0,
|
|
||||||
totalDiscount: 0,
|
|
||||||
netProfit: 0,
|
|
||||||
netProfitMargin: 0,
|
|
||||||
totalOrders: 0,
|
|
||||||
averageProfit: 0,
|
|
||||||
profitabilityRatio: 0,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@freezed
|
|
||||||
class ProfitLossDailyData with _$ProfitLossDailyData {
|
|
||||||
const factory ProfitLossDailyData({
|
|
||||||
required String date,
|
|
||||||
required int revenue,
|
|
||||||
required int cost,
|
|
||||||
required int grossProfit,
|
|
||||||
required double grossProfitMargin,
|
|
||||||
required int tax,
|
|
||||||
required int discount,
|
|
||||||
required int netProfit,
|
|
||||||
required double netProfitMargin,
|
|
||||||
required int orders,
|
|
||||||
}) = _ProfitLossDailyData;
|
|
||||||
|
|
||||||
factory ProfitLossDailyData.empty() => ProfitLossDailyData(
|
|
||||||
date: '',
|
|
||||||
revenue: 0,
|
|
||||||
cost: 0,
|
|
||||||
grossProfit: 0,
|
|
||||||
grossProfitMargin: 0,
|
|
||||||
tax: 0,
|
|
||||||
discount: 0,
|
|
||||||
netProfit: 0,
|
|
||||||
netProfitMargin: 0,
|
|
||||||
orders: 0,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@freezed
|
|
||||||
class ProfitLossProductData with _$ProfitLossProductData {
|
|
||||||
const factory ProfitLossProductData({
|
|
||||||
required String productId,
|
|
||||||
required String productName,
|
|
||||||
required String categoryId,
|
|
||||||
required String categoryName,
|
|
||||||
required int quantitySold,
|
|
||||||
required int revenue,
|
|
||||||
required int cost,
|
|
||||||
required int grossProfit,
|
|
||||||
required double grossProfitMargin,
|
|
||||||
required int averagePrice,
|
|
||||||
required int averageCost,
|
|
||||||
required int profitPerUnit,
|
|
||||||
}) = _ProfitLossProductData;
|
|
||||||
|
|
||||||
factory ProfitLossProductData.empty() => ProfitLossProductData(
|
|
||||||
productId: '',
|
|
||||||
productName: '',
|
|
||||||
categoryId: '',
|
|
||||||
categoryName: '',
|
|
||||||
quantitySold: 0,
|
|
||||||
revenue: 0,
|
|
||||||
cost: 0,
|
|
||||||
grossProfit: 0,
|
|
||||||
grossProfitMargin: 0,
|
|
||||||
averagePrice: 0,
|
|
||||||
averageCost: 0,
|
|
||||||
profitPerUnit: 0,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@ -1,70 +0,0 @@
|
|||||||
part of '../analytic.dart';
|
|
||||||
|
|
||||||
@freezed
|
|
||||||
class SalesAnalytic with _$SalesAnalytic {
|
|
||||||
const factory SalesAnalytic({
|
|
||||||
required String organizationId,
|
|
||||||
required String outletId,
|
|
||||||
required DateTime dateFrom,
|
|
||||||
required DateTime dateTo,
|
|
||||||
required String groupBy,
|
|
||||||
required SalesAnalyticSummary summary,
|
|
||||||
required List<SalesAnalyticData> data,
|
|
||||||
}) = _SalesAnalytic;
|
|
||||||
|
|
||||||
factory SalesAnalytic.empty() => SalesAnalytic(
|
|
||||||
organizationId: '',
|
|
||||||
outletId: '',
|
|
||||||
dateFrom: DateTime.fromMillisecondsSinceEpoch(0),
|
|
||||||
dateTo: DateTime.fromMillisecondsSinceEpoch(0),
|
|
||||||
groupBy: '',
|
|
||||||
summary: SalesAnalyticSummary.empty(),
|
|
||||||
data: [],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@freezed
|
|
||||||
class SalesAnalyticSummary with _$SalesAnalyticSummary {
|
|
||||||
const factory SalesAnalyticSummary({
|
|
||||||
required int totalSales,
|
|
||||||
required int totalOrders,
|
|
||||||
required int totalItems,
|
|
||||||
required double averageOrderValue,
|
|
||||||
required int totalTax,
|
|
||||||
required int totalDiscount,
|
|
||||||
required int netSales,
|
|
||||||
}) = _SalesAnalyticSummary;
|
|
||||||
|
|
||||||
factory SalesAnalyticSummary.empty() => const SalesAnalyticSummary(
|
|
||||||
totalSales: 0,
|
|
||||||
totalOrders: 0,
|
|
||||||
totalItems: 0,
|
|
||||||
averageOrderValue: 0,
|
|
||||||
totalTax: 0,
|
|
||||||
totalDiscount: 0,
|
|
||||||
netSales: 0,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@freezed
|
|
||||||
class SalesAnalyticData with _$SalesAnalyticData {
|
|
||||||
const factory SalesAnalyticData({
|
|
||||||
required DateTime date,
|
|
||||||
required int sales,
|
|
||||||
required int orders,
|
|
||||||
required int items,
|
|
||||||
required int tax,
|
|
||||||
required int discount,
|
|
||||||
required int netSales,
|
|
||||||
}) = _SalesAnalyticData;
|
|
||||||
|
|
||||||
factory SalesAnalyticData.empty() => SalesAnalyticData(
|
|
||||||
date: DateTime.fromMillisecondsSinceEpoch(0),
|
|
||||||
sales: 0,
|
|
||||||
orders: 0,
|
|
||||||
items: 0,
|
|
||||||
tax: 0,
|
|
||||||
discount: 0,
|
|
||||||
netSales: 0,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@ -1,10 +0,0 @@
|
|||||||
part of '../analytic.dart';
|
|
||||||
|
|
||||||
@freezed
|
|
||||||
sealed class AnalyticFailure with _$AnalyticFailure {
|
|
||||||
const factory AnalyticFailure.serverError(ApiFailure failure) = _ServerError;
|
|
||||||
const factory AnalyticFailure.unexpectedError() = _UnexpectedError;
|
|
||||||
const factory AnalyticFailure.empty() = _Empty;
|
|
||||||
const factory AnalyticFailure.dynamicErrorMessage(String erroMessage) =
|
|
||||||
_DynamicErrorMessage;
|
|
||||||
}
|
|
||||||
@ -1,20 +0,0 @@
|
|||||||
import 'package:dartz/dartz.dart';
|
|
||||||
|
|
||||||
import '../analytic.dart';
|
|
||||||
|
|
||||||
abstract class IAnalyticRepository {
|
|
||||||
Future<Either<AnalyticFailure, SalesAnalytic>> getSales({
|
|
||||||
required DateTime dateFrom,
|
|
||||||
required DateTime dateTo,
|
|
||||||
});
|
|
||||||
|
|
||||||
Future<Either<AnalyticFailure, ProfitLossAnalytic>> getProfitLoss({
|
|
||||||
required DateTime dateFrom,
|
|
||||||
required DateTime dateTo,
|
|
||||||
});
|
|
||||||
|
|
||||||
Future<Either<AnalyticFailure, CategoryAnalytic>> getCategory({
|
|
||||||
required DateTime dateFrom,
|
|
||||||
required DateTime dateTo,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
@ -1,10 +0,0 @@
|
|||||||
import 'package:dartz/dartz.dart';
|
|
||||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
|
||||||
|
|
||||||
import '../../common/api/api_failure.dart';
|
|
||||||
|
|
||||||
part 'category.freezed.dart';
|
|
||||||
|
|
||||||
part 'entities/category_entity.dart';
|
|
||||||
part 'failures/category_failure.dart';
|
|
||||||
part 'repositories/i_auth_repository.dart';
|
|
||||||
@ -1,952 +0,0 @@
|
|||||||
// 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 'category.dart';
|
|
||||||
|
|
||||||
// **************************************************************************
|
|
||||||
// FreezedGenerator
|
|
||||||
// **************************************************************************
|
|
||||||
|
|
||||||
T _$identity<T>(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 _$Category {
|
|
||||||
String get id => throw _privateConstructorUsedError;
|
|
||||||
String get organizationId => throw _privateConstructorUsedError;
|
|
||||||
String get name => throw _privateConstructorUsedError;
|
|
||||||
String get description => throw _privateConstructorUsedError;
|
|
||||||
String get businessType => throw _privateConstructorUsedError;
|
|
||||||
Map<String, dynamic> get metadata => throw _privateConstructorUsedError;
|
|
||||||
DateTime? get createdAt => throw _privateConstructorUsedError;
|
|
||||||
DateTime? get updatedAt => throw _privateConstructorUsedError;
|
|
||||||
|
|
||||||
/// Create a copy of Category
|
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
|
||||||
$CategoryCopyWith<Category> get copyWith =>
|
|
||||||
throw _privateConstructorUsedError;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
abstract class $CategoryCopyWith<$Res> {
|
|
||||||
factory $CategoryCopyWith(Category value, $Res Function(Category) then) =
|
|
||||||
_$CategoryCopyWithImpl<$Res, Category>;
|
|
||||||
@useResult
|
|
||||||
$Res call({
|
|
||||||
String id,
|
|
||||||
String organizationId,
|
|
||||||
String name,
|
|
||||||
String description,
|
|
||||||
String businessType,
|
|
||||||
Map<String, dynamic> metadata,
|
|
||||||
DateTime? createdAt,
|
|
||||||
DateTime? updatedAt,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
class _$CategoryCopyWithImpl<$Res, $Val extends Category>
|
|
||||||
implements $CategoryCopyWith<$Res> {
|
|
||||||
_$CategoryCopyWithImpl(this._value, this._then);
|
|
||||||
|
|
||||||
// ignore: unused_field
|
|
||||||
final $Val _value;
|
|
||||||
// ignore: unused_field
|
|
||||||
final $Res Function($Val) _then;
|
|
||||||
|
|
||||||
/// Create a copy of Category
|
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
|
||||||
@pragma('vm:prefer-inline')
|
|
||||||
@override
|
|
||||||
$Res call({
|
|
||||||
Object? id = null,
|
|
||||||
Object? organizationId = null,
|
|
||||||
Object? name = null,
|
|
||||||
Object? description = null,
|
|
||||||
Object? businessType = null,
|
|
||||||
Object? metadata = null,
|
|
||||||
Object? createdAt = freezed,
|
|
||||||
Object? updatedAt = freezed,
|
|
||||||
}) {
|
|
||||||
return _then(
|
|
||||||
_value.copyWith(
|
|
||||||
id: null == id
|
|
||||||
? _value.id
|
|
||||||
: id // ignore: cast_nullable_to_non_nullable
|
|
||||||
as String,
|
|
||||||
organizationId: null == organizationId
|
|
||||||
? _value.organizationId
|
|
||||||
: organizationId // ignore: cast_nullable_to_non_nullable
|
|
||||||
as String,
|
|
||||||
name: null == name
|
|
||||||
? _value.name
|
|
||||||
: name // ignore: cast_nullable_to_non_nullable
|
|
||||||
as String,
|
|
||||||
description: null == description
|
|
||||||
? _value.description
|
|
||||||
: description // ignore: cast_nullable_to_non_nullable
|
|
||||||
as String,
|
|
||||||
businessType: null == businessType
|
|
||||||
? _value.businessType
|
|
||||||
: businessType // ignore: cast_nullable_to_non_nullable
|
|
||||||
as String,
|
|
||||||
metadata: null == metadata
|
|
||||||
? _value.metadata
|
|
||||||
: metadata // ignore: cast_nullable_to_non_nullable
|
|
||||||
as Map<String, dynamic>,
|
|
||||||
createdAt: freezed == createdAt
|
|
||||||
? _value.createdAt
|
|
||||||
: createdAt // ignore: cast_nullable_to_non_nullable
|
|
||||||
as DateTime?,
|
|
||||||
updatedAt: freezed == updatedAt
|
|
||||||
? _value.updatedAt
|
|
||||||
: updatedAt // ignore: cast_nullable_to_non_nullable
|
|
||||||
as DateTime?,
|
|
||||||
)
|
|
||||||
as $Val,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
abstract class _$$CategoryImplCopyWith<$Res>
|
|
||||||
implements $CategoryCopyWith<$Res> {
|
|
||||||
factory _$$CategoryImplCopyWith(
|
|
||||||
_$CategoryImpl value,
|
|
||||||
$Res Function(_$CategoryImpl) then,
|
|
||||||
) = __$$CategoryImplCopyWithImpl<$Res>;
|
|
||||||
@override
|
|
||||||
@useResult
|
|
||||||
$Res call({
|
|
||||||
String id,
|
|
||||||
String organizationId,
|
|
||||||
String name,
|
|
||||||
String description,
|
|
||||||
String businessType,
|
|
||||||
Map<String, dynamic> metadata,
|
|
||||||
DateTime? createdAt,
|
|
||||||
DateTime? updatedAt,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
class __$$CategoryImplCopyWithImpl<$Res>
|
|
||||||
extends _$CategoryCopyWithImpl<$Res, _$CategoryImpl>
|
|
||||||
implements _$$CategoryImplCopyWith<$Res> {
|
|
||||||
__$$CategoryImplCopyWithImpl(
|
|
||||||
_$CategoryImpl _value,
|
|
||||||
$Res Function(_$CategoryImpl) _then,
|
|
||||||
) : super(_value, _then);
|
|
||||||
|
|
||||||
/// Create a copy of Category
|
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
|
||||||
@pragma('vm:prefer-inline')
|
|
||||||
@override
|
|
||||||
$Res call({
|
|
||||||
Object? id = null,
|
|
||||||
Object? organizationId = null,
|
|
||||||
Object? name = null,
|
|
||||||
Object? description = null,
|
|
||||||
Object? businessType = null,
|
|
||||||
Object? metadata = null,
|
|
||||||
Object? createdAt = freezed,
|
|
||||||
Object? updatedAt = freezed,
|
|
||||||
}) {
|
|
||||||
return _then(
|
|
||||||
_$CategoryImpl(
|
|
||||||
id: null == id
|
|
||||||
? _value.id
|
|
||||||
: id // ignore: cast_nullable_to_non_nullable
|
|
||||||
as String,
|
|
||||||
organizationId: null == organizationId
|
|
||||||
? _value.organizationId
|
|
||||||
: organizationId // ignore: cast_nullable_to_non_nullable
|
|
||||||
as String,
|
|
||||||
name: null == name
|
|
||||||
? _value.name
|
|
||||||
: name // ignore: cast_nullable_to_non_nullable
|
|
||||||
as String,
|
|
||||||
description: null == description
|
|
||||||
? _value.description
|
|
||||||
: description // ignore: cast_nullable_to_non_nullable
|
|
||||||
as String,
|
|
||||||
businessType: null == businessType
|
|
||||||
? _value.businessType
|
|
||||||
: businessType // ignore: cast_nullable_to_non_nullable
|
|
||||||
as String,
|
|
||||||
metadata: null == metadata
|
|
||||||
? _value._metadata
|
|
||||||
: metadata // ignore: cast_nullable_to_non_nullable
|
|
||||||
as Map<String, dynamic>,
|
|
||||||
createdAt: freezed == createdAt
|
|
||||||
? _value.createdAt
|
|
||||||
: createdAt // ignore: cast_nullable_to_non_nullable
|
|
||||||
as DateTime?,
|
|
||||||
updatedAt: freezed == updatedAt
|
|
||||||
? _value.updatedAt
|
|
||||||
: updatedAt // ignore: cast_nullable_to_non_nullable
|
|
||||||
as DateTime?,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
|
|
||||||
class _$CategoryImpl implements _Category {
|
|
||||||
const _$CategoryImpl({
|
|
||||||
required this.id,
|
|
||||||
required this.organizationId,
|
|
||||||
required this.name,
|
|
||||||
required this.description,
|
|
||||||
required this.businessType,
|
|
||||||
required final Map<String, dynamic> metadata,
|
|
||||||
this.createdAt,
|
|
||||||
this.updatedAt,
|
|
||||||
}) : _metadata = metadata;
|
|
||||||
|
|
||||||
@override
|
|
||||||
final String id;
|
|
||||||
@override
|
|
||||||
final String organizationId;
|
|
||||||
@override
|
|
||||||
final String name;
|
|
||||||
@override
|
|
||||||
final String description;
|
|
||||||
@override
|
|
||||||
final String businessType;
|
|
||||||
final Map<String, dynamic> _metadata;
|
|
||||||
@override
|
|
||||||
Map<String, dynamic> get metadata {
|
|
||||||
if (_metadata is EqualUnmodifiableMapView) return _metadata;
|
|
||||||
// ignore: implicit_dynamic_type
|
|
||||||
return EqualUnmodifiableMapView(_metadata);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
final DateTime? createdAt;
|
|
||||||
@override
|
|
||||||
final DateTime? updatedAt;
|
|
||||||
|
|
||||||
@override
|
|
||||||
String toString() {
|
|
||||||
return 'Category(id: $id, organizationId: $organizationId, name: $name, description: $description, businessType: $businessType, metadata: $metadata, createdAt: $createdAt, updatedAt: $updatedAt)';
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
bool operator ==(Object other) {
|
|
||||||
return identical(this, other) ||
|
|
||||||
(other.runtimeType == runtimeType &&
|
|
||||||
other is _$CategoryImpl &&
|
|
||||||
(identical(other.id, id) || other.id == id) &&
|
|
||||||
(identical(other.organizationId, organizationId) ||
|
|
||||||
other.organizationId == organizationId) &&
|
|
||||||
(identical(other.name, name) || other.name == name) &&
|
|
||||||
(identical(other.description, description) ||
|
|
||||||
other.description == description) &&
|
|
||||||
(identical(other.businessType, businessType) ||
|
|
||||||
other.businessType == businessType) &&
|
|
||||||
const DeepCollectionEquality().equals(other._metadata, _metadata) &&
|
|
||||||
(identical(other.createdAt, createdAt) ||
|
|
||||||
other.createdAt == createdAt) &&
|
|
||||||
(identical(other.updatedAt, updatedAt) ||
|
|
||||||
other.updatedAt == updatedAt));
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
int get hashCode => Object.hash(
|
|
||||||
runtimeType,
|
|
||||||
id,
|
|
||||||
organizationId,
|
|
||||||
name,
|
|
||||||
description,
|
|
||||||
businessType,
|
|
||||||
const DeepCollectionEquality().hash(_metadata),
|
|
||||||
createdAt,
|
|
||||||
updatedAt,
|
|
||||||
);
|
|
||||||
|
|
||||||
/// Create a copy of Category
|
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
|
||||||
@override
|
|
||||||
@pragma('vm:prefer-inline')
|
|
||||||
_$$CategoryImplCopyWith<_$CategoryImpl> get copyWith =>
|
|
||||||
__$$CategoryImplCopyWithImpl<_$CategoryImpl>(this, _$identity);
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract class _Category implements Category {
|
|
||||||
const factory _Category({
|
|
||||||
required final String id,
|
|
||||||
required final String organizationId,
|
|
||||||
required final String name,
|
|
||||||
required final String description,
|
|
||||||
required final String businessType,
|
|
||||||
required final Map<String, dynamic> metadata,
|
|
||||||
final DateTime? createdAt,
|
|
||||||
final DateTime? updatedAt,
|
|
||||||
}) = _$CategoryImpl;
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get id;
|
|
||||||
@override
|
|
||||||
String get organizationId;
|
|
||||||
@override
|
|
||||||
String get name;
|
|
||||||
@override
|
|
||||||
String get description;
|
|
||||||
@override
|
|
||||||
String get businessType;
|
|
||||||
@override
|
|
||||||
Map<String, dynamic> get metadata;
|
|
||||||
@override
|
|
||||||
DateTime? get createdAt;
|
|
||||||
@override
|
|
||||||
DateTime? get updatedAt;
|
|
||||||
|
|
||||||
/// Create a copy of Category
|
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
|
||||||
@override
|
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
|
||||||
_$$CategoryImplCopyWith<_$CategoryImpl> get copyWith =>
|
|
||||||
throw _privateConstructorUsedError;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
mixin _$CategoryFailure {
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult when<TResult extends Object?>({
|
|
||||||
required TResult Function(ApiFailure failure) serverError,
|
|
||||||
required TResult Function() unexpectedError,
|
|
||||||
required TResult Function() empty,
|
|
||||||
required TResult Function(String erroMessage) dynamicErrorMessage,
|
|
||||||
}) => throw _privateConstructorUsedError;
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult? whenOrNull<TResult extends Object?>({
|
|
||||||
TResult? Function(ApiFailure failure)? serverError,
|
|
||||||
TResult? Function()? unexpectedError,
|
|
||||||
TResult? Function()? empty,
|
|
||||||
TResult? Function(String erroMessage)? dynamicErrorMessage,
|
|
||||||
}) => throw _privateConstructorUsedError;
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult maybeWhen<TResult extends Object?>({
|
|
||||||
TResult Function(ApiFailure failure)? serverError,
|
|
||||||
TResult Function()? unexpectedError,
|
|
||||||
TResult Function()? empty,
|
|
||||||
TResult Function(String erroMessage)? dynamicErrorMessage,
|
|
||||||
required TResult orElse(),
|
|
||||||
}) => throw _privateConstructorUsedError;
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult map<TResult extends Object?>({
|
|
||||||
required TResult Function(_ServerError value) serverError,
|
|
||||||
required TResult Function(_UnexpectedError value) unexpectedError,
|
|
||||||
required TResult Function(_Empty value) empty,
|
|
||||||
required TResult Function(_DynamicErrorMessage value) dynamicErrorMessage,
|
|
||||||
}) => throw _privateConstructorUsedError;
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult? mapOrNull<TResult extends Object?>({
|
|
||||||
TResult? Function(_ServerError value)? serverError,
|
|
||||||
TResult? Function(_UnexpectedError value)? unexpectedError,
|
|
||||||
TResult? Function(_Empty value)? empty,
|
|
||||||
TResult? Function(_DynamicErrorMessage value)? dynamicErrorMessage,
|
|
||||||
}) => throw _privateConstructorUsedError;
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult maybeMap<TResult extends Object?>({
|
|
||||||
TResult Function(_ServerError value)? serverError,
|
|
||||||
TResult Function(_UnexpectedError value)? unexpectedError,
|
|
||||||
TResult Function(_Empty value)? empty,
|
|
||||||
TResult Function(_DynamicErrorMessage value)? dynamicErrorMessage,
|
|
||||||
required TResult orElse(),
|
|
||||||
}) => throw _privateConstructorUsedError;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
abstract class $CategoryFailureCopyWith<$Res> {
|
|
||||||
factory $CategoryFailureCopyWith(
|
|
||||||
CategoryFailure value,
|
|
||||||
$Res Function(CategoryFailure) then,
|
|
||||||
) = _$CategoryFailureCopyWithImpl<$Res, CategoryFailure>;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
class _$CategoryFailureCopyWithImpl<$Res, $Val extends CategoryFailure>
|
|
||||||
implements $CategoryFailureCopyWith<$Res> {
|
|
||||||
_$CategoryFailureCopyWithImpl(this._value, this._then);
|
|
||||||
|
|
||||||
// ignore: unused_field
|
|
||||||
final $Val _value;
|
|
||||||
// ignore: unused_field
|
|
||||||
final $Res Function($Val) _then;
|
|
||||||
|
|
||||||
/// Create a copy of CategoryFailure
|
|
||||||
/// 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 _$CategoryFailureCopyWithImpl<$Res, _$ServerErrorImpl>
|
|
||||||
implements _$$ServerErrorImplCopyWith<$Res> {
|
|
||||||
__$$ServerErrorImplCopyWithImpl(
|
|
||||||
_$ServerErrorImpl _value,
|
|
||||||
$Res Function(_$ServerErrorImpl) _then,
|
|
||||||
) : super(_value, _then);
|
|
||||||
|
|
||||||
/// Create a copy of CategoryFailure
|
|
||||||
/// 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 CategoryFailure
|
|
||||||
/// 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 'CategoryFailure.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 CategoryFailure
|
|
||||||
/// 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<TResult extends Object?>({
|
|
||||||
required TResult Function(ApiFailure failure) serverError,
|
|
||||||
required TResult Function() unexpectedError,
|
|
||||||
required TResult Function() empty,
|
|
||||||
required TResult Function(String erroMessage) dynamicErrorMessage,
|
|
||||||
}) {
|
|
||||||
return serverError(failure);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult? whenOrNull<TResult extends Object?>({
|
|
||||||
TResult? Function(ApiFailure failure)? serverError,
|
|
||||||
TResult? Function()? unexpectedError,
|
|
||||||
TResult? Function()? empty,
|
|
||||||
TResult? Function(String erroMessage)? dynamicErrorMessage,
|
|
||||||
}) {
|
|
||||||
return serverError?.call(failure);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult maybeWhen<TResult extends Object?>({
|
|
||||||
TResult Function(ApiFailure failure)? serverError,
|
|
||||||
TResult Function()? unexpectedError,
|
|
||||||
TResult Function()? empty,
|
|
||||||
TResult Function(String erroMessage)? dynamicErrorMessage,
|
|
||||||
required TResult orElse(),
|
|
||||||
}) {
|
|
||||||
if (serverError != null) {
|
|
||||||
return serverError(failure);
|
|
||||||
}
|
|
||||||
return orElse();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult map<TResult extends Object?>({
|
|
||||||
required TResult Function(_ServerError value) serverError,
|
|
||||||
required TResult Function(_UnexpectedError value) unexpectedError,
|
|
||||||
required TResult Function(_Empty value) empty,
|
|
||||||
required TResult Function(_DynamicErrorMessage value) dynamicErrorMessage,
|
|
||||||
}) {
|
|
||||||
return serverError(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult? mapOrNull<TResult extends Object?>({
|
|
||||||
TResult? Function(_ServerError value)? serverError,
|
|
||||||
TResult? Function(_UnexpectedError value)? unexpectedError,
|
|
||||||
TResult? Function(_Empty value)? empty,
|
|
||||||
TResult? Function(_DynamicErrorMessage value)? dynamicErrorMessage,
|
|
||||||
}) {
|
|
||||||
return serverError?.call(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult maybeMap<TResult extends Object?>({
|
|
||||||
TResult Function(_ServerError value)? serverError,
|
|
||||||
TResult Function(_UnexpectedError value)? unexpectedError,
|
|
||||||
TResult Function(_Empty value)? empty,
|
|
||||||
TResult Function(_DynamicErrorMessage value)? dynamicErrorMessage,
|
|
||||||
required TResult orElse(),
|
|
||||||
}) {
|
|
||||||
if (serverError != null) {
|
|
||||||
return serverError(this);
|
|
||||||
}
|
|
||||||
return orElse();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract class _ServerError implements CategoryFailure {
|
|
||||||
const factory _ServerError(final ApiFailure failure) = _$ServerErrorImpl;
|
|
||||||
|
|
||||||
ApiFailure get failure;
|
|
||||||
|
|
||||||
/// Create a copy of CategoryFailure
|
|
||||||
/// 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 _$CategoryFailureCopyWithImpl<$Res, _$UnexpectedErrorImpl>
|
|
||||||
implements _$$UnexpectedErrorImplCopyWith<$Res> {
|
|
||||||
__$$UnexpectedErrorImplCopyWithImpl(
|
|
||||||
_$UnexpectedErrorImpl _value,
|
|
||||||
$Res Function(_$UnexpectedErrorImpl) _then,
|
|
||||||
) : super(_value, _then);
|
|
||||||
|
|
||||||
/// Create a copy of CategoryFailure
|
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
|
|
||||||
class _$UnexpectedErrorImpl implements _UnexpectedError {
|
|
||||||
const _$UnexpectedErrorImpl();
|
|
||||||
|
|
||||||
@override
|
|
||||||
String toString() {
|
|
||||||
return 'CategoryFailure.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<TResult extends Object?>({
|
|
||||||
required TResult Function(ApiFailure failure) serverError,
|
|
||||||
required TResult Function() unexpectedError,
|
|
||||||
required TResult Function() empty,
|
|
||||||
required TResult Function(String erroMessage) dynamicErrorMessage,
|
|
||||||
}) {
|
|
||||||
return unexpectedError();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult? whenOrNull<TResult extends Object?>({
|
|
||||||
TResult? Function(ApiFailure failure)? serverError,
|
|
||||||
TResult? Function()? unexpectedError,
|
|
||||||
TResult? Function()? empty,
|
|
||||||
TResult? Function(String erroMessage)? dynamicErrorMessage,
|
|
||||||
}) {
|
|
||||||
return unexpectedError?.call();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult maybeWhen<TResult extends Object?>({
|
|
||||||
TResult Function(ApiFailure failure)? serverError,
|
|
||||||
TResult Function()? unexpectedError,
|
|
||||||
TResult Function()? empty,
|
|
||||||
TResult Function(String erroMessage)? dynamicErrorMessage,
|
|
||||||
required TResult orElse(),
|
|
||||||
}) {
|
|
||||||
if (unexpectedError != null) {
|
|
||||||
return unexpectedError();
|
|
||||||
}
|
|
||||||
return orElse();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult map<TResult extends Object?>({
|
|
||||||
required TResult Function(_ServerError value) serverError,
|
|
||||||
required TResult Function(_UnexpectedError value) unexpectedError,
|
|
||||||
required TResult Function(_Empty value) empty,
|
|
||||||
required TResult Function(_DynamicErrorMessage value) dynamicErrorMessage,
|
|
||||||
}) {
|
|
||||||
return unexpectedError(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult? mapOrNull<TResult extends Object?>({
|
|
||||||
TResult? Function(_ServerError value)? serverError,
|
|
||||||
TResult? Function(_UnexpectedError value)? unexpectedError,
|
|
||||||
TResult? Function(_Empty value)? empty,
|
|
||||||
TResult? Function(_DynamicErrorMessage value)? dynamicErrorMessage,
|
|
||||||
}) {
|
|
||||||
return unexpectedError?.call(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult maybeMap<TResult extends Object?>({
|
|
||||||
TResult Function(_ServerError value)? serverError,
|
|
||||||
TResult Function(_UnexpectedError value)? unexpectedError,
|
|
||||||
TResult Function(_Empty value)? empty,
|
|
||||||
TResult Function(_DynamicErrorMessage value)? dynamicErrorMessage,
|
|
||||||
required TResult orElse(),
|
|
||||||
}) {
|
|
||||||
if (unexpectedError != null) {
|
|
||||||
return unexpectedError(this);
|
|
||||||
}
|
|
||||||
return orElse();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract class _UnexpectedError implements CategoryFailure {
|
|
||||||
const factory _UnexpectedError() = _$UnexpectedErrorImpl;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
abstract class _$$EmptyImplCopyWith<$Res> {
|
|
||||||
factory _$$EmptyImplCopyWith(
|
|
||||||
_$EmptyImpl value,
|
|
||||||
$Res Function(_$EmptyImpl) then,
|
|
||||||
) = __$$EmptyImplCopyWithImpl<$Res>;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
class __$$EmptyImplCopyWithImpl<$Res>
|
|
||||||
extends _$CategoryFailureCopyWithImpl<$Res, _$EmptyImpl>
|
|
||||||
implements _$$EmptyImplCopyWith<$Res> {
|
|
||||||
__$$EmptyImplCopyWithImpl(
|
|
||||||
_$EmptyImpl _value,
|
|
||||||
$Res Function(_$EmptyImpl) _then,
|
|
||||||
) : super(_value, _then);
|
|
||||||
|
|
||||||
/// Create a copy of CategoryFailure
|
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
|
|
||||||
class _$EmptyImpl implements _Empty {
|
|
||||||
const _$EmptyImpl();
|
|
||||||
|
|
||||||
@override
|
|
||||||
String toString() {
|
|
||||||
return 'CategoryFailure.empty()';
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
bool operator ==(Object other) {
|
|
||||||
return identical(this, other) ||
|
|
||||||
(other.runtimeType == runtimeType && other is _$EmptyImpl);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
int get hashCode => runtimeType.hashCode;
|
|
||||||
|
|
||||||
@override
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult when<TResult extends Object?>({
|
|
||||||
required TResult Function(ApiFailure failure) serverError,
|
|
||||||
required TResult Function() unexpectedError,
|
|
||||||
required TResult Function() empty,
|
|
||||||
required TResult Function(String erroMessage) dynamicErrorMessage,
|
|
||||||
}) {
|
|
||||||
return empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult? whenOrNull<TResult extends Object?>({
|
|
||||||
TResult? Function(ApiFailure failure)? serverError,
|
|
||||||
TResult? Function()? unexpectedError,
|
|
||||||
TResult? Function()? empty,
|
|
||||||
TResult? Function(String erroMessage)? dynamicErrorMessage,
|
|
||||||
}) {
|
|
||||||
return empty?.call();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult maybeWhen<TResult extends Object?>({
|
|
||||||
TResult Function(ApiFailure failure)? serverError,
|
|
||||||
TResult Function()? unexpectedError,
|
|
||||||
TResult Function()? empty,
|
|
||||||
TResult Function(String erroMessage)? dynamicErrorMessage,
|
|
||||||
required TResult orElse(),
|
|
||||||
}) {
|
|
||||||
if (empty != null) {
|
|
||||||
return empty();
|
|
||||||
}
|
|
||||||
return orElse();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult map<TResult extends Object?>({
|
|
||||||
required TResult Function(_ServerError value) serverError,
|
|
||||||
required TResult Function(_UnexpectedError value) unexpectedError,
|
|
||||||
required TResult Function(_Empty value) empty,
|
|
||||||
required TResult Function(_DynamicErrorMessage value) dynamicErrorMessage,
|
|
||||||
}) {
|
|
||||||
return empty(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult? mapOrNull<TResult extends Object?>({
|
|
||||||
TResult? Function(_ServerError value)? serverError,
|
|
||||||
TResult? Function(_UnexpectedError value)? unexpectedError,
|
|
||||||
TResult? Function(_Empty value)? empty,
|
|
||||||
TResult? Function(_DynamicErrorMessage value)? dynamicErrorMessage,
|
|
||||||
}) {
|
|
||||||
return empty?.call(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult maybeMap<TResult extends Object?>({
|
|
||||||
TResult Function(_ServerError value)? serverError,
|
|
||||||
TResult Function(_UnexpectedError value)? unexpectedError,
|
|
||||||
TResult Function(_Empty value)? empty,
|
|
||||||
TResult Function(_DynamicErrorMessage value)? dynamicErrorMessage,
|
|
||||||
required TResult orElse(),
|
|
||||||
}) {
|
|
||||||
if (empty != null) {
|
|
||||||
return empty(this);
|
|
||||||
}
|
|
||||||
return orElse();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract class _Empty implements CategoryFailure {
|
|
||||||
const factory _Empty() = _$EmptyImpl;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @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 _$CategoryFailureCopyWithImpl<$Res, _$DynamicErrorMessageImpl>
|
|
||||||
implements _$$DynamicErrorMessageImplCopyWith<$Res> {
|
|
||||||
__$$DynamicErrorMessageImplCopyWithImpl(
|
|
||||||
_$DynamicErrorMessageImpl _value,
|
|
||||||
$Res Function(_$DynamicErrorMessageImpl) _then,
|
|
||||||
) : super(_value, _then);
|
|
||||||
|
|
||||||
/// Create a copy of CategoryFailure
|
|
||||||
/// 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 'CategoryFailure.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 CategoryFailure
|
|
||||||
/// 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<TResult extends Object?>({
|
|
||||||
required TResult Function(ApiFailure failure) serverError,
|
|
||||||
required TResult Function() unexpectedError,
|
|
||||||
required TResult Function() empty,
|
|
||||||
required TResult Function(String erroMessage) dynamicErrorMessage,
|
|
||||||
}) {
|
|
||||||
return dynamicErrorMessage(erroMessage);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult? whenOrNull<TResult extends Object?>({
|
|
||||||
TResult? Function(ApiFailure failure)? serverError,
|
|
||||||
TResult? Function()? unexpectedError,
|
|
||||||
TResult? Function()? empty,
|
|
||||||
TResult? Function(String erroMessage)? dynamicErrorMessage,
|
|
||||||
}) {
|
|
||||||
return dynamicErrorMessage?.call(erroMessage);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult maybeWhen<TResult extends Object?>({
|
|
||||||
TResult Function(ApiFailure failure)? serverError,
|
|
||||||
TResult Function()? unexpectedError,
|
|
||||||
TResult Function()? empty,
|
|
||||||
TResult Function(String erroMessage)? dynamicErrorMessage,
|
|
||||||
required TResult orElse(),
|
|
||||||
}) {
|
|
||||||
if (dynamicErrorMessage != null) {
|
|
||||||
return dynamicErrorMessage(erroMessage);
|
|
||||||
}
|
|
||||||
return orElse();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult map<TResult extends Object?>({
|
|
||||||
required TResult Function(_ServerError value) serverError,
|
|
||||||
required TResult Function(_UnexpectedError value) unexpectedError,
|
|
||||||
required TResult Function(_Empty value) empty,
|
|
||||||
required TResult Function(_DynamicErrorMessage value) dynamicErrorMessage,
|
|
||||||
}) {
|
|
||||||
return dynamicErrorMessage(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult? mapOrNull<TResult extends Object?>({
|
|
||||||
TResult? Function(_ServerError value)? serverError,
|
|
||||||
TResult? Function(_UnexpectedError value)? unexpectedError,
|
|
||||||
TResult? Function(_Empty value)? empty,
|
|
||||||
TResult? Function(_DynamicErrorMessage value)? dynamicErrorMessage,
|
|
||||||
}) {
|
|
||||||
return dynamicErrorMessage?.call(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult maybeMap<TResult extends Object?>({
|
|
||||||
TResult Function(_ServerError value)? serverError,
|
|
||||||
TResult Function(_UnexpectedError value)? unexpectedError,
|
|
||||||
TResult Function(_Empty value)? empty,
|
|
||||||
TResult Function(_DynamicErrorMessage value)? dynamicErrorMessage,
|
|
||||||
required TResult orElse(),
|
|
||||||
}) {
|
|
||||||
if (dynamicErrorMessage != null) {
|
|
||||||
return dynamicErrorMessage(this);
|
|
||||||
}
|
|
||||||
return orElse();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract class _DynamicErrorMessage implements CategoryFailure {
|
|
||||||
const factory _DynamicErrorMessage(final String erroMessage) =
|
|
||||||
_$DynamicErrorMessageImpl;
|
|
||||||
|
|
||||||
String get erroMessage;
|
|
||||||
|
|
||||||
/// Create a copy of CategoryFailure
|
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
|
||||||
_$$DynamicErrorMessageImplCopyWith<_$DynamicErrorMessageImpl> get copyWith =>
|
|
||||||
throw _privateConstructorUsedError;
|
|
||||||
}
|
|
||||||
@ -1,33 +0,0 @@
|
|||||||
part of '../category.dart';
|
|
||||||
|
|
||||||
@freezed
|
|
||||||
class Category with _$Category {
|
|
||||||
const factory Category({
|
|
||||||
required String id,
|
|
||||||
required String organizationId,
|
|
||||||
required String name,
|
|
||||||
required String description,
|
|
||||||
required String businessType,
|
|
||||||
required Map<String, dynamic> metadata,
|
|
||||||
DateTime? createdAt,
|
|
||||||
DateTime? updatedAt,
|
|
||||||
}) = _Category;
|
|
||||||
|
|
||||||
factory Category.empty() => const Category(
|
|
||||||
id: '',
|
|
||||||
organizationId: '',
|
|
||||||
name: '',
|
|
||||||
description: '',
|
|
||||||
businessType: '',
|
|
||||||
metadata: {},
|
|
||||||
);
|
|
||||||
|
|
||||||
factory Category.addAllData() => Category(
|
|
||||||
id: 'all',
|
|
||||||
organizationId: '',
|
|
||||||
name: 'Semua',
|
|
||||||
description: '',
|
|
||||||
businessType: '',
|
|
||||||
metadata: {},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@ -1,10 +0,0 @@
|
|||||||
part of '../category.dart';
|
|
||||||
|
|
||||||
@freezed
|
|
||||||
sealed class CategoryFailure with _$CategoryFailure {
|
|
||||||
const factory CategoryFailure.serverError(ApiFailure failure) = _ServerError;
|
|
||||||
const factory CategoryFailure.unexpectedError() = _UnexpectedError;
|
|
||||||
const factory CategoryFailure.empty() = _Empty;
|
|
||||||
const factory CategoryFailure.dynamicErrorMessage(String erroMessage) =
|
|
||||||
_DynamicErrorMessage;
|
|
||||||
}
|
|
||||||
@ -1,9 +0,0 @@
|
|||||||
part of '../category.dart';
|
|
||||||
|
|
||||||
abstract class ICategoryRepository {
|
|
||||||
Future<Either<CategoryFailure, List<Category>>> get({
|
|
||||||
int page = 1,
|
|
||||||
int limit = 20,
|
|
||||||
bool isActive = true,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
@ -1,43 +0,0 @@
|
|||||||
part of '../product.dart';
|
|
||||||
|
|
||||||
@freezed
|
|
||||||
class Product with _$Product {
|
|
||||||
const factory Product({
|
|
||||||
required String id,
|
|
||||||
required String organizationId,
|
|
||||||
required String categoryId,
|
|
||||||
required String sku,
|
|
||||||
required String name,
|
|
||||||
required String description,
|
|
||||||
required int price,
|
|
||||||
required int cost,
|
|
||||||
required String businessType,
|
|
||||||
required String imageUrl,
|
|
||||||
required String printerType,
|
|
||||||
required Map<String, dynamic> metadata,
|
|
||||||
required bool isActive,
|
|
||||||
required DateTime createdAt,
|
|
||||||
required DateTime updatedAt,
|
|
||||||
required List<ProductVariant> variants,
|
|
||||||
}) = _Product;
|
|
||||||
|
|
||||||
/// âś… factory kosong untuk default state
|
|
||||||
factory Product.empty() => Product(
|
|
||||||
id: '',
|
|
||||||
organizationId: '',
|
|
||||||
categoryId: '',
|
|
||||||
sku: '',
|
|
||||||
name: '',
|
|
||||||
description: '',
|
|
||||||
price: 0,
|
|
||||||
cost: 0,
|
|
||||||
businessType: '',
|
|
||||||
imageUrl: '',
|
|
||||||
printerType: '',
|
|
||||||
metadata: {},
|
|
||||||
isActive: false,
|
|
||||||
createdAt: DateTime.now(),
|
|
||||||
updatedAt: DateTime.now(),
|
|
||||||
variants: [],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@ -1,26 +0,0 @@
|
|||||||
part of '../product.dart';
|
|
||||||
|
|
||||||
@freezed
|
|
||||||
class ProductVariant with _$ProductVariant {
|
|
||||||
const factory ProductVariant({
|
|
||||||
required String id,
|
|
||||||
required String productId,
|
|
||||||
required String name,
|
|
||||||
required int priceModifier,
|
|
||||||
required int cost,
|
|
||||||
required Map<String, dynamic> metadata,
|
|
||||||
required DateTime createdAt,
|
|
||||||
required DateTime updatedAt,
|
|
||||||
}) = _ProductVariant;
|
|
||||||
|
|
||||||
factory ProductVariant.empty() => ProductVariant(
|
|
||||||
id: '',
|
|
||||||
productId: '',
|
|
||||||
name: '',
|
|
||||||
priceModifier: 0,
|
|
||||||
cost: 0,
|
|
||||||
metadata: {},
|
|
||||||
createdAt: DateTime.now(),
|
|
||||||
updatedAt: DateTime.now(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@ -1,10 +0,0 @@
|
|||||||
part of '../product.dart';
|
|
||||||
|
|
||||||
@freezed
|
|
||||||
sealed class ProductFailure with _$ProductFailure {
|
|
||||||
const factory ProductFailure.serverError(ApiFailure failure) = _ServerError;
|
|
||||||
const factory ProductFailure.unexpectedError() = _UnexpectedError;
|
|
||||||
const factory ProductFailure.empty() = _Empty;
|
|
||||||
const factory ProductFailure.dynamicErrorMessage(String erroMessage) =
|
|
||||||
_DynamicErrorMessage;
|
|
||||||
}
|
|
||||||
@ -1,11 +0,0 @@
|
|||||||
import 'package:dartz/dartz.dart';
|
|
||||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
|
||||||
|
|
||||||
import '../../common/api/api_failure.dart';
|
|
||||||
|
|
||||||
part 'product.freezed.dart';
|
|
||||||
|
|
||||||
part 'entities/product_entity.dart';
|
|
||||||
part 'entities/product_variant_entity.dart';
|
|
||||||
part 'failures/product_failure.dart';
|
|
||||||
part 'repositories/i_product_repository.dart';
|
|
||||||
File diff suppressed because it is too large
Load Diff
@ -1,10 +0,0 @@
|
|||||||
part of '../product.dart';
|
|
||||||
|
|
||||||
abstract class IProductRepository {
|
|
||||||
Future<Either<ProductFailure, List<Product>>> get({
|
|
||||||
int page = 1,
|
|
||||||
int limit = 10,
|
|
||||||
String? categoryId,
|
|
||||||
String? search,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
@ -1,10 +0,0 @@
|
|||||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
|
||||||
|
|
||||||
import '../../domain/analytic/analytic.dart';
|
|
||||||
|
|
||||||
part 'analytic_dtos.freezed.dart';
|
|
||||||
part 'analytic_dtos.g.dart';
|
|
||||||
|
|
||||||
part 'dto/sales_analytic_dto.dart';
|
|
||||||
part 'dto/profit_loss_analytic_dto.dart';
|
|
||||||
part 'dto/category_analytic_dto.dart';
|
|
||||||
File diff suppressed because it is too large
Load Diff
@ -1,259 +0,0 @@
|
|||||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
|
||||||
|
|
||||||
part of 'analytic_dtos.dart';
|
|
||||||
|
|
||||||
// **************************************************************************
|
|
||||||
// JsonSerializableGenerator
|
|
||||||
// **************************************************************************
|
|
||||||
|
|
||||||
_$SalesAnalyticDtoImpl _$$SalesAnalyticDtoImplFromJson(
|
|
||||||
Map<String, dynamic> json,
|
|
||||||
) => _$SalesAnalyticDtoImpl(
|
|
||||||
organizationId: json['organization_id'] as String?,
|
|
||||||
outletId: json['outlet_id'] as String?,
|
|
||||||
dateFrom: json['date_from'] == null
|
|
||||||
? null
|
|
||||||
: DateTime.parse(json['date_from'] as String),
|
|
||||||
dateTo: json['date_to'] == null
|
|
||||||
? null
|
|
||||||
: DateTime.parse(json['date_to'] as String),
|
|
||||||
groupBy: json['group_by'] as String?,
|
|
||||||
summary: json['summary'] == null
|
|
||||||
? null
|
|
||||||
: SalesAnalyticSummaryDto.fromJson(
|
|
||||||
json['summary'] as Map<String, dynamic>,
|
|
||||||
),
|
|
||||||
data: (json['data'] as List<dynamic>?)
|
|
||||||
?.map((e) => SalesAnalyticDataDto.fromJson(e as Map<String, dynamic>))
|
|
||||||
.toList(),
|
|
||||||
);
|
|
||||||
|
|
||||||
Map<String, dynamic> _$$SalesAnalyticDtoImplToJson(
|
|
||||||
_$SalesAnalyticDtoImpl instance,
|
|
||||||
) => <String, dynamic>{
|
|
||||||
'organization_id': instance.organizationId,
|
|
||||||
'outlet_id': instance.outletId,
|
|
||||||
'date_from': instance.dateFrom?.toIso8601String(),
|
|
||||||
'date_to': instance.dateTo?.toIso8601String(),
|
|
||||||
'group_by': instance.groupBy,
|
|
||||||
'summary': instance.summary,
|
|
||||||
'data': instance.data,
|
|
||||||
};
|
|
||||||
|
|
||||||
_$SalesAnalyticSummaryDtoImpl _$$SalesAnalyticSummaryDtoImplFromJson(
|
|
||||||
Map<String, dynamic> json,
|
|
||||||
) => _$SalesAnalyticSummaryDtoImpl(
|
|
||||||
totalSales: json['total_sales'] as num?,
|
|
||||||
totalOrders: json['total_orders'] as num?,
|
|
||||||
totalItems: json['total_items'] as num?,
|
|
||||||
averageOrderValue: json['average_order_value'] as num?,
|
|
||||||
totalTax: json['total_tax'] as num?,
|
|
||||||
totalDiscount: json['total_discount'] as num?,
|
|
||||||
netSales: json['net_sales'] as num?,
|
|
||||||
);
|
|
||||||
|
|
||||||
Map<String, dynamic> _$$SalesAnalyticSummaryDtoImplToJson(
|
|
||||||
_$SalesAnalyticSummaryDtoImpl instance,
|
|
||||||
) => <String, dynamic>{
|
|
||||||
'total_sales': instance.totalSales,
|
|
||||||
'total_orders': instance.totalOrders,
|
|
||||||
'total_items': instance.totalItems,
|
|
||||||
'average_order_value': instance.averageOrderValue,
|
|
||||||
'total_tax': instance.totalTax,
|
|
||||||
'total_discount': instance.totalDiscount,
|
|
||||||
'net_sales': instance.netSales,
|
|
||||||
};
|
|
||||||
|
|
||||||
_$SalesAnalyticDataDtoImpl _$$SalesAnalyticDataDtoImplFromJson(
|
|
||||||
Map<String, dynamic> json,
|
|
||||||
) => _$SalesAnalyticDataDtoImpl(
|
|
||||||
date: json['date'] == null ? null : DateTime.parse(json['date'] as String),
|
|
||||||
sales: json['sales'] as num?,
|
|
||||||
orders: json['orders'] as num?,
|
|
||||||
items: json['items'] as num?,
|
|
||||||
tax: json['tax'] as num?,
|
|
||||||
discount: json['discount'] as num?,
|
|
||||||
netSales: json['net_sales'] as num?,
|
|
||||||
);
|
|
||||||
|
|
||||||
Map<String, dynamic> _$$SalesAnalyticDataDtoImplToJson(
|
|
||||||
_$SalesAnalyticDataDtoImpl instance,
|
|
||||||
) => <String, dynamic>{
|
|
||||||
'date': instance.date?.toIso8601String(),
|
|
||||||
'sales': instance.sales,
|
|
||||||
'orders': instance.orders,
|
|
||||||
'items': instance.items,
|
|
||||||
'tax': instance.tax,
|
|
||||||
'discount': instance.discount,
|
|
||||||
'net_sales': instance.netSales,
|
|
||||||
};
|
|
||||||
|
|
||||||
_$ProfitLossAnalyticDtoImpl _$$ProfitLossAnalyticDtoImplFromJson(
|
|
||||||
Map<String, dynamic> json,
|
|
||||||
) => _$ProfitLossAnalyticDtoImpl(
|
|
||||||
organizationId: json['organization_id'] as String?,
|
|
||||||
dateFrom: json['date_from'] as String?,
|
|
||||||
dateTo: json['date_to'] as String?,
|
|
||||||
groupBy: json['group_by'] as String?,
|
|
||||||
summary: json['summary'] == null
|
|
||||||
? null
|
|
||||||
: ProfitLossSummaryDto.fromJson(json['summary'] as Map<String, dynamic>),
|
|
||||||
data: (json['data'] as List<dynamic>?)
|
|
||||||
?.map((e) => ProfitLossDailyDataDto.fromJson(e as Map<String, dynamic>))
|
|
||||||
.toList(),
|
|
||||||
productData: (json['product_data'] as List<dynamic>?)
|
|
||||||
?.map((e) => ProfitLossProductDataDto.fromJson(e as Map<String, dynamic>))
|
|
||||||
.toList(),
|
|
||||||
);
|
|
||||||
|
|
||||||
Map<String, dynamic> _$$ProfitLossAnalyticDtoImplToJson(
|
|
||||||
_$ProfitLossAnalyticDtoImpl instance,
|
|
||||||
) => <String, dynamic>{
|
|
||||||
'organization_id': instance.organizationId,
|
|
||||||
'date_from': instance.dateFrom,
|
|
||||||
'date_to': instance.dateTo,
|
|
||||||
'group_by': instance.groupBy,
|
|
||||||
'summary': instance.summary,
|
|
||||||
'data': instance.data,
|
|
||||||
'product_data': instance.productData,
|
|
||||||
};
|
|
||||||
|
|
||||||
_$ProfitLossSummaryDtoImpl _$$ProfitLossSummaryDtoImplFromJson(
|
|
||||||
Map<String, dynamic> json,
|
|
||||||
) => _$ProfitLossSummaryDtoImpl(
|
|
||||||
totalRevenue: (json['total_revenue'] as num?)?.toInt(),
|
|
||||||
totalCost: (json['total_cost'] as num?)?.toInt(),
|
|
||||||
grossProfit: (json['gross_profit'] as num?)?.toInt(),
|
|
||||||
grossProfitMargin: (json['gross_profit_margin'] as num?)?.toDouble(),
|
|
||||||
totalTax: (json['total_tax'] as num?)?.toInt(),
|
|
||||||
totalDiscount: (json['total_discount'] as num?)?.toInt(),
|
|
||||||
netProfit: (json['net_profit'] as num?)?.toInt(),
|
|
||||||
netProfitMargin: (json['net_profit_margin'] as num?)?.toDouble(),
|
|
||||||
totalOrders: (json['total_orders'] as num?)?.toInt(),
|
|
||||||
averageProfit: (json['average_profit'] as num?)?.toDouble(),
|
|
||||||
profitabilityRatio: (json['profitability_ratio'] as num?)?.toDouble(),
|
|
||||||
);
|
|
||||||
|
|
||||||
Map<String, dynamic> _$$ProfitLossSummaryDtoImplToJson(
|
|
||||||
_$ProfitLossSummaryDtoImpl instance,
|
|
||||||
) => <String, dynamic>{
|
|
||||||
'total_revenue': instance.totalRevenue,
|
|
||||||
'total_cost': instance.totalCost,
|
|
||||||
'gross_profit': instance.grossProfit,
|
|
||||||
'gross_profit_margin': instance.grossProfitMargin,
|
|
||||||
'total_tax': instance.totalTax,
|
|
||||||
'total_discount': instance.totalDiscount,
|
|
||||||
'net_profit': instance.netProfit,
|
|
||||||
'net_profit_margin': instance.netProfitMargin,
|
|
||||||
'total_orders': instance.totalOrders,
|
|
||||||
'average_profit': instance.averageProfit,
|
|
||||||
'profitability_ratio': instance.profitabilityRatio,
|
|
||||||
};
|
|
||||||
|
|
||||||
_$ProfitLossDailyDataDtoImpl _$$ProfitLossDailyDataDtoImplFromJson(
|
|
||||||
Map<String, dynamic> json,
|
|
||||||
) => _$ProfitLossDailyDataDtoImpl(
|
|
||||||
date: json['date'] as String?,
|
|
||||||
revenue: (json['revenue'] as num?)?.toInt(),
|
|
||||||
cost: (json['cost'] as num?)?.toInt(),
|
|
||||||
grossProfit: (json['gross_profit'] as num?)?.toInt(),
|
|
||||||
grossProfitMargin: (json['gross_profit_margin'] as num?)?.toDouble(),
|
|
||||||
tax: (json['tax'] as num?)?.toInt(),
|
|
||||||
discount: (json['discount'] as num?)?.toInt(),
|
|
||||||
netProfit: (json['net_profit'] as num?)?.toInt(),
|
|
||||||
netProfitMargin: (json['net_profit_margin'] as num?)?.toDouble(),
|
|
||||||
orders: (json['orders'] as num?)?.toInt(),
|
|
||||||
);
|
|
||||||
|
|
||||||
Map<String, dynamic> _$$ProfitLossDailyDataDtoImplToJson(
|
|
||||||
_$ProfitLossDailyDataDtoImpl instance,
|
|
||||||
) => <String, dynamic>{
|
|
||||||
'date': instance.date,
|
|
||||||
'revenue': instance.revenue,
|
|
||||||
'cost': instance.cost,
|
|
||||||
'gross_profit': instance.grossProfit,
|
|
||||||
'gross_profit_margin': instance.grossProfitMargin,
|
|
||||||
'tax': instance.tax,
|
|
||||||
'discount': instance.discount,
|
|
||||||
'net_profit': instance.netProfit,
|
|
||||||
'net_profit_margin': instance.netProfitMargin,
|
|
||||||
'orders': instance.orders,
|
|
||||||
};
|
|
||||||
|
|
||||||
_$ProfitLossProductDataDtoImpl _$$ProfitLossProductDataDtoImplFromJson(
|
|
||||||
Map<String, dynamic> json,
|
|
||||||
) => _$ProfitLossProductDataDtoImpl(
|
|
||||||
productId: json['product_id'] as String?,
|
|
||||||
productName: json['product_name'] as String?,
|
|
||||||
categoryId: json['category_id'] as String?,
|
|
||||||
categoryName: json['category_name'] as String?,
|
|
||||||
quantitySold: (json['quantity_sold'] as num?)?.toInt(),
|
|
||||||
revenue: (json['revenue'] as num?)?.toInt(),
|
|
||||||
cost: (json['cost'] as num?)?.toInt(),
|
|
||||||
grossProfit: (json['gross_profit'] as num?)?.toInt(),
|
|
||||||
grossProfitMargin: (json['gross_profit_margin'] as num?)?.toDouble(),
|
|
||||||
averagePrice: (json['average_price'] as num?)?.toInt(),
|
|
||||||
averageCost: (json['average_cost'] as num?)?.toInt(),
|
|
||||||
profitPerUnit: (json['profit_per_unit'] as num?)?.toInt(),
|
|
||||||
);
|
|
||||||
|
|
||||||
Map<String, dynamic> _$$ProfitLossProductDataDtoImplToJson(
|
|
||||||
_$ProfitLossProductDataDtoImpl instance,
|
|
||||||
) => <String, dynamic>{
|
|
||||||
'product_id': instance.productId,
|
|
||||||
'product_name': instance.productName,
|
|
||||||
'category_id': instance.categoryId,
|
|
||||||
'category_name': instance.categoryName,
|
|
||||||
'quantity_sold': instance.quantitySold,
|
|
||||||
'revenue': instance.revenue,
|
|
||||||
'cost': instance.cost,
|
|
||||||
'gross_profit': instance.grossProfit,
|
|
||||||
'gross_profit_margin': instance.grossProfitMargin,
|
|
||||||
'average_price': instance.averagePrice,
|
|
||||||
'average_cost': instance.averageCost,
|
|
||||||
'profit_per_unit': instance.profitPerUnit,
|
|
||||||
};
|
|
||||||
|
|
||||||
_$CategoryAnalyticDtoImpl _$$CategoryAnalyticDtoImplFromJson(
|
|
||||||
Map<String, dynamic> json,
|
|
||||||
) => _$CategoryAnalyticDtoImpl(
|
|
||||||
organizationId: json['organization_id'] as String?,
|
|
||||||
outletId: json['outlet_id'] as String?,
|
|
||||||
dateFrom: json['date_from'] as String?,
|
|
||||||
dateTo: json['date_to'] as String?,
|
|
||||||
data: (json['data'] as List<dynamic>?)
|
|
||||||
?.map((e) => CategoryAnalyticItemDto.fromJson(e as Map<String, dynamic>))
|
|
||||||
.toList(),
|
|
||||||
);
|
|
||||||
|
|
||||||
Map<String, dynamic> _$$CategoryAnalyticDtoImplToJson(
|
|
||||||
_$CategoryAnalyticDtoImpl instance,
|
|
||||||
) => <String, dynamic>{
|
|
||||||
'organization_id': instance.organizationId,
|
|
||||||
'outlet_id': instance.outletId,
|
|
||||||
'date_from': instance.dateFrom,
|
|
||||||
'date_to': instance.dateTo,
|
|
||||||
'data': instance.data,
|
|
||||||
};
|
|
||||||
|
|
||||||
_$CategoryAnalyticItemDtoImpl _$$CategoryAnalyticItemDtoImplFromJson(
|
|
||||||
Map<String, dynamic> json,
|
|
||||||
) => _$CategoryAnalyticItemDtoImpl(
|
|
||||||
categoryId: json['category_id'] as String?,
|
|
||||||
categoryName: json['category_name'] as String?,
|
|
||||||
totalRevenue: (json['total_revenue'] as num?)?.toInt(),
|
|
||||||
totalQuantity: (json['total_quantity'] as num?)?.toInt(),
|
|
||||||
productCount: (json['product_count'] as num?)?.toInt(),
|
|
||||||
orderCount: (json['order_count'] as num?)?.toInt(),
|
|
||||||
);
|
|
||||||
|
|
||||||
Map<String, dynamic> _$$CategoryAnalyticItemDtoImplToJson(
|
|
||||||
_$CategoryAnalyticItemDtoImpl instance,
|
|
||||||
) => <String, dynamic>{
|
|
||||||
'category_id': instance.categoryId,
|
|
||||||
'category_name': instance.categoryName,
|
|
||||||
'total_revenue': instance.totalRevenue,
|
|
||||||
'total_quantity': instance.totalQuantity,
|
|
||||||
'product_count': instance.productCount,
|
|
||||||
'order_count': instance.orderCount,
|
|
||||||
};
|
|
||||||
@ -1,101 +0,0 @@
|
|||||||
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/extension/extension.dart';
|
|
||||||
import '../../../common/function/app_function.dart';
|
|
||||||
import '../../../common/url/api_path.dart';
|
|
||||||
import '../../../domain/analytic/analytic.dart';
|
|
||||||
import '../analytic_dtos.dart';
|
|
||||||
|
|
||||||
@injectable
|
|
||||||
class AnalyticRemoteDataProvider {
|
|
||||||
final ApiClient _apiClient;
|
|
||||||
final String _logName = "AnalyticRemoteDataProvider";
|
|
||||||
|
|
||||||
AnalyticRemoteDataProvider(this._apiClient);
|
|
||||||
|
|
||||||
Future<DC<AnalyticFailure, SalesAnalyticDto>> fetchSales({
|
|
||||||
required DateTime dateFrom,
|
|
||||||
required DateTime dateTo,
|
|
||||||
}) async {
|
|
||||||
try {
|
|
||||||
final response = await _apiClient.get(
|
|
||||||
ApiPath.salesAnalytic,
|
|
||||||
params: {
|
|
||||||
'date_from': dateFrom.toServerDate,
|
|
||||||
'date_to': dateTo.toServerDate,
|
|
||||||
},
|
|
||||||
headers: getAuthorizationHeader(),
|
|
||||||
);
|
|
||||||
|
|
||||||
if (response.data['data'] == null) {
|
|
||||||
return DC.error(AnalyticFailure.empty());
|
|
||||||
}
|
|
||||||
|
|
||||||
final dto = SalesAnalyticDto.fromJson(response.data['data']);
|
|
||||||
|
|
||||||
return DC.data(dto);
|
|
||||||
} on ApiFailure catch (e, s) {
|
|
||||||
log('fetchSalesError', name: _logName, error: e, stackTrace: s);
|
|
||||||
return DC.error(AnalyticFailure.serverError(e));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<DC<AnalyticFailure, ProfitLossAnalyticDto>> fetchProfitLoss({
|
|
||||||
required DateTime dateFrom,
|
|
||||||
required DateTime dateTo,
|
|
||||||
}) async {
|
|
||||||
try {
|
|
||||||
final response = await _apiClient.get(
|
|
||||||
ApiPath.profitLossAnalytic,
|
|
||||||
params: {
|
|
||||||
'date_from': dateFrom.toServerDate,
|
|
||||||
'date_to': dateTo.toServerDate,
|
|
||||||
},
|
|
||||||
headers: getAuthorizationHeader(),
|
|
||||||
);
|
|
||||||
|
|
||||||
if (response.data['data'] == null) {
|
|
||||||
return DC.error(AnalyticFailure.empty());
|
|
||||||
}
|
|
||||||
|
|
||||||
final dto = ProfitLossAnalyticDto.fromJson(response.data['data']);
|
|
||||||
|
|
||||||
return DC.data(dto);
|
|
||||||
} on ApiFailure catch (e, s) {
|
|
||||||
log('fetchProfitLossError', name: _logName, error: e, stackTrace: s);
|
|
||||||
return DC.error(AnalyticFailure.serverError(e));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<DC<AnalyticFailure, CategoryAnalyticDto>> fetchCategory({
|
|
||||||
required DateTime dateFrom,
|
|
||||||
required DateTime dateTo,
|
|
||||||
}) async {
|
|
||||||
try {
|
|
||||||
final response = await _apiClient.get(
|
|
||||||
ApiPath.categoryAnalytic,
|
|
||||||
params: {
|
|
||||||
'date_from': dateFrom.toServerDate,
|
|
||||||
'date_to': dateTo.toServerDate,
|
|
||||||
},
|
|
||||||
headers: getAuthorizationHeader(),
|
|
||||||
);
|
|
||||||
|
|
||||||
if (response.data['data'] == null) {
|
|
||||||
return DC.error(AnalyticFailure.empty());
|
|
||||||
}
|
|
||||||
|
|
||||||
final dto = CategoryAnalyticDto.fromJson(response.data['data']);
|
|
||||||
|
|
||||||
return DC.data(dto);
|
|
||||||
} on ApiFailure catch (e, s) {
|
|
||||||
log('fetchCategoryError', name: _logName, error: e, stackTrace: s);
|
|
||||||
return DC.error(AnalyticFailure.serverError(e));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,51 +0,0 @@
|
|||||||
part of '../analytic_dtos.dart';
|
|
||||||
|
|
||||||
@freezed
|
|
||||||
class CategoryAnalyticDto with _$CategoryAnalyticDto {
|
|
||||||
const CategoryAnalyticDto._();
|
|
||||||
|
|
||||||
const factory CategoryAnalyticDto({
|
|
||||||
@JsonKey(name: 'organization_id') String? organizationId,
|
|
||||||
@JsonKey(name: 'outlet_id') String? outletId,
|
|
||||||
@JsonKey(name: 'date_from') String? dateFrom,
|
|
||||||
@JsonKey(name: 'date_to') String? dateTo,
|
|
||||||
@JsonKey(name: 'data') List<CategoryAnalyticItemDto>? data,
|
|
||||||
}) = _CategoryAnalyticDto;
|
|
||||||
|
|
||||||
factory CategoryAnalyticDto.fromJson(Map<String, dynamic> json) =>
|
|
||||||
_$CategoryAnalyticDtoFromJson(json);
|
|
||||||
|
|
||||||
CategoryAnalytic toDomain() => CategoryAnalytic(
|
|
||||||
organizationId: organizationId ?? "",
|
|
||||||
outletId: outletId ?? "",
|
|
||||||
dateFrom: dateFrom ?? "",
|
|
||||||
dateTo: dateTo ?? "",
|
|
||||||
data: data?.map((e) => e.toDomain()).toList() ?? [],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@freezed
|
|
||||||
class CategoryAnalyticItemDto with _$CategoryAnalyticItemDto {
|
|
||||||
const CategoryAnalyticItemDto._();
|
|
||||||
|
|
||||||
const factory CategoryAnalyticItemDto({
|
|
||||||
@JsonKey(name: 'category_id') String? categoryId,
|
|
||||||
@JsonKey(name: 'category_name') String? categoryName,
|
|
||||||
@JsonKey(name: 'total_revenue') int? totalRevenue,
|
|
||||||
@JsonKey(name: 'total_quantity') int? totalQuantity,
|
|
||||||
@JsonKey(name: 'product_count') int? productCount,
|
|
||||||
@JsonKey(name: 'order_count') int? orderCount,
|
|
||||||
}) = _CategoryAnalyticItemDto;
|
|
||||||
|
|
||||||
factory CategoryAnalyticItemDto.fromJson(Map<String, dynamic> json) =>
|
|
||||||
_$CategoryAnalyticItemDtoFromJson(json);
|
|
||||||
|
|
||||||
CategoryAnalyticItem toDomain() => CategoryAnalyticItem(
|
|
||||||
categoryId: categoryId ?? "",
|
|
||||||
categoryName: categoryName ?? "",
|
|
||||||
totalRevenue: totalRevenue ?? 0,
|
|
||||||
totalQuantity: totalQuantity ?? 0,
|
|
||||||
productCount: productCount ?? 0,
|
|
||||||
orderCount: orderCount ?? 0,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@ -1,137 +0,0 @@
|
|||||||
part of '../analytic_dtos.dart';
|
|
||||||
|
|
||||||
@freezed
|
|
||||||
class ProfitLossAnalyticDto with _$ProfitLossAnalyticDto {
|
|
||||||
const ProfitLossAnalyticDto._();
|
|
||||||
|
|
||||||
const factory ProfitLossAnalyticDto({
|
|
||||||
@JsonKey(name: 'organization_id') String? organizationId,
|
|
||||||
@JsonKey(name: 'date_from') String? dateFrom,
|
|
||||||
@JsonKey(name: 'date_to') String? dateTo,
|
|
||||||
@JsonKey(name: 'group_by') String? groupBy,
|
|
||||||
@JsonKey(name: 'summary') ProfitLossSummaryDto? summary,
|
|
||||||
@JsonKey(name: 'data') List<ProfitLossDailyDataDto>? data,
|
|
||||||
@JsonKey(name: 'product_data') List<ProfitLossProductDataDto>? productData,
|
|
||||||
}) = _ProfitLossAnalyticDto;
|
|
||||||
|
|
||||||
factory ProfitLossAnalyticDto.fromJson(Map<String, dynamic> json) =>
|
|
||||||
_$ProfitLossAnalyticDtoFromJson(json);
|
|
||||||
|
|
||||||
ProfitLossAnalytic toDomain() => ProfitLossAnalytic(
|
|
||||||
organizationId: organizationId ?? '',
|
|
||||||
dateFrom: dateFrom ?? '',
|
|
||||||
dateTo: dateTo ?? '',
|
|
||||||
groupBy: groupBy ?? '',
|
|
||||||
summary: summary?.toDomain() ?? ProfitLossSummary.empty(),
|
|
||||||
data: (data ?? []).map((e) => e.toDomain()).toList(),
|
|
||||||
productData: (productData ?? []).map((e) => e.toDomain()).toList(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@freezed
|
|
||||||
class ProfitLossSummaryDto with _$ProfitLossSummaryDto {
|
|
||||||
const ProfitLossSummaryDto._();
|
|
||||||
|
|
||||||
const factory ProfitLossSummaryDto({
|
|
||||||
@JsonKey(name: 'total_revenue') int? totalRevenue,
|
|
||||||
@JsonKey(name: 'total_cost') int? totalCost,
|
|
||||||
@JsonKey(name: 'gross_profit') int? grossProfit,
|
|
||||||
@JsonKey(name: 'gross_profit_margin') double? grossProfitMargin,
|
|
||||||
@JsonKey(name: 'total_tax') int? totalTax,
|
|
||||||
@JsonKey(name: 'total_discount') int? totalDiscount,
|
|
||||||
@JsonKey(name: 'net_profit') int? netProfit,
|
|
||||||
@JsonKey(name: 'net_profit_margin') double? netProfitMargin,
|
|
||||||
@JsonKey(name: 'total_orders') int? totalOrders,
|
|
||||||
@JsonKey(name: 'average_profit') double? averageProfit,
|
|
||||||
@JsonKey(name: 'profitability_ratio') double? profitabilityRatio,
|
|
||||||
}) = _ProfitLossSummaryDto;
|
|
||||||
|
|
||||||
factory ProfitLossSummaryDto.fromJson(Map<String, dynamic> json) =>
|
|
||||||
_$ProfitLossSummaryDtoFromJson(json);
|
|
||||||
|
|
||||||
ProfitLossSummary toDomain() => ProfitLossSummary(
|
|
||||||
totalRevenue: totalRevenue ?? 0,
|
|
||||||
totalCost: totalCost ?? 0,
|
|
||||||
grossProfit: grossProfit ?? 0,
|
|
||||||
grossProfitMargin: grossProfitMargin ?? 0.0,
|
|
||||||
totalTax: totalTax ?? 0,
|
|
||||||
totalDiscount: totalDiscount ?? 0,
|
|
||||||
netProfit: netProfit ?? 0,
|
|
||||||
netProfitMargin: netProfitMargin ?? 0.0,
|
|
||||||
totalOrders: totalOrders ?? 0,
|
|
||||||
averageProfit: averageProfit ?? 0.0,
|
|
||||||
profitabilityRatio: profitabilityRatio ?? 0.0,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@freezed
|
|
||||||
class ProfitLossDailyDataDto with _$ProfitLossDailyDataDto {
|
|
||||||
const ProfitLossDailyDataDto._();
|
|
||||||
|
|
||||||
const factory ProfitLossDailyDataDto({
|
|
||||||
@JsonKey(name: 'date') String? date,
|
|
||||||
@JsonKey(name: 'revenue') int? revenue,
|
|
||||||
@JsonKey(name: 'cost') int? cost,
|
|
||||||
@JsonKey(name: 'gross_profit') int? grossProfit,
|
|
||||||
@JsonKey(name: 'gross_profit_margin') double? grossProfitMargin,
|
|
||||||
@JsonKey(name: 'tax') int? tax,
|
|
||||||
@JsonKey(name: 'discount') int? discount,
|
|
||||||
@JsonKey(name: 'net_profit') int? netProfit,
|
|
||||||
@JsonKey(name: 'net_profit_margin') double? netProfitMargin,
|
|
||||||
@JsonKey(name: 'orders') int? orders,
|
|
||||||
}) = _ProfitLossDailyDataDto;
|
|
||||||
|
|
||||||
factory ProfitLossDailyDataDto.fromJson(Map<String, dynamic> json) =>
|
|
||||||
_$ProfitLossDailyDataDtoFromJson(json);
|
|
||||||
|
|
||||||
ProfitLossDailyData toDomain() => ProfitLossDailyData(
|
|
||||||
date: date ?? '',
|
|
||||||
revenue: revenue ?? 0,
|
|
||||||
cost: cost ?? 0,
|
|
||||||
grossProfit: grossProfit ?? 0,
|
|
||||||
grossProfitMargin: grossProfitMargin ?? 0.0,
|
|
||||||
tax: tax ?? 0,
|
|
||||||
discount: discount ?? 0,
|
|
||||||
netProfit: netProfit ?? 0,
|
|
||||||
netProfitMargin: netProfitMargin ?? 0.0,
|
|
||||||
orders: orders ?? 0,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@freezed
|
|
||||||
class ProfitLossProductDataDto with _$ProfitLossProductDataDto {
|
|
||||||
const ProfitLossProductDataDto._();
|
|
||||||
|
|
||||||
const factory ProfitLossProductDataDto({
|
|
||||||
@JsonKey(name: 'product_id') String? productId,
|
|
||||||
@JsonKey(name: 'product_name') String? productName,
|
|
||||||
@JsonKey(name: 'category_id') String? categoryId,
|
|
||||||
@JsonKey(name: 'category_name') String? categoryName,
|
|
||||||
@JsonKey(name: 'quantity_sold') int? quantitySold,
|
|
||||||
@JsonKey(name: 'revenue') int? revenue,
|
|
||||||
@JsonKey(name: 'cost') int? cost,
|
|
||||||
@JsonKey(name: 'gross_profit') int? grossProfit,
|
|
||||||
@JsonKey(name: 'gross_profit_margin') double? grossProfitMargin,
|
|
||||||
@JsonKey(name: 'average_price') int? averagePrice,
|
|
||||||
@JsonKey(name: 'average_cost') int? averageCost,
|
|
||||||
@JsonKey(name: 'profit_per_unit') int? profitPerUnit,
|
|
||||||
}) = _ProfitLossProductDataDto;
|
|
||||||
|
|
||||||
factory ProfitLossProductDataDto.fromJson(Map<String, dynamic> json) =>
|
|
||||||
_$ProfitLossProductDataDtoFromJson(json);
|
|
||||||
|
|
||||||
ProfitLossProductData toDomain() => ProfitLossProductData(
|
|
||||||
productId: productId ?? '',
|
|
||||||
productName: productName ?? '',
|
|
||||||
categoryId: categoryId ?? '',
|
|
||||||
categoryName: categoryName ?? '',
|
|
||||||
quantitySold: quantitySold ?? 0,
|
|
||||||
revenue: revenue ?? 0,
|
|
||||||
cost: cost ?? 0,
|
|
||||||
grossProfit: grossProfit ?? 0,
|
|
||||||
grossProfitMargin: grossProfitMargin ?? 0.0,
|
|
||||||
averagePrice: averagePrice ?? 0,
|
|
||||||
averageCost: averageCost ?? 0,
|
|
||||||
profitPerUnit: profitPerUnit ?? 0,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@ -1,85 +0,0 @@
|
|||||||
part of '../analytic_dtos.dart';
|
|
||||||
|
|
||||||
@freezed
|
|
||||||
class SalesAnalyticDto with _$SalesAnalyticDto {
|
|
||||||
const SalesAnalyticDto._();
|
|
||||||
|
|
||||||
const factory SalesAnalyticDto({
|
|
||||||
@JsonKey(name: 'organization_id') String? organizationId,
|
|
||||||
@JsonKey(name: 'outlet_id') String? outletId,
|
|
||||||
@JsonKey(name: 'date_from') DateTime? dateFrom,
|
|
||||||
@JsonKey(name: 'date_to') DateTime? dateTo,
|
|
||||||
@JsonKey(name: 'group_by') String? groupBy,
|
|
||||||
@JsonKey(name: 'summary') SalesAnalyticSummaryDto? summary,
|
|
||||||
@JsonKey(name: 'data') List<SalesAnalyticDataDto>? data,
|
|
||||||
}) = _SalesAnalyticDto;
|
|
||||||
|
|
||||||
factory SalesAnalyticDto.fromJson(Map<String, dynamic> json) =>
|
|
||||||
_$SalesAnalyticDtoFromJson(json);
|
|
||||||
|
|
||||||
SalesAnalytic toDomain() => SalesAnalytic(
|
|
||||||
organizationId: organizationId ?? '',
|
|
||||||
outletId: outletId ?? '',
|
|
||||||
dateFrom: dateFrom ?? DateTime.fromMillisecondsSinceEpoch(0),
|
|
||||||
dateTo: dateTo ?? DateTime.fromMillisecondsSinceEpoch(0),
|
|
||||||
groupBy: groupBy ?? '',
|
|
||||||
summary: summary?.toDomain() ?? SalesAnalyticSummary.empty(),
|
|
||||||
data: data?.map((e) => e.toDomain()).toList() ?? [],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@freezed
|
|
||||||
class SalesAnalyticSummaryDto with _$SalesAnalyticSummaryDto {
|
|
||||||
const SalesAnalyticSummaryDto._();
|
|
||||||
|
|
||||||
const factory SalesAnalyticSummaryDto({
|
|
||||||
@JsonKey(name: 'total_sales') num? totalSales,
|
|
||||||
@JsonKey(name: 'total_orders') num? totalOrders,
|
|
||||||
@JsonKey(name: 'total_items') num? totalItems,
|
|
||||||
@JsonKey(name: 'average_order_value') num? averageOrderValue,
|
|
||||||
@JsonKey(name: 'total_tax') num? totalTax,
|
|
||||||
@JsonKey(name: 'total_discount') num? totalDiscount,
|
|
||||||
@JsonKey(name: 'net_sales') num? netSales,
|
|
||||||
}) = _SalesAnalyticSummaryDto;
|
|
||||||
|
|
||||||
factory SalesAnalyticSummaryDto.fromJson(Map<String, dynamic> json) =>
|
|
||||||
_$SalesAnalyticSummaryDtoFromJson(json);
|
|
||||||
|
|
||||||
SalesAnalyticSummary toDomain() => SalesAnalyticSummary(
|
|
||||||
totalSales: totalSales?.toInt() ?? 0,
|
|
||||||
totalOrders: totalOrders?.toInt() ?? 0,
|
|
||||||
totalItems: totalItems?.toInt() ?? 0,
|
|
||||||
averageOrderValue: averageOrderValue?.toDouble() ?? 0,
|
|
||||||
totalTax: totalTax?.toInt() ?? 0,
|
|
||||||
totalDiscount: totalDiscount?.toInt() ?? 0,
|
|
||||||
netSales: netSales?.toInt() ?? 0,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@freezed
|
|
||||||
class SalesAnalyticDataDto with _$SalesAnalyticDataDto {
|
|
||||||
const SalesAnalyticDataDto._();
|
|
||||||
|
|
||||||
const factory SalesAnalyticDataDto({
|
|
||||||
@JsonKey(name: 'date') DateTime? date,
|
|
||||||
@JsonKey(name: 'sales') num? sales,
|
|
||||||
@JsonKey(name: 'orders') num? orders,
|
|
||||||
@JsonKey(name: 'items') num? items,
|
|
||||||
@JsonKey(name: 'tax') num? tax,
|
|
||||||
@JsonKey(name: 'discount') num? discount,
|
|
||||||
@JsonKey(name: 'net_sales') num? netSales,
|
|
||||||
}) = _SalesAnalyticDataDto;
|
|
||||||
|
|
||||||
factory SalesAnalyticDataDto.fromJson(Map<String, dynamic> json) =>
|
|
||||||
_$SalesAnalyticDataDtoFromJson(json);
|
|
||||||
|
|
||||||
SalesAnalyticData toDomain() => SalesAnalyticData(
|
|
||||||
date: date ?? DateTime.fromMillisecondsSinceEpoch(0),
|
|
||||||
sales: sales?.toInt() ?? 0,
|
|
||||||
orders: orders?.toInt() ?? 0,
|
|
||||||
items: items?.toInt() ?? 0,
|
|
||||||
tax: tax?.toInt() ?? 0,
|
|
||||||
discount: discount?.toInt() ?? 0,
|
|
||||||
netSales: netSales?.toInt() ?? 0,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@ -1,88 +0,0 @@
|
|||||||
import 'dart:developer';
|
|
||||||
|
|
||||||
import 'package:dartz/dartz.dart';
|
|
||||||
import 'package:injectable/injectable.dart';
|
|
||||||
|
|
||||||
import '../../../domain/analytic/analytic.dart';
|
|
||||||
import '../../../domain/analytic/repositories/i_analytic_repository.dart';
|
|
||||||
import '../datasource/remote_data_provider.dart';
|
|
||||||
|
|
||||||
@Injectable(as: IAnalyticRepository)
|
|
||||||
class AnalyticRepository implements IAnalyticRepository {
|
|
||||||
final AnalyticRemoteDataProvider _dataProvider;
|
|
||||||
final String _logName = 'AnalyticRepository';
|
|
||||||
|
|
||||||
AnalyticRepository(this._dataProvider);
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<Either<AnalyticFailure, SalesAnalytic>> getSales({
|
|
||||||
required DateTime dateFrom,
|
|
||||||
required DateTime dateTo,
|
|
||||||
}) async {
|
|
||||||
try {
|
|
||||||
final result = await _dataProvider.fetchSales(
|
|
||||||
dateFrom: dateFrom,
|
|
||||||
dateTo: dateTo,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (result.hasError) {
|
|
||||||
return left(result.error!);
|
|
||||||
}
|
|
||||||
|
|
||||||
final auth = result.data!.toDomain();
|
|
||||||
|
|
||||||
return right(auth);
|
|
||||||
} catch (e, s) {
|
|
||||||
log('getSalesError', name: _logName, error: e, stackTrace: s);
|
|
||||||
return left(const AnalyticFailure.unexpectedError());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<Either<AnalyticFailure, ProfitLossAnalytic>> getProfitLoss({
|
|
||||||
required DateTime dateFrom,
|
|
||||||
required DateTime dateTo,
|
|
||||||
}) async {
|
|
||||||
try {
|
|
||||||
final result = await _dataProvider.fetchProfitLoss(
|
|
||||||
dateFrom: dateFrom,
|
|
||||||
dateTo: dateTo,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (result.hasError) {
|
|
||||||
return left(result.error!);
|
|
||||||
}
|
|
||||||
|
|
||||||
final auth = result.data!.toDomain();
|
|
||||||
|
|
||||||
return right(auth);
|
|
||||||
} catch (e, s) {
|
|
||||||
log('getProfitLossError', name: _logName, error: e, stackTrace: s);
|
|
||||||
return left(const AnalyticFailure.unexpectedError());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<Either<AnalyticFailure, CategoryAnalytic>> getCategory({
|
|
||||||
required DateTime dateFrom,
|
|
||||||
required DateTime dateTo,
|
|
||||||
}) async {
|
|
||||||
try {
|
|
||||||
final result = await _dataProvider.fetchCategory(
|
|
||||||
dateFrom: dateFrom,
|
|
||||||
dateTo: dateTo,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (result.hasError) {
|
|
||||||
return left(result.error!);
|
|
||||||
}
|
|
||||||
|
|
||||||
final auth = result.data!.toDomain();
|
|
||||||
|
|
||||||
return right(auth);
|
|
||||||
} catch (e, s) {
|
|
||||||
log('getCategoryError', name: _logName, error: e, stackTrace: s);
|
|
||||||
return left(const AnalyticFailure.unexpectedError());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,5 +1,4 @@
|
|||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'dart:developer';
|
|
||||||
|
|
||||||
import 'package:injectable/injectable.dart';
|
import 'package:injectable/injectable.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
@ -11,7 +10,6 @@ import '../auth_dtos.dart';
|
|||||||
@injectable
|
@injectable
|
||||||
class AuthLocalDataProvider {
|
class AuthLocalDataProvider {
|
||||||
final SharedPreferences _sharedPreferences;
|
final SharedPreferences _sharedPreferences;
|
||||||
final String _logName = 'AuthLocalDataProvider';
|
|
||||||
|
|
||||||
AuthLocalDataProvider(this._sharedPreferences);
|
AuthLocalDataProvider(this._sharedPreferences);
|
||||||
|
|
||||||
@ -50,11 +48,7 @@ class AuthLocalDataProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<void> deleteAllAuth() async {
|
Future<void> deleteAllAuth() async {
|
||||||
try {
|
await _sharedPreferences.remove(LocalStorageKey.token);
|
||||||
await _sharedPreferences.remove(LocalStorageKey.token);
|
await _sharedPreferences.remove(LocalStorageKey.user);
|
||||||
await _sharedPreferences.remove(LocalStorageKey.user);
|
|
||||||
} catch (e) {
|
|
||||||
log('deleteAllAuthError', name: _logName, error: e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,7 +6,6 @@ import 'package:data_channel/data_channel.dart';
|
|||||||
|
|
||||||
import '../../../common/api/api_client.dart';
|
import '../../../common/api/api_client.dart';
|
||||||
import '../../../common/api/api_failure.dart';
|
import '../../../common/api/api_failure.dart';
|
||||||
import '../../../common/function/app_function.dart';
|
|
||||||
import '../../../common/url/api_path.dart';
|
import '../../../common/url/api_path.dart';
|
||||||
import '../../../domain/auth/auth.dart';
|
import '../../../domain/auth/auth.dart';
|
||||||
import '../auth_dtos.dart';
|
import '../auth_dtos.dart';
|
||||||
@ -46,7 +45,7 @@ class AuthRemoteDataProvider {
|
|||||||
|
|
||||||
Future<DC<AuthFailure, Unit>> logout() async {
|
Future<DC<AuthFailure, Unit>> logout() async {
|
||||||
try {
|
try {
|
||||||
await _apiClient.post(ApiPath.logout, headers: getAuthorizationHeader());
|
await _apiClient.post(ApiPath.logout);
|
||||||
return DC.data(unit);
|
return DC.data(unit);
|
||||||
} on ApiFailure catch (e, s) {
|
} on ApiFailure catch (e, s) {
|
||||||
log('login', name: _logName, error: e, stackTrace: s);
|
log('login', name: _logName, error: e, stackTrace: s);
|
||||||
|
|||||||
@ -1,8 +0,0 @@
|
|||||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
|
||||||
|
|
||||||
import '../../domain/category/category.dart';
|
|
||||||
|
|
||||||
part 'category_dtos.freezed.dart';
|
|
||||||
part 'category_dtos.g.dart';
|
|
||||||
|
|
||||||
part 'dto/category_dto.dart';
|
|
||||||
@ -1,368 +0,0 @@
|
|||||||
// 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 'category_dtos.dart';
|
|
||||||
|
|
||||||
// **************************************************************************
|
|
||||||
// FreezedGenerator
|
|
||||||
// **************************************************************************
|
|
||||||
|
|
||||||
T _$identity<T>(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',
|
|
||||||
);
|
|
||||||
|
|
||||||
CategoryDto _$CategoryDtoFromJson(Map<String, dynamic> json) {
|
|
||||||
return _CategoryDto.fromJson(json);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
mixin _$CategoryDto {
|
|
||||||
@JsonKey(name: 'id')
|
|
||||||
String? get id => throw _privateConstructorUsedError;
|
|
||||||
@JsonKey(name: 'organization_id')
|
|
||||||
String? get organizationId => throw _privateConstructorUsedError;
|
|
||||||
@JsonKey(name: 'name')
|
|
||||||
String? get name => throw _privateConstructorUsedError;
|
|
||||||
@JsonKey(name: 'description')
|
|
||||||
String? get description => throw _privateConstructorUsedError;
|
|
||||||
@JsonKey(name: 'business_type')
|
|
||||||
String? get businessType => throw _privateConstructorUsedError;
|
|
||||||
@JsonKey(name: 'metadata')
|
|
||||||
Map<String, dynamic>? get metadata => throw _privateConstructorUsedError;
|
|
||||||
@JsonKey(name: 'created_at')
|
|
||||||
DateTime? get createdAt => throw _privateConstructorUsedError;
|
|
||||||
@JsonKey(name: 'updated_at')
|
|
||||||
DateTime? get updatedAt => throw _privateConstructorUsedError;
|
|
||||||
|
|
||||||
/// Serializes this CategoryDto to a JSON map.
|
|
||||||
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
|
||||||
|
|
||||||
/// Create a copy of CategoryDto
|
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
|
||||||
$CategoryDtoCopyWith<CategoryDto> get copyWith =>
|
|
||||||
throw _privateConstructorUsedError;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
abstract class $CategoryDtoCopyWith<$Res> {
|
|
||||||
factory $CategoryDtoCopyWith(
|
|
||||||
CategoryDto value,
|
|
||||||
$Res Function(CategoryDto) then,
|
|
||||||
) = _$CategoryDtoCopyWithImpl<$Res, CategoryDto>;
|
|
||||||
@useResult
|
|
||||||
$Res call({
|
|
||||||
@JsonKey(name: 'id') String? id,
|
|
||||||
@JsonKey(name: 'organization_id') String? organizationId,
|
|
||||||
@JsonKey(name: 'name') String? name,
|
|
||||||
@JsonKey(name: 'description') String? description,
|
|
||||||
@JsonKey(name: 'business_type') String? businessType,
|
|
||||||
@JsonKey(name: 'metadata') Map<String, dynamic>? metadata,
|
|
||||||
@JsonKey(name: 'created_at') DateTime? createdAt,
|
|
||||||
@JsonKey(name: 'updated_at') DateTime? updatedAt,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
class _$CategoryDtoCopyWithImpl<$Res, $Val extends CategoryDto>
|
|
||||||
implements $CategoryDtoCopyWith<$Res> {
|
|
||||||
_$CategoryDtoCopyWithImpl(this._value, this._then);
|
|
||||||
|
|
||||||
// ignore: unused_field
|
|
||||||
final $Val _value;
|
|
||||||
// ignore: unused_field
|
|
||||||
final $Res Function($Val) _then;
|
|
||||||
|
|
||||||
/// Create a copy of CategoryDto
|
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
|
||||||
@pragma('vm:prefer-inline')
|
|
||||||
@override
|
|
||||||
$Res call({
|
|
||||||
Object? id = freezed,
|
|
||||||
Object? organizationId = freezed,
|
|
||||||
Object? name = freezed,
|
|
||||||
Object? description = freezed,
|
|
||||||
Object? businessType = freezed,
|
|
||||||
Object? metadata = freezed,
|
|
||||||
Object? createdAt = freezed,
|
|
||||||
Object? updatedAt = freezed,
|
|
||||||
}) {
|
|
||||||
return _then(
|
|
||||||
_value.copyWith(
|
|
||||||
id: freezed == id
|
|
||||||
? _value.id
|
|
||||||
: id // ignore: cast_nullable_to_non_nullable
|
|
||||||
as String?,
|
|
||||||
organizationId: freezed == organizationId
|
|
||||||
? _value.organizationId
|
|
||||||
: organizationId // ignore: cast_nullable_to_non_nullable
|
|
||||||
as String?,
|
|
||||||
name: freezed == name
|
|
||||||
? _value.name
|
|
||||||
: name // ignore: cast_nullable_to_non_nullable
|
|
||||||
as String?,
|
|
||||||
description: freezed == description
|
|
||||||
? _value.description
|
|
||||||
: description // ignore: cast_nullable_to_non_nullable
|
|
||||||
as String?,
|
|
||||||
businessType: freezed == businessType
|
|
||||||
? _value.businessType
|
|
||||||
: businessType // ignore: cast_nullable_to_non_nullable
|
|
||||||
as String?,
|
|
||||||
metadata: freezed == metadata
|
|
||||||
? _value.metadata
|
|
||||||
: metadata // ignore: cast_nullable_to_non_nullable
|
|
||||||
as Map<String, dynamic>?,
|
|
||||||
createdAt: freezed == createdAt
|
|
||||||
? _value.createdAt
|
|
||||||
: createdAt // ignore: cast_nullable_to_non_nullable
|
|
||||||
as DateTime?,
|
|
||||||
updatedAt: freezed == updatedAt
|
|
||||||
? _value.updatedAt
|
|
||||||
: updatedAt // ignore: cast_nullable_to_non_nullable
|
|
||||||
as DateTime?,
|
|
||||||
)
|
|
||||||
as $Val,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
abstract class _$$CategoryDtoImplCopyWith<$Res>
|
|
||||||
implements $CategoryDtoCopyWith<$Res> {
|
|
||||||
factory _$$CategoryDtoImplCopyWith(
|
|
||||||
_$CategoryDtoImpl value,
|
|
||||||
$Res Function(_$CategoryDtoImpl) then,
|
|
||||||
) = __$$CategoryDtoImplCopyWithImpl<$Res>;
|
|
||||||
@override
|
|
||||||
@useResult
|
|
||||||
$Res call({
|
|
||||||
@JsonKey(name: 'id') String? id,
|
|
||||||
@JsonKey(name: 'organization_id') String? organizationId,
|
|
||||||
@JsonKey(name: 'name') String? name,
|
|
||||||
@JsonKey(name: 'description') String? description,
|
|
||||||
@JsonKey(name: 'business_type') String? businessType,
|
|
||||||
@JsonKey(name: 'metadata') Map<String, dynamic>? metadata,
|
|
||||||
@JsonKey(name: 'created_at') DateTime? createdAt,
|
|
||||||
@JsonKey(name: 'updated_at') DateTime? updatedAt,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
class __$$CategoryDtoImplCopyWithImpl<$Res>
|
|
||||||
extends _$CategoryDtoCopyWithImpl<$Res, _$CategoryDtoImpl>
|
|
||||||
implements _$$CategoryDtoImplCopyWith<$Res> {
|
|
||||||
__$$CategoryDtoImplCopyWithImpl(
|
|
||||||
_$CategoryDtoImpl _value,
|
|
||||||
$Res Function(_$CategoryDtoImpl) _then,
|
|
||||||
) : super(_value, _then);
|
|
||||||
|
|
||||||
/// Create a copy of CategoryDto
|
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
|
||||||
@pragma('vm:prefer-inline')
|
|
||||||
@override
|
|
||||||
$Res call({
|
|
||||||
Object? id = freezed,
|
|
||||||
Object? organizationId = freezed,
|
|
||||||
Object? name = freezed,
|
|
||||||
Object? description = freezed,
|
|
||||||
Object? businessType = freezed,
|
|
||||||
Object? metadata = freezed,
|
|
||||||
Object? createdAt = freezed,
|
|
||||||
Object? updatedAt = freezed,
|
|
||||||
}) {
|
|
||||||
return _then(
|
|
||||||
_$CategoryDtoImpl(
|
|
||||||
id: freezed == id
|
|
||||||
? _value.id
|
|
||||||
: id // ignore: cast_nullable_to_non_nullable
|
|
||||||
as String?,
|
|
||||||
organizationId: freezed == organizationId
|
|
||||||
? _value.organizationId
|
|
||||||
: organizationId // ignore: cast_nullable_to_non_nullable
|
|
||||||
as String?,
|
|
||||||
name: freezed == name
|
|
||||||
? _value.name
|
|
||||||
: name // ignore: cast_nullable_to_non_nullable
|
|
||||||
as String?,
|
|
||||||
description: freezed == description
|
|
||||||
? _value.description
|
|
||||||
: description // ignore: cast_nullable_to_non_nullable
|
|
||||||
as String?,
|
|
||||||
businessType: freezed == businessType
|
|
||||||
? _value.businessType
|
|
||||||
: businessType // ignore: cast_nullable_to_non_nullable
|
|
||||||
as String?,
|
|
||||||
metadata: freezed == metadata
|
|
||||||
? _value._metadata
|
|
||||||
: metadata // ignore: cast_nullable_to_non_nullable
|
|
||||||
as Map<String, dynamic>?,
|
|
||||||
createdAt: freezed == createdAt
|
|
||||||
? _value.createdAt
|
|
||||||
: createdAt // ignore: cast_nullable_to_non_nullable
|
|
||||||
as DateTime?,
|
|
||||||
updatedAt: freezed == updatedAt
|
|
||||||
? _value.updatedAt
|
|
||||||
: updatedAt // ignore: cast_nullable_to_non_nullable
|
|
||||||
as DateTime?,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
@JsonSerializable()
|
|
||||||
class _$CategoryDtoImpl extends _CategoryDto {
|
|
||||||
const _$CategoryDtoImpl({
|
|
||||||
@JsonKey(name: 'id') this.id,
|
|
||||||
@JsonKey(name: 'organization_id') this.organizationId,
|
|
||||||
@JsonKey(name: 'name') this.name,
|
|
||||||
@JsonKey(name: 'description') this.description,
|
|
||||||
@JsonKey(name: 'business_type') this.businessType,
|
|
||||||
@JsonKey(name: 'metadata') final Map<String, dynamic>? metadata,
|
|
||||||
@JsonKey(name: 'created_at') this.createdAt,
|
|
||||||
@JsonKey(name: 'updated_at') this.updatedAt,
|
|
||||||
}) : _metadata = metadata,
|
|
||||||
super._();
|
|
||||||
|
|
||||||
factory _$CategoryDtoImpl.fromJson(Map<String, dynamic> json) =>
|
|
||||||
_$$CategoryDtoImplFromJson(json);
|
|
||||||
|
|
||||||
@override
|
|
||||||
@JsonKey(name: 'id')
|
|
||||||
final String? id;
|
|
||||||
@override
|
|
||||||
@JsonKey(name: 'organization_id')
|
|
||||||
final String? organizationId;
|
|
||||||
@override
|
|
||||||
@JsonKey(name: 'name')
|
|
||||||
final String? name;
|
|
||||||
@override
|
|
||||||
@JsonKey(name: 'description')
|
|
||||||
final String? description;
|
|
||||||
@override
|
|
||||||
@JsonKey(name: 'business_type')
|
|
||||||
final String? businessType;
|
|
||||||
final Map<String, dynamic>? _metadata;
|
|
||||||
@override
|
|
||||||
@JsonKey(name: 'metadata')
|
|
||||||
Map<String, dynamic>? get metadata {
|
|
||||||
final value = _metadata;
|
|
||||||
if (value == null) return null;
|
|
||||||
if (_metadata is EqualUnmodifiableMapView) return _metadata;
|
|
||||||
// ignore: implicit_dynamic_type
|
|
||||||
return EqualUnmodifiableMapView(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
@JsonKey(name: 'created_at')
|
|
||||||
final DateTime? createdAt;
|
|
||||||
@override
|
|
||||||
@JsonKey(name: 'updated_at')
|
|
||||||
final DateTime? updatedAt;
|
|
||||||
|
|
||||||
@override
|
|
||||||
String toString() {
|
|
||||||
return 'CategoryDto(id: $id, organizationId: $organizationId, name: $name, description: $description, businessType: $businessType, metadata: $metadata, createdAt: $createdAt, updatedAt: $updatedAt)';
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
bool operator ==(Object other) {
|
|
||||||
return identical(this, other) ||
|
|
||||||
(other.runtimeType == runtimeType &&
|
|
||||||
other is _$CategoryDtoImpl &&
|
|
||||||
(identical(other.id, id) || other.id == id) &&
|
|
||||||
(identical(other.organizationId, organizationId) ||
|
|
||||||
other.organizationId == organizationId) &&
|
|
||||||
(identical(other.name, name) || other.name == name) &&
|
|
||||||
(identical(other.description, description) ||
|
|
||||||
other.description == description) &&
|
|
||||||
(identical(other.businessType, businessType) ||
|
|
||||||
other.businessType == businessType) &&
|
|
||||||
const DeepCollectionEquality().equals(other._metadata, _metadata) &&
|
|
||||||
(identical(other.createdAt, createdAt) ||
|
|
||||||
other.createdAt == createdAt) &&
|
|
||||||
(identical(other.updatedAt, updatedAt) ||
|
|
||||||
other.updatedAt == updatedAt));
|
|
||||||
}
|
|
||||||
|
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
|
||||||
@override
|
|
||||||
int get hashCode => Object.hash(
|
|
||||||
runtimeType,
|
|
||||||
id,
|
|
||||||
organizationId,
|
|
||||||
name,
|
|
||||||
description,
|
|
||||||
businessType,
|
|
||||||
const DeepCollectionEquality().hash(_metadata),
|
|
||||||
createdAt,
|
|
||||||
updatedAt,
|
|
||||||
);
|
|
||||||
|
|
||||||
/// Create a copy of CategoryDto
|
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
|
||||||
@override
|
|
||||||
@pragma('vm:prefer-inline')
|
|
||||||
_$$CategoryDtoImplCopyWith<_$CategoryDtoImpl> get copyWith =>
|
|
||||||
__$$CategoryDtoImplCopyWithImpl<_$CategoryDtoImpl>(this, _$identity);
|
|
||||||
|
|
||||||
@override
|
|
||||||
Map<String, dynamic> toJson() {
|
|
||||||
return _$$CategoryDtoImplToJson(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract class _CategoryDto extends CategoryDto {
|
|
||||||
const factory _CategoryDto({
|
|
||||||
@JsonKey(name: 'id') final String? id,
|
|
||||||
@JsonKey(name: 'organization_id') final String? organizationId,
|
|
||||||
@JsonKey(name: 'name') final String? name,
|
|
||||||
@JsonKey(name: 'description') final String? description,
|
|
||||||
@JsonKey(name: 'business_type') final String? businessType,
|
|
||||||
@JsonKey(name: 'metadata') final Map<String, dynamic>? metadata,
|
|
||||||
@JsonKey(name: 'created_at') final DateTime? createdAt,
|
|
||||||
@JsonKey(name: 'updated_at') final DateTime? updatedAt,
|
|
||||||
}) = _$CategoryDtoImpl;
|
|
||||||
const _CategoryDto._() : super._();
|
|
||||||
|
|
||||||
factory _CategoryDto.fromJson(Map<String, dynamic> json) =
|
|
||||||
_$CategoryDtoImpl.fromJson;
|
|
||||||
|
|
||||||
@override
|
|
||||||
@JsonKey(name: 'id')
|
|
||||||
String? get id;
|
|
||||||
@override
|
|
||||||
@JsonKey(name: 'organization_id')
|
|
||||||
String? get organizationId;
|
|
||||||
@override
|
|
||||||
@JsonKey(name: 'name')
|
|
||||||
String? get name;
|
|
||||||
@override
|
|
||||||
@JsonKey(name: 'description')
|
|
||||||
String? get description;
|
|
||||||
@override
|
|
||||||
@JsonKey(name: 'business_type')
|
|
||||||
String? get businessType;
|
|
||||||
@override
|
|
||||||
@JsonKey(name: 'metadata')
|
|
||||||
Map<String, dynamic>? get metadata;
|
|
||||||
@override
|
|
||||||
@JsonKey(name: 'created_at')
|
|
||||||
DateTime? get createdAt;
|
|
||||||
@override
|
|
||||||
@JsonKey(name: 'updated_at')
|
|
||||||
DateTime? get updatedAt;
|
|
||||||
|
|
||||||
/// Create a copy of CategoryDto
|
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
|
||||||
@override
|
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
|
||||||
_$$CategoryDtoImplCopyWith<_$CategoryDtoImpl> get copyWith =>
|
|
||||||
throw _privateConstructorUsedError;
|
|
||||||
}
|
|
||||||
@ -1,35 +0,0 @@
|
|||||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
|
||||||
|
|
||||||
part of 'category_dtos.dart';
|
|
||||||
|
|
||||||
// **************************************************************************
|
|
||||||
// JsonSerializableGenerator
|
|
||||||
// **************************************************************************
|
|
||||||
|
|
||||||
_$CategoryDtoImpl _$$CategoryDtoImplFromJson(Map<String, dynamic> json) =>
|
|
||||||
_$CategoryDtoImpl(
|
|
||||||
id: json['id'] as String?,
|
|
||||||
organizationId: json['organization_id'] as String?,
|
|
||||||
name: json['name'] as String?,
|
|
||||||
description: json['description'] as String?,
|
|
||||||
businessType: json['business_type'] as String?,
|
|
||||||
metadata: json['metadata'] as Map<String, dynamic>?,
|
|
||||||
createdAt: json['created_at'] == null
|
|
||||||
? null
|
|
||||||
: DateTime.parse(json['created_at'] as String),
|
|
||||||
updatedAt: json['updated_at'] == null
|
|
||||||
? null
|
|
||||||
: DateTime.parse(json['updated_at'] as String),
|
|
||||||
);
|
|
||||||
|
|
||||||
Map<String, dynamic> _$$CategoryDtoImplToJson(_$CategoryDtoImpl instance) =>
|
|
||||||
<String, dynamic>{
|
|
||||||
'id': instance.id,
|
|
||||||
'organization_id': instance.organizationId,
|
|
||||||
'name': instance.name,
|
|
||||||
'description': instance.description,
|
|
||||||
'business_type': instance.businessType,
|
|
||||||
'metadata': instance.metadata,
|
|
||||||
'created_at': instance.createdAt?.toIso8601String(),
|
|
||||||
'updated_at': instance.updatedAt?.toIso8601String(),
|
|
||||||
};
|
|
||||||
@ -1,46 +0,0 @@
|
|||||||
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/category/category.dart';
|
|
||||||
import '../category_dtos.dart';
|
|
||||||
|
|
||||||
@injectable
|
|
||||||
class CategoryRemoteDataProvider {
|
|
||||||
final ApiClient _apiClient;
|
|
||||||
final String _logName = 'CategoryRemoteDataProvider';
|
|
||||||
|
|
||||||
CategoryRemoteDataProvider(this._apiClient);
|
|
||||||
|
|
||||||
Future<DC<CategoryFailure, List<CategoryDto>>> fetch({
|
|
||||||
int page = 1,
|
|
||||||
int limit = 20,
|
|
||||||
bool isActive = true,
|
|
||||||
}) async {
|
|
||||||
try {
|
|
||||||
final response = await _apiClient.get(
|
|
||||||
ApiPath.category,
|
|
||||||
params: {'page': page, 'limit': limit, 'is_active': isActive},
|
|
||||||
headers: getAuthorizationHeader(),
|
|
||||||
);
|
|
||||||
|
|
||||||
if (response.data['data'] == null) {
|
|
||||||
return DC.error(CategoryFailure.empty());
|
|
||||||
}
|
|
||||||
|
|
||||||
final dto = (response.data['data']['categories'] as List)
|
|
||||||
.map((item) => CategoryDto.fromJson(item))
|
|
||||||
.toList();
|
|
||||||
|
|
||||||
return DC.data(dto);
|
|
||||||
} on ApiFailure catch (e, s) {
|
|
||||||
log('fetchCategoryError', name: _logName, error: e, stackTrace: s);
|
|
||||||
return DC.error(CategoryFailure.serverError(e));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,31 +0,0 @@
|
|||||||
part of '../category_dtos.dart';
|
|
||||||
|
|
||||||
@freezed
|
|
||||||
class CategoryDto with _$CategoryDto {
|
|
||||||
const CategoryDto._();
|
|
||||||
|
|
||||||
const factory CategoryDto({
|
|
||||||
@JsonKey(name: 'id') String? id,
|
|
||||||
@JsonKey(name: 'organization_id') String? organizationId,
|
|
||||||
@JsonKey(name: 'name') String? name,
|
|
||||||
@JsonKey(name: 'description') String? description,
|
|
||||||
@JsonKey(name: 'business_type') String? businessType,
|
|
||||||
@JsonKey(name: 'metadata') Map<String, dynamic>? metadata,
|
|
||||||
@JsonKey(name: 'created_at') DateTime? createdAt,
|
|
||||||
@JsonKey(name: 'updated_at') DateTime? updatedAt,
|
|
||||||
}) = _CategoryDto;
|
|
||||||
|
|
||||||
factory CategoryDto.fromJson(Map<String, dynamic> json) =>
|
|
||||||
_$CategoryDtoFromJson(json);
|
|
||||||
|
|
||||||
Category toDomain() => Category(
|
|
||||||
id: id ?? '',
|
|
||||||
organizationId: organizationId ?? '',
|
|
||||||
name: name ?? '',
|
|
||||||
description: description ?? '',
|
|
||||||
businessType: businessType ?? '',
|
|
||||||
metadata: metadata ?? {},
|
|
||||||
createdAt: createdAt,
|
|
||||||
updatedAt: updatedAt,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@ -1,41 +0,0 @@
|
|||||||
import 'dart:developer';
|
|
||||||
|
|
||||||
import 'package:dartz/dartz.dart';
|
|
||||||
import 'package:injectable/injectable.dart';
|
|
||||||
|
|
||||||
import '../../../domain/category/category.dart';
|
|
||||||
import '../datasource/remote_data_provider.dart';
|
|
||||||
|
|
||||||
@Injectable(as: ICategoryRepository)
|
|
||||||
class CategoryRepository implements ICategoryRepository {
|
|
||||||
final CategoryRemoteDataProvider _dataProvider;
|
|
||||||
final String _logName = 'CategoryRepository';
|
|
||||||
|
|
||||||
CategoryRepository(this._dataProvider);
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<Either<CategoryFailure, List<Category>>> get({
|
|
||||||
int page = 1,
|
|
||||||
int limit = 20,
|
|
||||||
bool isActive = true,
|
|
||||||
}) async {
|
|
||||||
try {
|
|
||||||
final result = await _dataProvider.fetch(
|
|
||||||
page: page,
|
|
||||||
limit: limit,
|
|
||||||
isActive: isActive,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (result.hasError) {
|
|
||||||
return left(result.error!);
|
|
||||||
}
|
|
||||||
|
|
||||||
final auth = result.data!.map((e) => e.toDomain()).toList();
|
|
||||||
|
|
||||||
return right(auth);
|
|
||||||
} catch (e, s) {
|
|
||||||
log('getCategoryError', name: _logName, error: e, stackTrace: s);
|
|
||||||
return left(const CategoryFailure.unexpectedError());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,57 +0,0 @@
|
|||||||
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/product/product.dart';
|
|
||||||
import '../product_dtos.dart';
|
|
||||||
|
|
||||||
@injectable
|
|
||||||
class ProductRemoteDataProvider {
|
|
||||||
final ApiClient _apiClient;
|
|
||||||
final String _logName = 'ProductRemoteDataProvider';
|
|
||||||
|
|
||||||
ProductRemoteDataProvider(this._apiClient);
|
|
||||||
|
|
||||||
Future<DC<ProductFailure, List<ProductDto>>> fetch({
|
|
||||||
int page = 1,
|
|
||||||
int limit = 10,
|
|
||||||
String? categoryId,
|
|
||||||
String? search,
|
|
||||||
}) async {
|
|
||||||
try {
|
|
||||||
Map<String, dynamic> params = {'page': page, 'limit': limit};
|
|
||||||
|
|
||||||
if (categoryId != null) {
|
|
||||||
params['category_id'] = categoryId;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (search != null) {
|
|
||||||
params['search'] = search;
|
|
||||||
}
|
|
||||||
|
|
||||||
final response = await _apiClient.get(
|
|
||||||
ApiPath.product,
|
|
||||||
params: params,
|
|
||||||
headers: getAuthorizationHeader(),
|
|
||||||
);
|
|
||||||
|
|
||||||
if (response.data['data'] == null) {
|
|
||||||
return DC.error(ProductFailure.empty());
|
|
||||||
}
|
|
||||||
|
|
||||||
final dto = (response.data['data']['products'] as List)
|
|
||||||
.map((item) => ProductDto.fromJson(item))
|
|
||||||
.toList();
|
|
||||||
|
|
||||||
return DC.data(dto);
|
|
||||||
} on ApiFailure catch (e, s) {
|
|
||||||
log('fetchProductError', name: _logName, error: e, stackTrace: s);
|
|
||||||
return DC.error(ProductFailure.serverError(e));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,70 +0,0 @@
|
|||||||
part of '../product_dtos.dart';
|
|
||||||
|
|
||||||
@freezed
|
|
||||||
class ProductDto with _$ProductDto {
|
|
||||||
const ProductDto._();
|
|
||||||
|
|
||||||
const factory ProductDto({
|
|
||||||
@JsonKey(name: 'id') String? id,
|
|
||||||
@JsonKey(name: 'organization_id') String? organizationId,
|
|
||||||
@JsonKey(name: 'category_id') String? categoryId,
|
|
||||||
@JsonKey(name: 'sku') String? sku,
|
|
||||||
@JsonKey(name: 'name') String? name,
|
|
||||||
@JsonKey(name: 'description') String? description,
|
|
||||||
@JsonKey(name: 'price') int? price,
|
|
||||||
@JsonKey(name: 'cost') int? cost,
|
|
||||||
@JsonKey(name: 'business_type') String? businessType,
|
|
||||||
@JsonKey(name: 'image_url') String? imageUrl,
|
|
||||||
@JsonKey(name: 'printer_type') String? printerType,
|
|
||||||
@JsonKey(name: 'metadata') Map<String, dynamic>? metadata,
|
|
||||||
@JsonKey(name: 'is_active') bool? isActive,
|
|
||||||
@JsonKey(name: 'created_at') DateTime? createdAt,
|
|
||||||
@JsonKey(name: 'updated_at') DateTime? updatedAt,
|
|
||||||
@JsonKey(name: 'variants') List<ProductVariantDto>? variants,
|
|
||||||
}) = _ProductDto;
|
|
||||||
|
|
||||||
factory ProductDto.fromJson(Map<String, dynamic> json) =>
|
|
||||||
_$ProductDtoFromJson(json);
|
|
||||||
|
|
||||||
/// DTO -> Domain (isi default kalau null)
|
|
||||||
Product toDomain() => Product(
|
|
||||||
id: id ?? '',
|
|
||||||
organizationId: organizationId ?? '',
|
|
||||||
categoryId: categoryId ?? '',
|
|
||||||
sku: sku ?? '',
|
|
||||||
name: name ?? '',
|
|
||||||
description: description ?? '',
|
|
||||||
price: price ?? 0,
|
|
||||||
cost: cost ?? 0,
|
|
||||||
businessType: businessType ?? '',
|
|
||||||
imageUrl: imageUrl ?? '',
|
|
||||||
printerType: printerType ?? '',
|
|
||||||
metadata: metadata ?? {},
|
|
||||||
isActive: isActive ?? false,
|
|
||||||
createdAt: createdAt ?? DateTime.now(),
|
|
||||||
updatedAt: updatedAt ?? DateTime.now(),
|
|
||||||
variants: variants?.map((v) => v.toDomain()).toList() ?? [],
|
|
||||||
);
|
|
||||||
|
|
||||||
/// Domain -> DTO
|
|
||||||
factory ProductDto.fromDomain(Product product) => ProductDto(
|
|
||||||
id: product.id,
|
|
||||||
organizationId: product.organizationId,
|
|
||||||
categoryId: product.categoryId,
|
|
||||||
sku: product.sku,
|
|
||||||
name: product.name,
|
|
||||||
description: product.description,
|
|
||||||
price: product.price,
|
|
||||||
cost: product.cost,
|
|
||||||
businessType: product.businessType,
|
|
||||||
imageUrl: product.imageUrl,
|
|
||||||
printerType: product.printerType,
|
|
||||||
metadata: product.metadata,
|
|
||||||
isActive: product.isActive,
|
|
||||||
createdAt: product.createdAt,
|
|
||||||
updatedAt: product.updatedAt,
|
|
||||||
variants: product.variants
|
|
||||||
.map((v) => ProductVariantDto.fromDomain(v))
|
|
||||||
.toList(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@ -1,45 +0,0 @@
|
|||||||
part of '../product_dtos.dart';
|
|
||||||
|
|
||||||
@freezed
|
|
||||||
class ProductVariantDto with _$ProductVariantDto {
|
|
||||||
const ProductVariantDto._();
|
|
||||||
|
|
||||||
const factory ProductVariantDto({
|
|
||||||
@JsonKey(name: 'id') String? id,
|
|
||||||
@JsonKey(name: 'product_id') String? productId,
|
|
||||||
@JsonKey(name: 'name') String? name,
|
|
||||||
@JsonKey(name: 'price_modifier') int? priceModifier,
|
|
||||||
@JsonKey(name: 'cost') int? cost,
|
|
||||||
@JsonKey(name: 'metadata') Map<String, dynamic>? metadata,
|
|
||||||
@JsonKey(name: 'created_at') DateTime? createdAt,
|
|
||||||
@JsonKey(name: 'updated_at') DateTime? updatedAt,
|
|
||||||
}) = _ProductVariantDto;
|
|
||||||
|
|
||||||
factory ProductVariantDto.fromJson(Map<String, dynamic> json) =>
|
|
||||||
_$ProductVariantDtoFromJson(json);
|
|
||||||
|
|
||||||
/// DTO -> Domain
|
|
||||||
ProductVariant toDomain() => ProductVariant(
|
|
||||||
id: id ?? '',
|
|
||||||
productId: productId ?? '',
|
|
||||||
name: name ?? '',
|
|
||||||
priceModifier: priceModifier ?? 0,
|
|
||||||
cost: cost ?? 0,
|
|
||||||
metadata: metadata ?? {},
|
|
||||||
createdAt: createdAt ?? DateTime.now(),
|
|
||||||
updatedAt: updatedAt ?? DateTime.now(),
|
|
||||||
);
|
|
||||||
|
|
||||||
/// Domain -> DTO
|
|
||||||
factory ProductVariantDto.fromDomain(ProductVariant variant) =>
|
|
||||||
ProductVariantDto(
|
|
||||||
id: variant.id,
|
|
||||||
productId: variant.productId,
|
|
||||||
name: variant.name,
|
|
||||||
priceModifier: variant.priceModifier,
|
|
||||||
cost: variant.cost,
|
|
||||||
metadata: variant.metadata,
|
|
||||||
createdAt: variant.createdAt,
|
|
||||||
updatedAt: variant.updatedAt,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@ -1,9 +0,0 @@
|
|||||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
|
||||||
|
|
||||||
import '../../domain/product/product.dart';
|
|
||||||
|
|
||||||
part 'product_dtos.freezed.dart';
|
|
||||||
part 'product_dtos.g.dart';
|
|
||||||
|
|
||||||
part 'dto/product_dto.dart';
|
|
||||||
part 'dto/product_variant_dto.dart';
|
|
||||||
@ -1,926 +0,0 @@
|
|||||||
// 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 'product_dtos.dart';
|
|
||||||
|
|
||||||
// **************************************************************************
|
|
||||||
// FreezedGenerator
|
|
||||||
// **************************************************************************
|
|
||||||
|
|
||||||
T _$identity<T>(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',
|
|
||||||
);
|
|
||||||
|
|
||||||
ProductDto _$ProductDtoFromJson(Map<String, dynamic> json) {
|
|
||||||
return _ProductDto.fromJson(json);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
mixin _$ProductDto {
|
|
||||||
@JsonKey(name: 'id')
|
|
||||||
String? get id => throw _privateConstructorUsedError;
|
|
||||||
@JsonKey(name: 'organization_id')
|
|
||||||
String? get organizationId => throw _privateConstructorUsedError;
|
|
||||||
@JsonKey(name: 'category_id')
|
|
||||||
String? get categoryId => throw _privateConstructorUsedError;
|
|
||||||
@JsonKey(name: 'sku')
|
|
||||||
String? get sku => throw _privateConstructorUsedError;
|
|
||||||
@JsonKey(name: 'name')
|
|
||||||
String? get name => throw _privateConstructorUsedError;
|
|
||||||
@JsonKey(name: 'description')
|
|
||||||
String? get description => throw _privateConstructorUsedError;
|
|
||||||
@JsonKey(name: 'price')
|
|
||||||
int? get price => throw _privateConstructorUsedError;
|
|
||||||
@JsonKey(name: 'cost')
|
|
||||||
int? get cost => throw _privateConstructorUsedError;
|
|
||||||
@JsonKey(name: 'business_type')
|
|
||||||
String? get businessType => throw _privateConstructorUsedError;
|
|
||||||
@JsonKey(name: 'image_url')
|
|
||||||
String? get imageUrl => throw _privateConstructorUsedError;
|
|
||||||
@JsonKey(name: 'printer_type')
|
|
||||||
String? get printerType => throw _privateConstructorUsedError;
|
|
||||||
@JsonKey(name: 'metadata')
|
|
||||||
Map<String, dynamic>? get metadata => throw _privateConstructorUsedError;
|
|
||||||
@JsonKey(name: 'is_active')
|
|
||||||
bool? get isActive => throw _privateConstructorUsedError;
|
|
||||||
@JsonKey(name: 'created_at')
|
|
||||||
DateTime? get createdAt => throw _privateConstructorUsedError;
|
|
||||||
@JsonKey(name: 'updated_at')
|
|
||||||
DateTime? get updatedAt => throw _privateConstructorUsedError;
|
|
||||||
@JsonKey(name: 'variants')
|
|
||||||
List<ProductVariantDto>? get variants => throw _privateConstructorUsedError;
|
|
||||||
|
|
||||||
/// Serializes this ProductDto to a JSON map.
|
|
||||||
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
|
||||||
|
|
||||||
/// Create a copy of ProductDto
|
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
|
||||||
$ProductDtoCopyWith<ProductDto> get copyWith =>
|
|
||||||
throw _privateConstructorUsedError;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
abstract class $ProductDtoCopyWith<$Res> {
|
|
||||||
factory $ProductDtoCopyWith(
|
|
||||||
ProductDto value,
|
|
||||||
$Res Function(ProductDto) then,
|
|
||||||
) = _$ProductDtoCopyWithImpl<$Res, ProductDto>;
|
|
||||||
@useResult
|
|
||||||
$Res call({
|
|
||||||
@JsonKey(name: 'id') String? id,
|
|
||||||
@JsonKey(name: 'organization_id') String? organizationId,
|
|
||||||
@JsonKey(name: 'category_id') String? categoryId,
|
|
||||||
@JsonKey(name: 'sku') String? sku,
|
|
||||||
@JsonKey(name: 'name') String? name,
|
|
||||||
@JsonKey(name: 'description') String? description,
|
|
||||||
@JsonKey(name: 'price') int? price,
|
|
||||||
@JsonKey(name: 'cost') int? cost,
|
|
||||||
@JsonKey(name: 'business_type') String? businessType,
|
|
||||||
@JsonKey(name: 'image_url') String? imageUrl,
|
|
||||||
@JsonKey(name: 'printer_type') String? printerType,
|
|
||||||
@JsonKey(name: 'metadata') Map<String, dynamic>? metadata,
|
|
||||||
@JsonKey(name: 'is_active') bool? isActive,
|
|
||||||
@JsonKey(name: 'created_at') DateTime? createdAt,
|
|
||||||
@JsonKey(name: 'updated_at') DateTime? updatedAt,
|
|
||||||
@JsonKey(name: 'variants') List<ProductVariantDto>? variants,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
class _$ProductDtoCopyWithImpl<$Res, $Val extends ProductDto>
|
|
||||||
implements $ProductDtoCopyWith<$Res> {
|
|
||||||
_$ProductDtoCopyWithImpl(this._value, this._then);
|
|
||||||
|
|
||||||
// ignore: unused_field
|
|
||||||
final $Val _value;
|
|
||||||
// ignore: unused_field
|
|
||||||
final $Res Function($Val) _then;
|
|
||||||
|
|
||||||
/// Create a copy of ProductDto
|
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
|
||||||
@pragma('vm:prefer-inline')
|
|
||||||
@override
|
|
||||||
$Res call({
|
|
||||||
Object? id = freezed,
|
|
||||||
Object? organizationId = freezed,
|
|
||||||
Object? categoryId = freezed,
|
|
||||||
Object? sku = freezed,
|
|
||||||
Object? name = freezed,
|
|
||||||
Object? description = freezed,
|
|
||||||
Object? price = freezed,
|
|
||||||
Object? cost = freezed,
|
|
||||||
Object? businessType = freezed,
|
|
||||||
Object? imageUrl = freezed,
|
|
||||||
Object? printerType = freezed,
|
|
||||||
Object? metadata = freezed,
|
|
||||||
Object? isActive = freezed,
|
|
||||||
Object? createdAt = freezed,
|
|
||||||
Object? updatedAt = freezed,
|
|
||||||
Object? variants = freezed,
|
|
||||||
}) {
|
|
||||||
return _then(
|
|
||||||
_value.copyWith(
|
|
||||||
id: freezed == id
|
|
||||||
? _value.id
|
|
||||||
: id // ignore: cast_nullable_to_non_nullable
|
|
||||||
as String?,
|
|
||||||
organizationId: freezed == organizationId
|
|
||||||
? _value.organizationId
|
|
||||||
: organizationId // ignore: cast_nullable_to_non_nullable
|
|
||||||
as String?,
|
|
||||||
categoryId: freezed == categoryId
|
|
||||||
? _value.categoryId
|
|
||||||
: categoryId // ignore: cast_nullable_to_non_nullable
|
|
||||||
as String?,
|
|
||||||
sku: freezed == sku
|
|
||||||
? _value.sku
|
|
||||||
: sku // ignore: cast_nullable_to_non_nullable
|
|
||||||
as String?,
|
|
||||||
name: freezed == name
|
|
||||||
? _value.name
|
|
||||||
: name // ignore: cast_nullable_to_non_nullable
|
|
||||||
as String?,
|
|
||||||
description: freezed == description
|
|
||||||
? _value.description
|
|
||||||
: description // ignore: cast_nullable_to_non_nullable
|
|
||||||
as String?,
|
|
||||||
price: freezed == price
|
|
||||||
? _value.price
|
|
||||||
: price // ignore: cast_nullable_to_non_nullable
|
|
||||||
as int?,
|
|
||||||
cost: freezed == cost
|
|
||||||
? _value.cost
|
|
||||||
: cost // ignore: cast_nullable_to_non_nullable
|
|
||||||
as int?,
|
|
||||||
businessType: freezed == businessType
|
|
||||||
? _value.businessType
|
|
||||||
: businessType // ignore: cast_nullable_to_non_nullable
|
|
||||||
as String?,
|
|
||||||
imageUrl: freezed == imageUrl
|
|
||||||
? _value.imageUrl
|
|
||||||
: imageUrl // ignore: cast_nullable_to_non_nullable
|
|
||||||
as String?,
|
|
||||||
printerType: freezed == printerType
|
|
||||||
? _value.printerType
|
|
||||||
: printerType // ignore: cast_nullable_to_non_nullable
|
|
||||||
as String?,
|
|
||||||
metadata: freezed == metadata
|
|
||||||
? _value.metadata
|
|
||||||
: metadata // ignore: cast_nullable_to_non_nullable
|
|
||||||
as Map<String, dynamic>?,
|
|
||||||
isActive: freezed == isActive
|
|
||||||
? _value.isActive
|
|
||||||
: isActive // ignore: cast_nullable_to_non_nullable
|
|
||||||
as bool?,
|
|
||||||
createdAt: freezed == createdAt
|
|
||||||
? _value.createdAt
|
|
||||||
: createdAt // ignore: cast_nullable_to_non_nullable
|
|
||||||
as DateTime?,
|
|
||||||
updatedAt: freezed == updatedAt
|
|
||||||
? _value.updatedAt
|
|
||||||
: updatedAt // ignore: cast_nullable_to_non_nullable
|
|
||||||
as DateTime?,
|
|
||||||
variants: freezed == variants
|
|
||||||
? _value.variants
|
|
||||||
: variants // ignore: cast_nullable_to_non_nullable
|
|
||||||
as List<ProductVariantDto>?,
|
|
||||||
)
|
|
||||||
as $Val,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
abstract class _$$ProductDtoImplCopyWith<$Res>
|
|
||||||
implements $ProductDtoCopyWith<$Res> {
|
|
||||||
factory _$$ProductDtoImplCopyWith(
|
|
||||||
_$ProductDtoImpl value,
|
|
||||||
$Res Function(_$ProductDtoImpl) then,
|
|
||||||
) = __$$ProductDtoImplCopyWithImpl<$Res>;
|
|
||||||
@override
|
|
||||||
@useResult
|
|
||||||
$Res call({
|
|
||||||
@JsonKey(name: 'id') String? id,
|
|
||||||
@JsonKey(name: 'organization_id') String? organizationId,
|
|
||||||
@JsonKey(name: 'category_id') String? categoryId,
|
|
||||||
@JsonKey(name: 'sku') String? sku,
|
|
||||||
@JsonKey(name: 'name') String? name,
|
|
||||||
@JsonKey(name: 'description') String? description,
|
|
||||||
@JsonKey(name: 'price') int? price,
|
|
||||||
@JsonKey(name: 'cost') int? cost,
|
|
||||||
@JsonKey(name: 'business_type') String? businessType,
|
|
||||||
@JsonKey(name: 'image_url') String? imageUrl,
|
|
||||||
@JsonKey(name: 'printer_type') String? printerType,
|
|
||||||
@JsonKey(name: 'metadata') Map<String, dynamic>? metadata,
|
|
||||||
@JsonKey(name: 'is_active') bool? isActive,
|
|
||||||
@JsonKey(name: 'created_at') DateTime? createdAt,
|
|
||||||
@JsonKey(name: 'updated_at') DateTime? updatedAt,
|
|
||||||
@JsonKey(name: 'variants') List<ProductVariantDto>? variants,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
class __$$ProductDtoImplCopyWithImpl<$Res>
|
|
||||||
extends _$ProductDtoCopyWithImpl<$Res, _$ProductDtoImpl>
|
|
||||||
implements _$$ProductDtoImplCopyWith<$Res> {
|
|
||||||
__$$ProductDtoImplCopyWithImpl(
|
|
||||||
_$ProductDtoImpl _value,
|
|
||||||
$Res Function(_$ProductDtoImpl) _then,
|
|
||||||
) : super(_value, _then);
|
|
||||||
|
|
||||||
/// Create a copy of ProductDto
|
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
|
||||||
@pragma('vm:prefer-inline')
|
|
||||||
@override
|
|
||||||
$Res call({
|
|
||||||
Object? id = freezed,
|
|
||||||
Object? organizationId = freezed,
|
|
||||||
Object? categoryId = freezed,
|
|
||||||
Object? sku = freezed,
|
|
||||||
Object? name = freezed,
|
|
||||||
Object? description = freezed,
|
|
||||||
Object? price = freezed,
|
|
||||||
Object? cost = freezed,
|
|
||||||
Object? businessType = freezed,
|
|
||||||
Object? imageUrl = freezed,
|
|
||||||
Object? printerType = freezed,
|
|
||||||
Object? metadata = freezed,
|
|
||||||
Object? isActive = freezed,
|
|
||||||
Object? createdAt = freezed,
|
|
||||||
Object? updatedAt = freezed,
|
|
||||||
Object? variants = freezed,
|
|
||||||
}) {
|
|
||||||
return _then(
|
|
||||||
_$ProductDtoImpl(
|
|
||||||
id: freezed == id
|
|
||||||
? _value.id
|
|
||||||
: id // ignore: cast_nullable_to_non_nullable
|
|
||||||
as String?,
|
|
||||||
organizationId: freezed == organizationId
|
|
||||||
? _value.organizationId
|
|
||||||
: organizationId // ignore: cast_nullable_to_non_nullable
|
|
||||||
as String?,
|
|
||||||
categoryId: freezed == categoryId
|
|
||||||
? _value.categoryId
|
|
||||||
: categoryId // ignore: cast_nullable_to_non_nullable
|
|
||||||
as String?,
|
|
||||||
sku: freezed == sku
|
|
||||||
? _value.sku
|
|
||||||
: sku // ignore: cast_nullable_to_non_nullable
|
|
||||||
as String?,
|
|
||||||
name: freezed == name
|
|
||||||
? _value.name
|
|
||||||
: name // ignore: cast_nullable_to_non_nullable
|
|
||||||
as String?,
|
|
||||||
description: freezed == description
|
|
||||||
? _value.description
|
|
||||||
: description // ignore: cast_nullable_to_non_nullable
|
|
||||||
as String?,
|
|
||||||
price: freezed == price
|
|
||||||
? _value.price
|
|
||||||
: price // ignore: cast_nullable_to_non_nullable
|
|
||||||
as int?,
|
|
||||||
cost: freezed == cost
|
|
||||||
? _value.cost
|
|
||||||
: cost // ignore: cast_nullable_to_non_nullable
|
|
||||||
as int?,
|
|
||||||
businessType: freezed == businessType
|
|
||||||
? _value.businessType
|
|
||||||
: businessType // ignore: cast_nullable_to_non_nullable
|
|
||||||
as String?,
|
|
||||||
imageUrl: freezed == imageUrl
|
|
||||||
? _value.imageUrl
|
|
||||||
: imageUrl // ignore: cast_nullable_to_non_nullable
|
|
||||||
as String?,
|
|
||||||
printerType: freezed == printerType
|
|
||||||
? _value.printerType
|
|
||||||
: printerType // ignore: cast_nullable_to_non_nullable
|
|
||||||
as String?,
|
|
||||||
metadata: freezed == metadata
|
|
||||||
? _value._metadata
|
|
||||||
: metadata // ignore: cast_nullable_to_non_nullable
|
|
||||||
as Map<String, dynamic>?,
|
|
||||||
isActive: freezed == isActive
|
|
||||||
? _value.isActive
|
|
||||||
: isActive // ignore: cast_nullable_to_non_nullable
|
|
||||||
as bool?,
|
|
||||||
createdAt: freezed == createdAt
|
|
||||||
? _value.createdAt
|
|
||||||
: createdAt // ignore: cast_nullable_to_non_nullable
|
|
||||||
as DateTime?,
|
|
||||||
updatedAt: freezed == updatedAt
|
|
||||||
? _value.updatedAt
|
|
||||||
: updatedAt // ignore: cast_nullable_to_non_nullable
|
|
||||||
as DateTime?,
|
|
||||||
variants: freezed == variants
|
|
||||||
? _value._variants
|
|
||||||
: variants // ignore: cast_nullable_to_non_nullable
|
|
||||||
as List<ProductVariantDto>?,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
@JsonSerializable()
|
|
||||||
class _$ProductDtoImpl extends _ProductDto {
|
|
||||||
const _$ProductDtoImpl({
|
|
||||||
@JsonKey(name: 'id') this.id,
|
|
||||||
@JsonKey(name: 'organization_id') this.organizationId,
|
|
||||||
@JsonKey(name: 'category_id') this.categoryId,
|
|
||||||
@JsonKey(name: 'sku') this.sku,
|
|
||||||
@JsonKey(name: 'name') this.name,
|
|
||||||
@JsonKey(name: 'description') this.description,
|
|
||||||
@JsonKey(name: 'price') this.price,
|
|
||||||
@JsonKey(name: 'cost') this.cost,
|
|
||||||
@JsonKey(name: 'business_type') this.businessType,
|
|
||||||
@JsonKey(name: 'image_url') this.imageUrl,
|
|
||||||
@JsonKey(name: 'printer_type') this.printerType,
|
|
||||||
@JsonKey(name: 'metadata') final Map<String, dynamic>? metadata,
|
|
||||||
@JsonKey(name: 'is_active') this.isActive,
|
|
||||||
@JsonKey(name: 'created_at') this.createdAt,
|
|
||||||
@JsonKey(name: 'updated_at') this.updatedAt,
|
|
||||||
@JsonKey(name: 'variants') final List<ProductVariantDto>? variants,
|
|
||||||
}) : _metadata = metadata,
|
|
||||||
_variants = variants,
|
|
||||||
super._();
|
|
||||||
|
|
||||||
factory _$ProductDtoImpl.fromJson(Map<String, dynamic> json) =>
|
|
||||||
_$$ProductDtoImplFromJson(json);
|
|
||||||
|
|
||||||
@override
|
|
||||||
@JsonKey(name: 'id')
|
|
||||||
final String? id;
|
|
||||||
@override
|
|
||||||
@JsonKey(name: 'organization_id')
|
|
||||||
final String? organizationId;
|
|
||||||
@override
|
|
||||||
@JsonKey(name: 'category_id')
|
|
||||||
final String? categoryId;
|
|
||||||
@override
|
|
||||||
@JsonKey(name: 'sku')
|
|
||||||
final String? sku;
|
|
||||||
@override
|
|
||||||
@JsonKey(name: 'name')
|
|
||||||
final String? name;
|
|
||||||
@override
|
|
||||||
@JsonKey(name: 'description')
|
|
||||||
final String? description;
|
|
||||||
@override
|
|
||||||
@JsonKey(name: 'price')
|
|
||||||
final int? price;
|
|
||||||
@override
|
|
||||||
@JsonKey(name: 'cost')
|
|
||||||
final int? cost;
|
|
||||||
@override
|
|
||||||
@JsonKey(name: 'business_type')
|
|
||||||
final String? businessType;
|
|
||||||
@override
|
|
||||||
@JsonKey(name: 'image_url')
|
|
||||||
final String? imageUrl;
|
|
||||||
@override
|
|
||||||
@JsonKey(name: 'printer_type')
|
|
||||||
final String? printerType;
|
|
||||||
final Map<String, dynamic>? _metadata;
|
|
||||||
@override
|
|
||||||
@JsonKey(name: 'metadata')
|
|
||||||
Map<String, dynamic>? get metadata {
|
|
||||||
final value = _metadata;
|
|
||||||
if (value == null) return null;
|
|
||||||
if (_metadata is EqualUnmodifiableMapView) return _metadata;
|
|
||||||
// ignore: implicit_dynamic_type
|
|
||||||
return EqualUnmodifiableMapView(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
@JsonKey(name: 'is_active')
|
|
||||||
final bool? isActive;
|
|
||||||
@override
|
|
||||||
@JsonKey(name: 'created_at')
|
|
||||||
final DateTime? createdAt;
|
|
||||||
@override
|
|
||||||
@JsonKey(name: 'updated_at')
|
|
||||||
final DateTime? updatedAt;
|
|
||||||
final List<ProductVariantDto>? _variants;
|
|
||||||
@override
|
|
||||||
@JsonKey(name: 'variants')
|
|
||||||
List<ProductVariantDto>? get variants {
|
|
||||||
final value = _variants;
|
|
||||||
if (value == null) return null;
|
|
||||||
if (_variants is EqualUnmodifiableListView) return _variants;
|
|
||||||
// ignore: implicit_dynamic_type
|
|
||||||
return EqualUnmodifiableListView(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
String toString() {
|
|
||||||
return 'ProductDto(id: $id, organizationId: $organizationId, categoryId: $categoryId, sku: $sku, name: $name, description: $description, price: $price, cost: $cost, businessType: $businessType, imageUrl: $imageUrl, printerType: $printerType, metadata: $metadata, isActive: $isActive, createdAt: $createdAt, updatedAt: $updatedAt, variants: $variants)';
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
bool operator ==(Object other) {
|
|
||||||
return identical(this, other) ||
|
|
||||||
(other.runtimeType == runtimeType &&
|
|
||||||
other is _$ProductDtoImpl &&
|
|
||||||
(identical(other.id, id) || other.id == id) &&
|
|
||||||
(identical(other.organizationId, organizationId) ||
|
|
||||||
other.organizationId == organizationId) &&
|
|
||||||
(identical(other.categoryId, categoryId) ||
|
|
||||||
other.categoryId == categoryId) &&
|
|
||||||
(identical(other.sku, sku) || other.sku == sku) &&
|
|
||||||
(identical(other.name, name) || other.name == name) &&
|
|
||||||
(identical(other.description, description) ||
|
|
||||||
other.description == description) &&
|
|
||||||
(identical(other.price, price) || other.price == price) &&
|
|
||||||
(identical(other.cost, cost) || other.cost == cost) &&
|
|
||||||
(identical(other.businessType, businessType) ||
|
|
||||||
other.businessType == businessType) &&
|
|
||||||
(identical(other.imageUrl, imageUrl) ||
|
|
||||||
other.imageUrl == imageUrl) &&
|
|
||||||
(identical(other.printerType, printerType) ||
|
|
||||||
other.printerType == printerType) &&
|
|
||||||
const DeepCollectionEquality().equals(other._metadata, _metadata) &&
|
|
||||||
(identical(other.isActive, isActive) ||
|
|
||||||
other.isActive == isActive) &&
|
|
||||||
(identical(other.createdAt, createdAt) ||
|
|
||||||
other.createdAt == createdAt) &&
|
|
||||||
(identical(other.updatedAt, updatedAt) ||
|
|
||||||
other.updatedAt == updatedAt) &&
|
|
||||||
const DeepCollectionEquality().equals(other._variants, _variants));
|
|
||||||
}
|
|
||||||
|
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
|
||||||
@override
|
|
||||||
int get hashCode => Object.hash(
|
|
||||||
runtimeType,
|
|
||||||
id,
|
|
||||||
organizationId,
|
|
||||||
categoryId,
|
|
||||||
sku,
|
|
||||||
name,
|
|
||||||
description,
|
|
||||||
price,
|
|
||||||
cost,
|
|
||||||
businessType,
|
|
||||||
imageUrl,
|
|
||||||
printerType,
|
|
||||||
const DeepCollectionEquality().hash(_metadata),
|
|
||||||
isActive,
|
|
||||||
createdAt,
|
|
||||||
updatedAt,
|
|
||||||
const DeepCollectionEquality().hash(_variants),
|
|
||||||
);
|
|
||||||
|
|
||||||
/// Create a copy of ProductDto
|
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
|
||||||
@override
|
|
||||||
@pragma('vm:prefer-inline')
|
|
||||||
_$$ProductDtoImplCopyWith<_$ProductDtoImpl> get copyWith =>
|
|
||||||
__$$ProductDtoImplCopyWithImpl<_$ProductDtoImpl>(this, _$identity);
|
|
||||||
|
|
||||||
@override
|
|
||||||
Map<String, dynamic> toJson() {
|
|
||||||
return _$$ProductDtoImplToJson(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract class _ProductDto extends ProductDto {
|
|
||||||
const factory _ProductDto({
|
|
||||||
@JsonKey(name: 'id') final String? id,
|
|
||||||
@JsonKey(name: 'organization_id') final String? organizationId,
|
|
||||||
@JsonKey(name: 'category_id') final String? categoryId,
|
|
||||||
@JsonKey(name: 'sku') final String? sku,
|
|
||||||
@JsonKey(name: 'name') final String? name,
|
|
||||||
@JsonKey(name: 'description') final String? description,
|
|
||||||
@JsonKey(name: 'price') final int? price,
|
|
||||||
@JsonKey(name: 'cost') final int? cost,
|
|
||||||
@JsonKey(name: 'business_type') final String? businessType,
|
|
||||||
@JsonKey(name: 'image_url') final String? imageUrl,
|
|
||||||
@JsonKey(name: 'printer_type') final String? printerType,
|
|
||||||
@JsonKey(name: 'metadata') final Map<String, dynamic>? metadata,
|
|
||||||
@JsonKey(name: 'is_active') final bool? isActive,
|
|
||||||
@JsonKey(name: 'created_at') final DateTime? createdAt,
|
|
||||||
@JsonKey(name: 'updated_at') final DateTime? updatedAt,
|
|
||||||
@JsonKey(name: 'variants') final List<ProductVariantDto>? variants,
|
|
||||||
}) = _$ProductDtoImpl;
|
|
||||||
const _ProductDto._() : super._();
|
|
||||||
|
|
||||||
factory _ProductDto.fromJson(Map<String, dynamic> json) =
|
|
||||||
_$ProductDtoImpl.fromJson;
|
|
||||||
|
|
||||||
@override
|
|
||||||
@JsonKey(name: 'id')
|
|
||||||
String? get id;
|
|
||||||
@override
|
|
||||||
@JsonKey(name: 'organization_id')
|
|
||||||
String? get organizationId;
|
|
||||||
@override
|
|
||||||
@JsonKey(name: 'category_id')
|
|
||||||
String? get categoryId;
|
|
||||||
@override
|
|
||||||
@JsonKey(name: 'sku')
|
|
||||||
String? get sku;
|
|
||||||
@override
|
|
||||||
@JsonKey(name: 'name')
|
|
||||||
String? get name;
|
|
||||||
@override
|
|
||||||
@JsonKey(name: 'description')
|
|
||||||
String? get description;
|
|
||||||
@override
|
|
||||||
@JsonKey(name: 'price')
|
|
||||||
int? get price;
|
|
||||||
@override
|
|
||||||
@JsonKey(name: 'cost')
|
|
||||||
int? get cost;
|
|
||||||
@override
|
|
||||||
@JsonKey(name: 'business_type')
|
|
||||||
String? get businessType;
|
|
||||||
@override
|
|
||||||
@JsonKey(name: 'image_url')
|
|
||||||
String? get imageUrl;
|
|
||||||
@override
|
|
||||||
@JsonKey(name: 'printer_type')
|
|
||||||
String? get printerType;
|
|
||||||
@override
|
|
||||||
@JsonKey(name: 'metadata')
|
|
||||||
Map<String, dynamic>? get metadata;
|
|
||||||
@override
|
|
||||||
@JsonKey(name: 'is_active')
|
|
||||||
bool? get isActive;
|
|
||||||
@override
|
|
||||||
@JsonKey(name: 'created_at')
|
|
||||||
DateTime? get createdAt;
|
|
||||||
@override
|
|
||||||
@JsonKey(name: 'updated_at')
|
|
||||||
DateTime? get updatedAt;
|
|
||||||
@override
|
|
||||||
@JsonKey(name: 'variants')
|
|
||||||
List<ProductVariantDto>? get variants;
|
|
||||||
|
|
||||||
/// Create a copy of ProductDto
|
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
|
||||||
@override
|
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
|
||||||
_$$ProductDtoImplCopyWith<_$ProductDtoImpl> get copyWith =>
|
|
||||||
throw _privateConstructorUsedError;
|
|
||||||
}
|
|
||||||
|
|
||||||
ProductVariantDto _$ProductVariantDtoFromJson(Map<String, dynamic> json) {
|
|
||||||
return _ProductVariantDto.fromJson(json);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
mixin _$ProductVariantDto {
|
|
||||||
@JsonKey(name: 'id')
|
|
||||||
String? get id => throw _privateConstructorUsedError;
|
|
||||||
@JsonKey(name: 'product_id')
|
|
||||||
String? get productId => throw _privateConstructorUsedError;
|
|
||||||
@JsonKey(name: 'name')
|
|
||||||
String? get name => throw _privateConstructorUsedError;
|
|
||||||
@JsonKey(name: 'price_modifier')
|
|
||||||
int? get priceModifier => throw _privateConstructorUsedError;
|
|
||||||
@JsonKey(name: 'cost')
|
|
||||||
int? get cost => throw _privateConstructorUsedError;
|
|
||||||
@JsonKey(name: 'metadata')
|
|
||||||
Map<String, dynamic>? get metadata => throw _privateConstructorUsedError;
|
|
||||||
@JsonKey(name: 'created_at')
|
|
||||||
DateTime? get createdAt => throw _privateConstructorUsedError;
|
|
||||||
@JsonKey(name: 'updated_at')
|
|
||||||
DateTime? get updatedAt => throw _privateConstructorUsedError;
|
|
||||||
|
|
||||||
/// Serializes this ProductVariantDto to a JSON map.
|
|
||||||
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
|
||||||
|
|
||||||
/// Create a copy of ProductVariantDto
|
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
|
||||||
$ProductVariantDtoCopyWith<ProductVariantDto> get copyWith =>
|
|
||||||
throw _privateConstructorUsedError;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
abstract class $ProductVariantDtoCopyWith<$Res> {
|
|
||||||
factory $ProductVariantDtoCopyWith(
|
|
||||||
ProductVariantDto value,
|
|
||||||
$Res Function(ProductVariantDto) then,
|
|
||||||
) = _$ProductVariantDtoCopyWithImpl<$Res, ProductVariantDto>;
|
|
||||||
@useResult
|
|
||||||
$Res call({
|
|
||||||
@JsonKey(name: 'id') String? id,
|
|
||||||
@JsonKey(name: 'product_id') String? productId,
|
|
||||||
@JsonKey(name: 'name') String? name,
|
|
||||||
@JsonKey(name: 'price_modifier') int? priceModifier,
|
|
||||||
@JsonKey(name: 'cost') int? cost,
|
|
||||||
@JsonKey(name: 'metadata') Map<String, dynamic>? metadata,
|
|
||||||
@JsonKey(name: 'created_at') DateTime? createdAt,
|
|
||||||
@JsonKey(name: 'updated_at') DateTime? updatedAt,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
class _$ProductVariantDtoCopyWithImpl<$Res, $Val extends ProductVariantDto>
|
|
||||||
implements $ProductVariantDtoCopyWith<$Res> {
|
|
||||||
_$ProductVariantDtoCopyWithImpl(this._value, this._then);
|
|
||||||
|
|
||||||
// ignore: unused_field
|
|
||||||
final $Val _value;
|
|
||||||
// ignore: unused_field
|
|
||||||
final $Res Function($Val) _then;
|
|
||||||
|
|
||||||
/// Create a copy of ProductVariantDto
|
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
|
||||||
@pragma('vm:prefer-inline')
|
|
||||||
@override
|
|
||||||
$Res call({
|
|
||||||
Object? id = freezed,
|
|
||||||
Object? productId = freezed,
|
|
||||||
Object? name = freezed,
|
|
||||||
Object? priceModifier = freezed,
|
|
||||||
Object? cost = freezed,
|
|
||||||
Object? metadata = freezed,
|
|
||||||
Object? createdAt = freezed,
|
|
||||||
Object? updatedAt = freezed,
|
|
||||||
}) {
|
|
||||||
return _then(
|
|
||||||
_value.copyWith(
|
|
||||||
id: freezed == id
|
|
||||||
? _value.id
|
|
||||||
: id // ignore: cast_nullable_to_non_nullable
|
|
||||||
as String?,
|
|
||||||
productId: freezed == productId
|
|
||||||
? _value.productId
|
|
||||||
: productId // ignore: cast_nullable_to_non_nullable
|
|
||||||
as String?,
|
|
||||||
name: freezed == name
|
|
||||||
? _value.name
|
|
||||||
: name // ignore: cast_nullable_to_non_nullable
|
|
||||||
as String?,
|
|
||||||
priceModifier: freezed == priceModifier
|
|
||||||
? _value.priceModifier
|
|
||||||
: priceModifier // ignore: cast_nullable_to_non_nullable
|
|
||||||
as int?,
|
|
||||||
cost: freezed == cost
|
|
||||||
? _value.cost
|
|
||||||
: cost // ignore: cast_nullable_to_non_nullable
|
|
||||||
as int?,
|
|
||||||
metadata: freezed == metadata
|
|
||||||
? _value.metadata
|
|
||||||
: metadata // ignore: cast_nullable_to_non_nullable
|
|
||||||
as Map<String, dynamic>?,
|
|
||||||
createdAt: freezed == createdAt
|
|
||||||
? _value.createdAt
|
|
||||||
: createdAt // ignore: cast_nullable_to_non_nullable
|
|
||||||
as DateTime?,
|
|
||||||
updatedAt: freezed == updatedAt
|
|
||||||
? _value.updatedAt
|
|
||||||
: updatedAt // ignore: cast_nullable_to_non_nullable
|
|
||||||
as DateTime?,
|
|
||||||
)
|
|
||||||
as $Val,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
abstract class _$$ProductVariantDtoImplCopyWith<$Res>
|
|
||||||
implements $ProductVariantDtoCopyWith<$Res> {
|
|
||||||
factory _$$ProductVariantDtoImplCopyWith(
|
|
||||||
_$ProductVariantDtoImpl value,
|
|
||||||
$Res Function(_$ProductVariantDtoImpl) then,
|
|
||||||
) = __$$ProductVariantDtoImplCopyWithImpl<$Res>;
|
|
||||||
@override
|
|
||||||
@useResult
|
|
||||||
$Res call({
|
|
||||||
@JsonKey(name: 'id') String? id,
|
|
||||||
@JsonKey(name: 'product_id') String? productId,
|
|
||||||
@JsonKey(name: 'name') String? name,
|
|
||||||
@JsonKey(name: 'price_modifier') int? priceModifier,
|
|
||||||
@JsonKey(name: 'cost') int? cost,
|
|
||||||
@JsonKey(name: 'metadata') Map<String, dynamic>? metadata,
|
|
||||||
@JsonKey(name: 'created_at') DateTime? createdAt,
|
|
||||||
@JsonKey(name: 'updated_at') DateTime? updatedAt,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
class __$$ProductVariantDtoImplCopyWithImpl<$Res>
|
|
||||||
extends _$ProductVariantDtoCopyWithImpl<$Res, _$ProductVariantDtoImpl>
|
|
||||||
implements _$$ProductVariantDtoImplCopyWith<$Res> {
|
|
||||||
__$$ProductVariantDtoImplCopyWithImpl(
|
|
||||||
_$ProductVariantDtoImpl _value,
|
|
||||||
$Res Function(_$ProductVariantDtoImpl) _then,
|
|
||||||
) : super(_value, _then);
|
|
||||||
|
|
||||||
/// Create a copy of ProductVariantDto
|
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
|
||||||
@pragma('vm:prefer-inline')
|
|
||||||
@override
|
|
||||||
$Res call({
|
|
||||||
Object? id = freezed,
|
|
||||||
Object? productId = freezed,
|
|
||||||
Object? name = freezed,
|
|
||||||
Object? priceModifier = freezed,
|
|
||||||
Object? cost = freezed,
|
|
||||||
Object? metadata = freezed,
|
|
||||||
Object? createdAt = freezed,
|
|
||||||
Object? updatedAt = freezed,
|
|
||||||
}) {
|
|
||||||
return _then(
|
|
||||||
_$ProductVariantDtoImpl(
|
|
||||||
id: freezed == id
|
|
||||||
? _value.id
|
|
||||||
: id // ignore: cast_nullable_to_non_nullable
|
|
||||||
as String?,
|
|
||||||
productId: freezed == productId
|
|
||||||
? _value.productId
|
|
||||||
: productId // ignore: cast_nullable_to_non_nullable
|
|
||||||
as String?,
|
|
||||||
name: freezed == name
|
|
||||||
? _value.name
|
|
||||||
: name // ignore: cast_nullable_to_non_nullable
|
|
||||||
as String?,
|
|
||||||
priceModifier: freezed == priceModifier
|
|
||||||
? _value.priceModifier
|
|
||||||
: priceModifier // ignore: cast_nullable_to_non_nullable
|
|
||||||
as int?,
|
|
||||||
cost: freezed == cost
|
|
||||||
? _value.cost
|
|
||||||
: cost // ignore: cast_nullable_to_non_nullable
|
|
||||||
as int?,
|
|
||||||
metadata: freezed == metadata
|
|
||||||
? _value._metadata
|
|
||||||
: metadata // ignore: cast_nullable_to_non_nullable
|
|
||||||
as Map<String, dynamic>?,
|
|
||||||
createdAt: freezed == createdAt
|
|
||||||
? _value.createdAt
|
|
||||||
: createdAt // ignore: cast_nullable_to_non_nullable
|
|
||||||
as DateTime?,
|
|
||||||
updatedAt: freezed == updatedAt
|
|
||||||
? _value.updatedAt
|
|
||||||
: updatedAt // ignore: cast_nullable_to_non_nullable
|
|
||||||
as DateTime?,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
@JsonSerializable()
|
|
||||||
class _$ProductVariantDtoImpl extends _ProductVariantDto {
|
|
||||||
const _$ProductVariantDtoImpl({
|
|
||||||
@JsonKey(name: 'id') this.id,
|
|
||||||
@JsonKey(name: 'product_id') this.productId,
|
|
||||||
@JsonKey(name: 'name') this.name,
|
|
||||||
@JsonKey(name: 'price_modifier') this.priceModifier,
|
|
||||||
@JsonKey(name: 'cost') this.cost,
|
|
||||||
@JsonKey(name: 'metadata') final Map<String, dynamic>? metadata,
|
|
||||||
@JsonKey(name: 'created_at') this.createdAt,
|
|
||||||
@JsonKey(name: 'updated_at') this.updatedAt,
|
|
||||||
}) : _metadata = metadata,
|
|
||||||
super._();
|
|
||||||
|
|
||||||
factory _$ProductVariantDtoImpl.fromJson(Map<String, dynamic> json) =>
|
|
||||||
_$$ProductVariantDtoImplFromJson(json);
|
|
||||||
|
|
||||||
@override
|
|
||||||
@JsonKey(name: 'id')
|
|
||||||
final String? id;
|
|
||||||
@override
|
|
||||||
@JsonKey(name: 'product_id')
|
|
||||||
final String? productId;
|
|
||||||
@override
|
|
||||||
@JsonKey(name: 'name')
|
|
||||||
final String? name;
|
|
||||||
@override
|
|
||||||
@JsonKey(name: 'price_modifier')
|
|
||||||
final int? priceModifier;
|
|
||||||
@override
|
|
||||||
@JsonKey(name: 'cost')
|
|
||||||
final int? cost;
|
|
||||||
final Map<String, dynamic>? _metadata;
|
|
||||||
@override
|
|
||||||
@JsonKey(name: 'metadata')
|
|
||||||
Map<String, dynamic>? get metadata {
|
|
||||||
final value = _metadata;
|
|
||||||
if (value == null) return null;
|
|
||||||
if (_metadata is EqualUnmodifiableMapView) return _metadata;
|
|
||||||
// ignore: implicit_dynamic_type
|
|
||||||
return EqualUnmodifiableMapView(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
@JsonKey(name: 'created_at')
|
|
||||||
final DateTime? createdAt;
|
|
||||||
@override
|
|
||||||
@JsonKey(name: 'updated_at')
|
|
||||||
final DateTime? updatedAt;
|
|
||||||
|
|
||||||
@override
|
|
||||||
String toString() {
|
|
||||||
return 'ProductVariantDto(id: $id, productId: $productId, name: $name, priceModifier: $priceModifier, cost: $cost, metadata: $metadata, createdAt: $createdAt, updatedAt: $updatedAt)';
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
bool operator ==(Object other) {
|
|
||||||
return identical(this, other) ||
|
|
||||||
(other.runtimeType == runtimeType &&
|
|
||||||
other is _$ProductVariantDtoImpl &&
|
|
||||||
(identical(other.id, id) || other.id == id) &&
|
|
||||||
(identical(other.productId, productId) ||
|
|
||||||
other.productId == productId) &&
|
|
||||||
(identical(other.name, name) || other.name == name) &&
|
|
||||||
(identical(other.priceModifier, priceModifier) ||
|
|
||||||
other.priceModifier == priceModifier) &&
|
|
||||||
(identical(other.cost, cost) || other.cost == cost) &&
|
|
||||||
const DeepCollectionEquality().equals(other._metadata, _metadata) &&
|
|
||||||
(identical(other.createdAt, createdAt) ||
|
|
||||||
other.createdAt == createdAt) &&
|
|
||||||
(identical(other.updatedAt, updatedAt) ||
|
|
||||||
other.updatedAt == updatedAt));
|
|
||||||
}
|
|
||||||
|
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
|
||||||
@override
|
|
||||||
int get hashCode => Object.hash(
|
|
||||||
runtimeType,
|
|
||||||
id,
|
|
||||||
productId,
|
|
||||||
name,
|
|
||||||
priceModifier,
|
|
||||||
cost,
|
|
||||||
const DeepCollectionEquality().hash(_metadata),
|
|
||||||
createdAt,
|
|
||||||
updatedAt,
|
|
||||||
);
|
|
||||||
|
|
||||||
/// Create a copy of ProductVariantDto
|
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
|
||||||
@override
|
|
||||||
@pragma('vm:prefer-inline')
|
|
||||||
_$$ProductVariantDtoImplCopyWith<_$ProductVariantDtoImpl> get copyWith =>
|
|
||||||
__$$ProductVariantDtoImplCopyWithImpl<_$ProductVariantDtoImpl>(
|
|
||||||
this,
|
|
||||||
_$identity,
|
|
||||||
);
|
|
||||||
|
|
||||||
@override
|
|
||||||
Map<String, dynamic> toJson() {
|
|
||||||
return _$$ProductVariantDtoImplToJson(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract class _ProductVariantDto extends ProductVariantDto {
|
|
||||||
const factory _ProductVariantDto({
|
|
||||||
@JsonKey(name: 'id') final String? id,
|
|
||||||
@JsonKey(name: 'product_id') final String? productId,
|
|
||||||
@JsonKey(name: 'name') final String? name,
|
|
||||||
@JsonKey(name: 'price_modifier') final int? priceModifier,
|
|
||||||
@JsonKey(name: 'cost') final int? cost,
|
|
||||||
@JsonKey(name: 'metadata') final Map<String, dynamic>? metadata,
|
|
||||||
@JsonKey(name: 'created_at') final DateTime? createdAt,
|
|
||||||
@JsonKey(name: 'updated_at') final DateTime? updatedAt,
|
|
||||||
}) = _$ProductVariantDtoImpl;
|
|
||||||
const _ProductVariantDto._() : super._();
|
|
||||||
|
|
||||||
factory _ProductVariantDto.fromJson(Map<String, dynamic> json) =
|
|
||||||
_$ProductVariantDtoImpl.fromJson;
|
|
||||||
|
|
||||||
@override
|
|
||||||
@JsonKey(name: 'id')
|
|
||||||
String? get id;
|
|
||||||
@override
|
|
||||||
@JsonKey(name: 'product_id')
|
|
||||||
String? get productId;
|
|
||||||
@override
|
|
||||||
@JsonKey(name: 'name')
|
|
||||||
String? get name;
|
|
||||||
@override
|
|
||||||
@JsonKey(name: 'price_modifier')
|
|
||||||
int? get priceModifier;
|
|
||||||
@override
|
|
||||||
@JsonKey(name: 'cost')
|
|
||||||
int? get cost;
|
|
||||||
@override
|
|
||||||
@JsonKey(name: 'metadata')
|
|
||||||
Map<String, dynamic>? get metadata;
|
|
||||||
@override
|
|
||||||
@JsonKey(name: 'created_at')
|
|
||||||
DateTime? get createdAt;
|
|
||||||
@override
|
|
||||||
@JsonKey(name: 'updated_at')
|
|
||||||
DateTime? get updatedAt;
|
|
||||||
|
|
||||||
/// Create a copy of ProductVariantDto
|
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
|
||||||
@override
|
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
|
||||||
_$$ProductVariantDtoImplCopyWith<_$ProductVariantDtoImpl> get copyWith =>
|
|
||||||
throw _privateConstructorUsedError;
|
|
||||||
}
|
|
||||||
@ -1,83 +0,0 @@
|
|||||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
|
||||||
|
|
||||||
part of 'product_dtos.dart';
|
|
||||||
|
|
||||||
// **************************************************************************
|
|
||||||
// JsonSerializableGenerator
|
|
||||||
// **************************************************************************
|
|
||||||
|
|
||||||
_$ProductDtoImpl _$$ProductDtoImplFromJson(Map<String, dynamic> json) =>
|
|
||||||
_$ProductDtoImpl(
|
|
||||||
id: json['id'] as String?,
|
|
||||||
organizationId: json['organization_id'] as String?,
|
|
||||||
categoryId: json['category_id'] as String?,
|
|
||||||
sku: json['sku'] as String?,
|
|
||||||
name: json['name'] as String?,
|
|
||||||
description: json['description'] as String?,
|
|
||||||
price: (json['price'] as num?)?.toInt(),
|
|
||||||
cost: (json['cost'] as num?)?.toInt(),
|
|
||||||
businessType: json['business_type'] as String?,
|
|
||||||
imageUrl: json['image_url'] as String?,
|
|
||||||
printerType: json['printer_type'] as String?,
|
|
||||||
metadata: json['metadata'] as Map<String, dynamic>?,
|
|
||||||
isActive: json['is_active'] as bool?,
|
|
||||||
createdAt: json['created_at'] == null
|
|
||||||
? null
|
|
||||||
: DateTime.parse(json['created_at'] as String),
|
|
||||||
updatedAt: json['updated_at'] == null
|
|
||||||
? null
|
|
||||||
: DateTime.parse(json['updated_at'] as String),
|
|
||||||
variants: (json['variants'] as List<dynamic>?)
|
|
||||||
?.map((e) => ProductVariantDto.fromJson(e as Map<String, dynamic>))
|
|
||||||
.toList(),
|
|
||||||
);
|
|
||||||
|
|
||||||
Map<String, dynamic> _$$ProductDtoImplToJson(_$ProductDtoImpl instance) =>
|
|
||||||
<String, dynamic>{
|
|
||||||
'id': instance.id,
|
|
||||||
'organization_id': instance.organizationId,
|
|
||||||
'category_id': instance.categoryId,
|
|
||||||
'sku': instance.sku,
|
|
||||||
'name': instance.name,
|
|
||||||
'description': instance.description,
|
|
||||||
'price': instance.price,
|
|
||||||
'cost': instance.cost,
|
|
||||||
'business_type': instance.businessType,
|
|
||||||
'image_url': instance.imageUrl,
|
|
||||||
'printer_type': instance.printerType,
|
|
||||||
'metadata': instance.metadata,
|
|
||||||
'is_active': instance.isActive,
|
|
||||||
'created_at': instance.createdAt?.toIso8601String(),
|
|
||||||
'updated_at': instance.updatedAt?.toIso8601String(),
|
|
||||||
'variants': instance.variants,
|
|
||||||
};
|
|
||||||
|
|
||||||
_$ProductVariantDtoImpl _$$ProductVariantDtoImplFromJson(
|
|
||||||
Map<String, dynamic> json,
|
|
||||||
) => _$ProductVariantDtoImpl(
|
|
||||||
id: json['id'] as String?,
|
|
||||||
productId: json['product_id'] as String?,
|
|
||||||
name: json['name'] as String?,
|
|
||||||
priceModifier: (json['price_modifier'] as num?)?.toInt(),
|
|
||||||
cost: (json['cost'] as num?)?.toInt(),
|
|
||||||
metadata: json['metadata'] as Map<String, dynamic>?,
|
|
||||||
createdAt: json['created_at'] == null
|
|
||||||
? null
|
|
||||||
: DateTime.parse(json['created_at'] as String),
|
|
||||||
updatedAt: json['updated_at'] == null
|
|
||||||
? null
|
|
||||||
: DateTime.parse(json['updated_at'] as String),
|
|
||||||
);
|
|
||||||
|
|
||||||
Map<String, dynamic> _$$ProductVariantDtoImplToJson(
|
|
||||||
_$ProductVariantDtoImpl instance,
|
|
||||||
) => <String, dynamic>{
|
|
||||||
'id': instance.id,
|
|
||||||
'product_id': instance.productId,
|
|
||||||
'name': instance.name,
|
|
||||||
'price_modifier': instance.priceModifier,
|
|
||||||
'cost': instance.cost,
|
|
||||||
'metadata': instance.metadata,
|
|
||||||
'created_at': instance.createdAt?.toIso8601String(),
|
|
||||||
'updated_at': instance.updatedAt?.toIso8601String(),
|
|
||||||
};
|
|
||||||
@ -1,43 +0,0 @@
|
|||||||
import 'dart:developer';
|
|
||||||
|
|
||||||
import 'package:dartz/dartz.dart';
|
|
||||||
import 'package:injectable/injectable.dart';
|
|
||||||
|
|
||||||
import '../../../domain/product/product.dart';
|
|
||||||
import '../datasources/remote_data_provider.dart';
|
|
||||||
|
|
||||||
@Injectable(as: IProductRepository)
|
|
||||||
class ProductRepository implements IProductRepository {
|
|
||||||
final ProductRemoteDataProvider _dataProvider;
|
|
||||||
final String _logName = 'ProductRepository';
|
|
||||||
|
|
||||||
ProductRepository(this._dataProvider);
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<Either<ProductFailure, List<Product>>> get({
|
|
||||||
int page = 1,
|
|
||||||
int limit = 10,
|
|
||||||
String? categoryId,
|
|
||||||
String? search,
|
|
||||||
}) async {
|
|
||||||
try {
|
|
||||||
final result = await _dataProvider.fetch(
|
|
||||||
page: page,
|
|
||||||
limit: limit,
|
|
||||||
categoryId: categoryId,
|
|
||||||
search: search,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (result.hasError) {
|
|
||||||
return left(result.error!);
|
|
||||||
}
|
|
||||||
|
|
||||||
final auth = result.data!.map((e) => e.toDomain()).toList();
|
|
||||||
|
|
||||||
return right(auth);
|
|
||||||
} catch (e, s) {
|
|
||||||
log('getProductError', name: _logName, error: e, stackTrace: s);
|
|
||||||
return left(const ProductFailure.unexpectedError());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -9,23 +9,13 @@
|
|||||||
// coverage:ignore-file
|
// coverage:ignore-file
|
||||||
|
|
||||||
// ignore_for_file: no_leading_underscores_for_library_prefixes
|
// ignore_for_file: no_leading_underscores_for_library_prefixes
|
||||||
import 'package:apskel_owner_flutter/application/analytic/category_analytic_loader/category_analytic_loader_bloc.dart'
|
|
||||||
as _i1038;
|
|
||||||
import 'package:apskel_owner_flutter/application/analytic/profit_loss_loader/profit_loss_loader_bloc.dart'
|
|
||||||
as _i11;
|
|
||||||
import 'package:apskel_owner_flutter/application/analytic/sales_loader/sales_loader_bloc.dart'
|
|
||||||
as _i889;
|
|
||||||
import 'package:apskel_owner_flutter/application/auth/auth_bloc.dart' as _i945;
|
import 'package:apskel_owner_flutter/application/auth/auth_bloc.dart' as _i945;
|
||||||
import 'package:apskel_owner_flutter/application/auth/login_form/login_form_bloc.dart'
|
import 'package:apskel_owner_flutter/application/auth/login_form/login_form_bloc.dart'
|
||||||
as _i775;
|
as _i775;
|
||||||
import 'package:apskel_owner_flutter/application/auth/logout_form/logout_form_bloc.dart'
|
import 'package:apskel_owner_flutter/application/auth/logout_form/logout_form_bloc.dart'
|
||||||
as _i574;
|
as _i574;
|
||||||
import 'package:apskel_owner_flutter/application/category/category_loader/category_loader_bloc.dart'
|
|
||||||
as _i183;
|
|
||||||
import 'package:apskel_owner_flutter/application/language/language_bloc.dart'
|
import 'package:apskel_owner_flutter/application/language/language_bloc.dart'
|
||||||
as _i455;
|
as _i455;
|
||||||
import 'package:apskel_owner_flutter/application/product/product_loader/product_loader_bloc.dart'
|
|
||||||
as _i458;
|
|
||||||
import 'package:apskel_owner_flutter/common/api/api_client.dart' as _i115;
|
import 'package:apskel_owner_flutter/common/api/api_client.dart' as _i115;
|
||||||
import 'package:apskel_owner_flutter/common/di/di_auto_route.dart' as _i311;
|
import 'package:apskel_owner_flutter/common/di/di_auto_route.dart' as _i311;
|
||||||
import 'package:apskel_owner_flutter/common/di/di_connectivity.dart' as _i586;
|
import 'package:apskel_owner_flutter/common/di/di_connectivity.dart' as _i586;
|
||||||
@ -35,30 +25,14 @@ import 'package:apskel_owner_flutter/common/di/di_shared_preferences.dart'
|
|||||||
as _i402;
|
as _i402;
|
||||||
import 'package:apskel_owner_flutter/common/network/network_client.dart'
|
import 'package:apskel_owner_flutter/common/network/network_client.dart'
|
||||||
as _i543;
|
as _i543;
|
||||||
import 'package:apskel_owner_flutter/domain/analytic/repositories/i_analytic_repository.dart'
|
|
||||||
as _i477;
|
|
||||||
import 'package:apskel_owner_flutter/domain/auth/auth.dart' as _i49;
|
import 'package:apskel_owner_flutter/domain/auth/auth.dart' as _i49;
|
||||||
import 'package:apskel_owner_flutter/domain/category/category.dart' as _i1020;
|
|
||||||
import 'package:apskel_owner_flutter/domain/product/product.dart' as _i419;
|
|
||||||
import 'package:apskel_owner_flutter/env.dart' as _i6;
|
import 'package:apskel_owner_flutter/env.dart' as _i6;
|
||||||
import 'package:apskel_owner_flutter/infrastructure/analytic/datasource/remote_data_provider.dart'
|
|
||||||
as _i866;
|
|
||||||
import 'package:apskel_owner_flutter/infrastructure/analytic/repositories/analytic_repository.dart'
|
|
||||||
as _i393;
|
|
||||||
import 'package:apskel_owner_flutter/infrastructure/auth/datasources/local_data_provider.dart'
|
import 'package:apskel_owner_flutter/infrastructure/auth/datasources/local_data_provider.dart'
|
||||||
as _i991;
|
as _i991;
|
||||||
import 'package:apskel_owner_flutter/infrastructure/auth/datasources/remote_data_provider.dart'
|
import 'package:apskel_owner_flutter/infrastructure/auth/datasources/remote_data_provider.dart'
|
||||||
as _i17;
|
as _i17;
|
||||||
import 'package:apskel_owner_flutter/infrastructure/auth/repositories/auth_repository.dart'
|
import 'package:apskel_owner_flutter/infrastructure/auth/repositories/auth_repository.dart'
|
||||||
as _i1035;
|
as _i1035;
|
||||||
import 'package:apskel_owner_flutter/infrastructure/category/datasource/remote_data_provider.dart'
|
|
||||||
as _i333;
|
|
||||||
import 'package:apskel_owner_flutter/infrastructure/category/repositories/category_repository.dart'
|
|
||||||
as _i869;
|
|
||||||
import 'package:apskel_owner_flutter/infrastructure/product/datasources/remote_data_provider.dart'
|
|
||||||
as _i823;
|
|
||||||
import 'package:apskel_owner_flutter/infrastructure/product/repositories/product_repository.dart'
|
|
||||||
as _i121;
|
|
||||||
import 'package:apskel_owner_flutter/presentation/router/app_router.dart'
|
import 'package:apskel_owner_flutter/presentation/router/app_router.dart'
|
||||||
as _i258;
|
as _i258;
|
||||||
import 'package:connectivity_plus/connectivity_plus.dart' as _i895;
|
import 'package:connectivity_plus/connectivity_plus.dart' as _i895;
|
||||||
@ -104,52 +78,23 @@ extension GetItInjectableX on _i174.GetIt {
|
|||||||
gh.factory<_i991.AuthLocalDataProvider>(
|
gh.factory<_i991.AuthLocalDataProvider>(
|
||||||
() => _i991.AuthLocalDataProvider(gh<_i460.SharedPreferences>()),
|
() => _i991.AuthLocalDataProvider(gh<_i460.SharedPreferences>()),
|
||||||
);
|
);
|
||||||
gh.lazySingleton<_i115.ApiClient>(
|
|
||||||
() => _i115.ApiClient(gh<_i361.Dio>(), gh<_i6.Env>()),
|
|
||||||
);
|
|
||||||
gh.factory<_i6.Env>(() => _i6.ProdEnv(), registerFor: {_prod});
|
gh.factory<_i6.Env>(() => _i6.ProdEnv(), registerFor: {_prod});
|
||||||
gh.factory<_i333.CategoryRemoteDataProvider>(
|
gh.lazySingleton<_i115.ApiClient>(
|
||||||
() => _i333.CategoryRemoteDataProvider(gh<_i115.ApiClient>()),
|
() => _i115.ApiClient(
|
||||||
|
gh<_i361.Dio>(),
|
||||||
|
gh<_i6.Env>(),
|
||||||
|
gh<_i460.SharedPreferences>(),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
gh.factory<_i17.AuthRemoteDataProvider>(
|
gh.factory<_i17.AuthRemoteDataProvider>(
|
||||||
() => _i17.AuthRemoteDataProvider(gh<_i115.ApiClient>()),
|
() => _i17.AuthRemoteDataProvider(gh<_i115.ApiClient>()),
|
||||||
);
|
);
|
||||||
gh.factory<_i823.ProductRemoteDataProvider>(
|
|
||||||
() => _i823.ProductRemoteDataProvider(gh<_i115.ApiClient>()),
|
|
||||||
);
|
|
||||||
gh.factory<_i866.AnalyticRemoteDataProvider>(
|
|
||||||
() => _i866.AnalyticRemoteDataProvider(gh<_i115.ApiClient>()),
|
|
||||||
);
|
|
||||||
gh.factory<_i477.IAnalyticRepository>(
|
|
||||||
() => _i393.AnalyticRepository(gh<_i866.AnalyticRemoteDataProvider>()),
|
|
||||||
);
|
|
||||||
gh.factory<_i49.IAuthRepository>(
|
gh.factory<_i49.IAuthRepository>(
|
||||||
() => _i1035.AuthRepository(
|
() => _i1035.AuthRepository(
|
||||||
gh<_i991.AuthLocalDataProvider>(),
|
gh<_i991.AuthLocalDataProvider>(),
|
||||||
gh<_i17.AuthRemoteDataProvider>(),
|
gh<_i17.AuthRemoteDataProvider>(),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
gh.factory<_i419.IProductRepository>(
|
|
||||||
() => _i121.ProductRepository(gh<_i823.ProductRemoteDataProvider>()),
|
|
||||||
);
|
|
||||||
gh.factory<_i1020.ICategoryRepository>(
|
|
||||||
() => _i869.CategoryRepository(gh<_i333.CategoryRemoteDataProvider>()),
|
|
||||||
);
|
|
||||||
gh.factory<_i458.ProductLoaderBloc>(
|
|
||||||
() => _i458.ProductLoaderBloc(gh<_i419.IProductRepository>()),
|
|
||||||
);
|
|
||||||
gh.factory<_i183.CategoryLoaderBloc>(
|
|
||||||
() => _i183.CategoryLoaderBloc(gh<_i1020.ICategoryRepository>()),
|
|
||||||
);
|
|
||||||
gh.factory<_i889.SalesLoaderBloc>(
|
|
||||||
() => _i889.SalesLoaderBloc(gh<_i477.IAnalyticRepository>()),
|
|
||||||
);
|
|
||||||
gh.factory<_i11.ProfitLossLoaderBloc>(
|
|
||||||
() => _i11.ProfitLossLoaderBloc(gh<_i477.IAnalyticRepository>()),
|
|
||||||
);
|
|
||||||
gh.factory<_i1038.CategoryAnalyticLoaderBloc>(
|
|
||||||
() => _i1038.CategoryAnalyticLoaderBloc(gh<_i477.IAnalyticRepository>()),
|
|
||||||
);
|
|
||||||
gh.factory<_i775.LoginFormBloc>(
|
gh.factory<_i775.LoginFormBloc>(
|
||||||
() => _i775.LoginFormBloc(gh<_i49.IAuthRepository>()),
|
() => _i775.LoginFormBloc(gh<_i49.IAuthRepository>()),
|
||||||
);
|
);
|
||||||
|
|||||||
@ -1,5 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:cached_network_image/cached_network_image.dart';
|
|
||||||
import 'package:shimmer/shimmer.dart';
|
|
||||||
|
|
||||||
part 'network_image.dart';
|
|
||||||
@ -1,68 +0,0 @@
|
|||||||
part of 'image.dart';
|
|
||||||
|
|
||||||
class AppNetworkImage extends StatelessWidget {
|
|
||||||
final String? url;
|
|
||||||
final double? height;
|
|
||||||
final double? width;
|
|
||||||
final double? borderRadius;
|
|
||||||
final BoxFit? fit;
|
|
||||||
final bool? isCanZoom;
|
|
||||||
final VoidCallback? onTap;
|
|
||||||
|
|
||||||
const AppNetworkImage({
|
|
||||||
super.key,
|
|
||||||
this.url,
|
|
||||||
this.height,
|
|
||||||
this.width,
|
|
||||||
this.borderRadius = 0,
|
|
||||||
this.fit = BoxFit.cover,
|
|
||||||
this.isCanZoom = false,
|
|
||||||
this.onTap,
|
|
||||||
});
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
Widget customPhoto(
|
|
||||||
double? heightx,
|
|
||||||
double? widthx,
|
|
||||||
BoxFit? fitx,
|
|
||||||
double? radius,
|
|
||||||
) {
|
|
||||||
return CachedNetworkImage(
|
|
||||||
imageUrl: url.toString(),
|
|
||||||
placeholder: (context, url) => Shimmer.fromColors(
|
|
||||||
baseColor: Colors.grey[300]!,
|
|
||||||
highlightColor: Colors.grey[100]!,
|
|
||||||
child: Container(
|
|
||||||
height: height,
|
|
||||||
width: width,
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: Colors.grey.shade300,
|
|
||||||
borderRadius: BorderRadius.circular(radius ?? 0),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
errorWidget: (context, url, error) => Container(
|
|
||||||
height: height,
|
|
||||||
width: width,
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: Colors.grey.shade200,
|
|
||||||
borderRadius: BorderRadius.circular(radius ?? 0),
|
|
||||||
),
|
|
||||||
child: Icon(Icons.image_outlined, color: Colors.grey.shade400),
|
|
||||||
),
|
|
||||||
height: heightx,
|
|
||||||
width: widthx,
|
|
||||||
fit: fitx,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return GestureDetector(
|
|
||||||
onTap: onTap,
|
|
||||||
child: ClipRRect(
|
|
||||||
borderRadius: BorderRadius.circular(borderRadius!),
|
|
||||||
child: customPhoto(height, width, BoxFit.fill, borderRadius),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,27 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
|
|
||||||
import '../../../common/theme/theme.dart';
|
|
||||||
import 'empty_widget.dart';
|
|
||||||
|
|
||||||
class EmptySearchWidget extends StatelessWidget {
|
|
||||||
final String? searchQuery;
|
|
||||||
final VoidCallback? onClear;
|
|
||||||
|
|
||||||
const EmptySearchWidget({Key? key, this.searchQuery, this.onClear})
|
|
||||||
: super(key: key);
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return EmptyWidget(
|
|
||||||
title: 'Pencarian Tidak Ditemukan',
|
|
||||||
message: searchQuery != null
|
|
||||||
? 'Tidak ada hasil untuk "$searchQuery"\nCoba kata kunci lain'
|
|
||||||
: 'Coba gunakan kata kunci yang berbeda',
|
|
||||||
emptyIcon: Icons.search_off_rounded,
|
|
||||||
iconColor: AppColor.warning,
|
|
||||||
buttonText: 'Hapus Filter',
|
|
||||||
onRefresh: onClear,
|
|
||||||
showButton: onClear != null,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,179 +0,0 @@
|
|||||||
// ==================== EMPTY WIDGET ====================
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
|
|
||||||
import '../../../common/theme/theme.dart';
|
|
||||||
|
|
||||||
class EmptyWidget extends StatefulWidget {
|
|
||||||
final String? title;
|
|
||||||
final String? message;
|
|
||||||
final VoidCallback? onRefresh;
|
|
||||||
final IconData? emptyIcon;
|
|
||||||
final String? buttonText;
|
|
||||||
final double? width;
|
|
||||||
final double? height;
|
|
||||||
final bool showButton;
|
|
||||||
final EdgeInsets? padding;
|
|
||||||
final Color? iconColor;
|
|
||||||
|
|
||||||
const EmptyWidget({
|
|
||||||
super.key,
|
|
||||||
this.title,
|
|
||||||
this.message,
|
|
||||||
this.onRefresh,
|
|
||||||
this.emptyIcon,
|
|
||||||
this.buttonText,
|
|
||||||
this.width,
|
|
||||||
this.height,
|
|
||||||
this.showButton = true,
|
|
||||||
this.padding,
|
|
||||||
this.iconColor,
|
|
||||||
});
|
|
||||||
|
|
||||||
@override
|
|
||||||
State<EmptyWidget> createState() => _EmptyWidgetState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _EmptyWidgetState extends State<EmptyWidget>
|
|
||||||
with SingleTickerProviderStateMixin {
|
|
||||||
late AnimationController _animationController;
|
|
||||||
late Animation<double> _fadeAnimation;
|
|
||||||
late Animation<Offset> _slideAnimation;
|
|
||||||
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
super.initState();
|
|
||||||
_animationController = AnimationController(
|
|
||||||
duration: const Duration(milliseconds: 800),
|
|
||||||
vsync: this,
|
|
||||||
);
|
|
||||||
|
|
||||||
_fadeAnimation = Tween<double>(begin: 0.0, end: 1.0).animate(
|
|
||||||
CurvedAnimation(parent: _animationController, curve: Curves.easeInOut),
|
|
||||||
);
|
|
||||||
|
|
||||||
_slideAnimation =
|
|
||||||
Tween<Offset>(begin: const Offset(0.0, 0.3), end: Offset.zero).animate(
|
|
||||||
CurvedAnimation(
|
|
||||||
parent: _animationController,
|
|
||||||
curve: Curves.easeOutCubic,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
_animationController.forward();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void dispose() {
|
|
||||||
_animationController.dispose();
|
|
||||||
super.dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return Container(
|
|
||||||
width: widget.width,
|
|
||||||
height: widget.height,
|
|
||||||
padding: widget.padding ?? const EdgeInsets.all(24),
|
|
||||||
child: FadeTransition(
|
|
||||||
opacity: _fadeAnimation,
|
|
||||||
child: SlideTransition(
|
|
||||||
position: _slideAnimation,
|
|
||||||
child: Column(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
|
||||||
mainAxisSize: MainAxisSize.min,
|
|
||||||
children: [
|
|
||||||
// Empty Illustration
|
|
||||||
Stack(
|
|
||||||
alignment: Alignment.center,
|
|
||||||
children: [
|
|
||||||
// Background Circle
|
|
||||||
Container(
|
|
||||||
width: 120,
|
|
||||||
height: 120,
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
shape: BoxShape.circle,
|
|
||||||
gradient: LinearGradient(
|
|
||||||
colors: [
|
|
||||||
AppColor.primary.withOpacity(0.05),
|
|
||||||
AppColor.secondary.withOpacity(0.05),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
|
|
||||||
// Icon Container
|
|
||||||
Container(
|
|
||||||
width: 80,
|
|
||||||
height: 80,
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
shape: BoxShape.circle,
|
|
||||||
color: AppColor.surface,
|
|
||||||
border: Border.all(color: AppColor.border, width: 2),
|
|
||||||
boxShadow: [
|
|
||||||
BoxShadow(
|
|
||||||
color: AppColor.primary.withOpacity(0.08),
|
|
||||||
blurRadius: 20,
|
|
||||||
offset: const Offset(0, 4),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
child: Icon(
|
|
||||||
widget.emptyIcon ?? Icons.inbox_outlined,
|
|
||||||
size: 40,
|
|
||||||
color: widget.iconColor ?? AppColor.textLight,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
|
|
||||||
const SizedBox(height: 24),
|
|
||||||
|
|
||||||
// Title
|
|
||||||
Text(
|
|
||||||
widget.title ?? 'Tidak Ada Data',
|
|
||||||
style: AppStyle.xl.copyWith(
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
color: AppColor.textPrimary,
|
|
||||||
),
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
),
|
|
||||||
|
|
||||||
const SizedBox(height: 8),
|
|
||||||
|
|
||||||
// Message
|
|
||||||
Text(
|
|
||||||
widget.message ?? 'Belum ada data untuk ditampilkan',
|
|
||||||
style: AppStyle.md.copyWith(
|
|
||||||
color: AppColor.textSecondary,
|
|
||||||
height: 1.4,
|
|
||||||
),
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
),
|
|
||||||
|
|
||||||
// Action Button
|
|
||||||
if (widget.showButton && widget.onRefresh != null) ...[
|
|
||||||
const SizedBox(height: 24),
|
|
||||||
OutlinedButton.icon(
|
|
||||||
onPressed: widget.onRefresh,
|
|
||||||
icon: const Icon(Icons.refresh_rounded, size: 18),
|
|
||||||
label: Text(widget.buttonText ?? 'Muat Ulang'),
|
|
||||||
style: OutlinedButton.styleFrom(
|
|
||||||
foregroundColor: AppColor.primary,
|
|
||||||
side: BorderSide(color: AppColor.primary, width: 1.5),
|
|
||||||
padding: const EdgeInsets.symmetric(
|
|
||||||
horizontal: 20,
|
|
||||||
vertical: 12,
|
|
||||||
),
|
|
||||||
shape: RoundedRectangleBorder(
|
|
||||||
borderRadius: BorderRadius.circular(8),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,176 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
|
|
||||||
import '../../../common/theme/theme.dart';
|
|
||||||
|
|
||||||
class ErrorWidget extends StatefulWidget {
|
|
||||||
final String? title;
|
|
||||||
final String? message;
|
|
||||||
final VoidCallback? onRetry;
|
|
||||||
final String? errorCode;
|
|
||||||
final IconData? errorIcon;
|
|
||||||
final double? width;
|
|
||||||
final double? height;
|
|
||||||
final bool showRetryButton;
|
|
||||||
final EdgeInsets? padding;
|
|
||||||
|
|
||||||
const ErrorWidget({
|
|
||||||
super.key,
|
|
||||||
this.title,
|
|
||||||
this.message,
|
|
||||||
this.onRetry,
|
|
||||||
this.errorCode,
|
|
||||||
this.errorIcon,
|
|
||||||
this.width,
|
|
||||||
this.height,
|
|
||||||
this.showRetryButton = true,
|
|
||||||
this.padding,
|
|
||||||
});
|
|
||||||
|
|
||||||
@override
|
|
||||||
State<ErrorWidget> createState() => _ErrorWidgetState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _ErrorWidgetState extends State<ErrorWidget>
|
|
||||||
with SingleTickerProviderStateMixin {
|
|
||||||
late AnimationController _animationController;
|
|
||||||
late Animation<double> _fadeAnimation;
|
|
||||||
late Animation<double> _scaleAnimation;
|
|
||||||
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
super.initState();
|
|
||||||
_animationController = AnimationController(
|
|
||||||
duration: const Duration(milliseconds: 600),
|
|
||||||
vsync: this,
|
|
||||||
);
|
|
||||||
|
|
||||||
_fadeAnimation = Tween<double>(begin: 0.0, end: 1.0).animate(
|
|
||||||
CurvedAnimation(parent: _animationController, curve: Curves.easeInOut),
|
|
||||||
);
|
|
||||||
|
|
||||||
_scaleAnimation = Tween<double>(begin: 0.8, end: 1.0).animate(
|
|
||||||
CurvedAnimation(parent: _animationController, curve: Curves.elasticOut),
|
|
||||||
);
|
|
||||||
|
|
||||||
_animationController.forward();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void dispose() {
|
|
||||||
_animationController.dispose();
|
|
||||||
super.dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return Container(
|
|
||||||
width: widget.width,
|
|
||||||
height: widget.height,
|
|
||||||
padding: widget.padding ?? const EdgeInsets.all(24),
|
|
||||||
child: FadeTransition(
|
|
||||||
opacity: _fadeAnimation,
|
|
||||||
child: ScaleTransition(
|
|
||||||
scale: _scaleAnimation,
|
|
||||||
child: Column(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
|
||||||
mainAxisSize: MainAxisSize.min,
|
|
||||||
children: [
|
|
||||||
// Error Icon
|
|
||||||
Container(
|
|
||||||
width: 80,
|
|
||||||
height: 80,
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
shape: BoxShape.circle,
|
|
||||||
gradient: LinearGradient(
|
|
||||||
colors: [
|
|
||||||
AppColor.error.withOpacity(0.1),
|
|
||||||
AppColor.warning.withOpacity(0.1),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
border: Border.all(
|
|
||||||
color: AppColor.error.withOpacity(0.2),
|
|
||||||
width: 2,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
child: Icon(
|
|
||||||
widget.errorIcon ?? Icons.error_outline_rounded,
|
|
||||||
size: 40,
|
|
||||||
color: AppColor.error,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
|
|
||||||
const SizedBox(height: 16),
|
|
||||||
|
|
||||||
// Title
|
|
||||||
if (widget.title != null)
|
|
||||||
Text(
|
|
||||||
widget.title!,
|
|
||||||
style: AppStyle.xl.copyWith(
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
color: AppColor.textPrimary,
|
|
||||||
),
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
),
|
|
||||||
|
|
||||||
const SizedBox(height: 8),
|
|
||||||
|
|
||||||
// Message
|
|
||||||
Text(
|
|
||||||
widget.message ?? 'Terjadi kesalahan tidak terduga',
|
|
||||||
style: AppStyle.md.copyWith(
|
|
||||||
color: AppColor.textSecondary,
|
|
||||||
height: 1.4,
|
|
||||||
),
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
),
|
|
||||||
|
|
||||||
// Error Code
|
|
||||||
if (widget.errorCode != null) ...[
|
|
||||||
const SizedBox(height: 12),
|
|
||||||
Container(
|
|
||||||
padding: const EdgeInsets.symmetric(
|
|
||||||
horizontal: 12,
|
|
||||||
vertical: 6,
|
|
||||||
),
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: AppColor.error.withOpacity(0.1),
|
|
||||||
borderRadius: BorderRadius.circular(12),
|
|
||||||
border: Border.all(color: AppColor.error.withOpacity(0.2)),
|
|
||||||
),
|
|
||||||
child: Text(
|
|
||||||
'Error: ${widget.errorCode}',
|
|
||||||
style: AppStyle.xs.copyWith(
|
|
||||||
color: AppColor.error,
|
|
||||||
fontWeight: FontWeight.w500,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
|
|
||||||
// Retry Button
|
|
||||||
if (widget.showRetryButton && widget.onRetry != null) ...[
|
|
||||||
const SizedBox(height: 20),
|
|
||||||
ElevatedButton.icon(
|
|
||||||
onPressed: widget.onRetry,
|
|
||||||
icon: const Icon(Icons.refresh_rounded, size: 18),
|
|
||||||
label: const Text('Coba Lagi'),
|
|
||||||
style: ElevatedButton.styleFrom(
|
|
||||||
backgroundColor: AppColor.primary,
|
|
||||||
foregroundColor: AppColor.textWhite,
|
|
||||||
padding: const EdgeInsets.symmetric(
|
|
||||||
horizontal: 20,
|
|
||||||
vertical: 12,
|
|
||||||
),
|
|
||||||
shape: RoundedRectangleBorder(
|
|
||||||
borderRadius: BorderRadius.circular(8),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,509 +0,0 @@
|
|||||||
import 'package:auto_route/auto_route.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
|
|
||||||
import '../../../common/theme/theme.dart';
|
|
||||||
|
|
||||||
@RoutePage()
|
|
||||||
class ErrorPage extends StatefulWidget {
|
|
||||||
final String? title;
|
|
||||||
final String? message;
|
|
||||||
final VoidCallback? onRetry;
|
|
||||||
final VoidCallback? onBack;
|
|
||||||
final String? errorCode;
|
|
||||||
final IconData? errorIcon;
|
|
||||||
|
|
||||||
const ErrorPage({
|
|
||||||
Key? key,
|
|
||||||
this.title,
|
|
||||||
this.message,
|
|
||||||
this.onRetry,
|
|
||||||
this.onBack,
|
|
||||||
this.errorCode,
|
|
||||||
this.errorIcon,
|
|
||||||
}) : super(key: key);
|
|
||||||
|
|
||||||
@override
|
|
||||||
State<ErrorPage> createState() => _ErrorPageState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _ErrorPageState extends State<ErrorPage> with TickerProviderStateMixin {
|
|
||||||
late AnimationController _bounceController;
|
|
||||||
late AnimationController _fadeController;
|
|
||||||
late AnimationController _slideController;
|
|
||||||
|
|
||||||
late Animation<double> _bounceAnimation;
|
|
||||||
late Animation<double> _fadeAnimation;
|
|
||||||
late Animation<Offset> _slideAnimation;
|
|
||||||
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
super.initState();
|
|
||||||
|
|
||||||
_bounceController = AnimationController(
|
|
||||||
duration: const Duration(milliseconds: 1200),
|
|
||||||
vsync: this,
|
|
||||||
);
|
|
||||||
|
|
||||||
_fadeController = AnimationController(
|
|
||||||
duration: const Duration(milliseconds: 800),
|
|
||||||
vsync: this,
|
|
||||||
);
|
|
||||||
|
|
||||||
_slideController = AnimationController(
|
|
||||||
duration: const Duration(milliseconds: 1000),
|
|
||||||
vsync: this,
|
|
||||||
);
|
|
||||||
|
|
||||||
_bounceAnimation = Tween<double>(begin: 0.0, end: 1.0).animate(
|
|
||||||
CurvedAnimation(parent: _bounceController, curve: Curves.elasticOut),
|
|
||||||
);
|
|
||||||
|
|
||||||
_fadeAnimation = Tween<double>(begin: 0.0, end: 1.0).animate(
|
|
||||||
CurvedAnimation(parent: _fadeController, curve: Curves.easeInOut),
|
|
||||||
);
|
|
||||||
|
|
||||||
_slideAnimation =
|
|
||||||
Tween<Offset>(begin: const Offset(0.0, 0.5), end: Offset.zero).animate(
|
|
||||||
CurvedAnimation(parent: _slideController, curve: Curves.easeOutCubic),
|
|
||||||
);
|
|
||||||
|
|
||||||
// Start animations
|
|
||||||
_bounceController.forward();
|
|
||||||
Future.delayed(const Duration(milliseconds: 300), () {
|
|
||||||
_fadeController.forward();
|
|
||||||
});
|
|
||||||
Future.delayed(const Duration(milliseconds: 500), () {
|
|
||||||
_slideController.forward();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void dispose() {
|
|
||||||
_bounceController.dispose();
|
|
||||||
_fadeController.dispose();
|
|
||||||
_slideController.dispose();
|
|
||||||
super.dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return Scaffold(
|
|
||||||
body: Container(
|
|
||||||
width: double.infinity,
|
|
||||||
height: double.infinity,
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
gradient: LinearGradient(
|
|
||||||
begin: Alignment.topLeft,
|
|
||||||
end: Alignment.bottomRight,
|
|
||||||
colors: [
|
|
||||||
AppColor.primary.withOpacity(0.05),
|
|
||||||
AppColor.background,
|
|
||||||
AppColor.primaryLight.withOpacity(0.03),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
child: SafeArea(
|
|
||||||
child: SingleChildScrollView(
|
|
||||||
padding: const EdgeInsets.all(24.0),
|
|
||||||
child: Column(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
|
||||||
children: [
|
|
||||||
const SizedBox(height: 60),
|
|
||||||
|
|
||||||
// Animated Error Illustration
|
|
||||||
AnimatedBuilder(
|
|
||||||
animation: _bounceAnimation,
|
|
||||||
builder: (context, child) {
|
|
||||||
return Transform.scale(
|
|
||||||
scale: _bounceAnimation.value,
|
|
||||||
child: Stack(
|
|
||||||
alignment: Alignment.center,
|
|
||||||
children: [
|
|
||||||
// Outer glow circle
|
|
||||||
Container(
|
|
||||||
width: 200,
|
|
||||||
height: 200,
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
shape: BoxShape.circle,
|
|
||||||
gradient: RadialGradient(
|
|
||||||
colors: [
|
|
||||||
AppColor.error.withOpacity(0.1),
|
|
||||||
Colors.transparent,
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
|
|
||||||
// Middle circle with gradient
|
|
||||||
Container(
|
|
||||||
width: 140,
|
|
||||||
height: 140,
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
shape: BoxShape.circle,
|
|
||||||
gradient: LinearGradient(
|
|
||||||
begin: Alignment.topLeft,
|
|
||||||
end: Alignment.bottomRight,
|
|
||||||
colors: [
|
|
||||||
AppColor.error.withOpacity(0.15),
|
|
||||||
AppColor.warning.withOpacity(0.15),
|
|
||||||
AppColor.primary.withOpacity(0.1),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
boxShadow: [
|
|
||||||
BoxShadow(
|
|
||||||
color: AppColor.error.withOpacity(0.2),
|
|
||||||
blurRadius: 30,
|
|
||||||
offset: const Offset(0, 10),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
|
|
||||||
// Inner circle with icon
|
|
||||||
Container(
|
|
||||||
width: 100,
|
|
||||||
height: 100,
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
shape: BoxShape.circle,
|
|
||||||
gradient: LinearGradient(
|
|
||||||
colors: AppColor.primaryGradient,
|
|
||||||
),
|
|
||||||
boxShadow: [
|
|
||||||
BoxShadow(
|
|
||||||
color: AppColor.primary.withOpacity(0.3),
|
|
||||||
blurRadius: 20,
|
|
||||||
offset: const Offset(0, 8),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
child: Icon(
|
|
||||||
widget.errorIcon ?? Icons.sentiment_dissatisfied,
|
|
||||||
size: 50,
|
|
||||||
color: AppColor.textWhite,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
|
|
||||||
// Decorative floating dots
|
|
||||||
...List.generate(6, (index) {
|
|
||||||
final radius = 120.0;
|
|
||||||
return Positioned(
|
|
||||||
left:
|
|
||||||
100 +
|
|
||||||
radius *
|
|
||||||
0.8 *
|
|
||||||
(index.isEven ? 1 : -1) *
|
|
||||||
(index / 6),
|
|
||||||
top:
|
|
||||||
100 +
|
|
||||||
radius *
|
|
||||||
0.6 *
|
|
||||||
(index.isOdd ? 1 : -1) *
|
|
||||||
(index / 6),
|
|
||||||
child: Container(
|
|
||||||
width: 8 + (index % 3) * 4,
|
|
||||||
height: 8 + (index % 3) * 4,
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
shape: BoxShape.circle,
|
|
||||||
color: [
|
|
||||||
AppColor.primary,
|
|
||||||
AppColor.error,
|
|
||||||
AppColor.warning,
|
|
||||||
][index % 3].withOpacity(0.6),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
|
|
||||||
const SizedBox(height: 40),
|
|
||||||
|
|
||||||
// Animated Title
|
|
||||||
FadeTransition(
|
|
||||||
opacity: _fadeAnimation,
|
|
||||||
child: Text(
|
|
||||||
widget.title ?? 'Ups! Ada Yang Salah',
|
|
||||||
style: AppStyle.h2.copyWith(
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
color: AppColor.primary, // warna solid
|
|
||||||
),
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
|
|
||||||
const SizedBox(height: 16),
|
|
||||||
|
|
||||||
// Animated Message
|
|
||||||
SlideTransition(
|
|
||||||
position: _slideAnimation,
|
|
||||||
child: FadeTransition(
|
|
||||||
opacity: _fadeAnimation,
|
|
||||||
child: Container(
|
|
||||||
padding: const EdgeInsets.all(20),
|
|
||||||
margin: const EdgeInsets.symmetric(horizontal: 8),
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: AppColor.surface,
|
|
||||||
borderRadius: BorderRadius.circular(16),
|
|
||||||
boxShadow: [
|
|
||||||
BoxShadow(
|
|
||||||
color: AppColor.primary.withOpacity(0.08),
|
|
||||||
blurRadius: 20,
|
|
||||||
offset: const Offset(0, 8),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
border: Border.all(
|
|
||||||
color: AppColor.border.withOpacity(0.5),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
child: Column(
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
widget.message ??
|
|
||||||
'Sepertinya ada masalah teknis yang tidak terduga. Jangan khawatir, tim kami sedang bekerja keras untuk memperbaikinya!',
|
|
||||||
style: AppStyle.lg.copyWith(
|
|
||||||
color: AppColor.textSecondary,
|
|
||||||
height: 1.6,
|
|
||||||
),
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
),
|
|
||||||
|
|
||||||
if (widget.errorCode != null) ...[
|
|
||||||
const SizedBox(height: 16),
|
|
||||||
Container(
|
|
||||||
padding: const EdgeInsets.symmetric(
|
|
||||||
horizontal: 16,
|
|
||||||
vertical: 8,
|
|
||||||
),
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
gradient: LinearGradient(
|
|
||||||
colors: [
|
|
||||||
AppColor.error.withOpacity(0.1),
|
|
||||||
AppColor.warning.withOpacity(0.1),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
borderRadius: BorderRadius.circular(20),
|
|
||||||
border: Border.all(
|
|
||||||
color: AppColor.error.withOpacity(0.3),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
child: Row(
|
|
||||||
mainAxisSize: MainAxisSize.min,
|
|
||||||
children: [
|
|
||||||
Icon(
|
|
||||||
Icons.code,
|
|
||||||
size: 16,
|
|
||||||
color: AppColor.error,
|
|
||||||
),
|
|
||||||
const SizedBox(width: 8),
|
|
||||||
Text(
|
|
||||||
'Kode Error: ${widget.errorCode}',
|
|
||||||
style: AppStyle.sm.copyWith(
|
|
||||||
color: AppColor.error,
|
|
||||||
fontWeight: FontWeight.w600,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
|
|
||||||
const SizedBox(height: 50),
|
|
||||||
|
|
||||||
// Animated Buttons
|
|
||||||
SlideTransition(
|
|
||||||
position: _slideAnimation,
|
|
||||||
child: FadeTransition(
|
|
||||||
opacity: _fadeAnimation,
|
|
||||||
child: Column(
|
|
||||||
children: [
|
|
||||||
// Retry Button with gradient
|
|
||||||
if (widget.onRetry != null)
|
|
||||||
Container(
|
|
||||||
width: double.infinity,
|
|
||||||
height: 60,
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
gradient: LinearGradient(
|
|
||||||
colors: AppColor.primaryGradient,
|
|
||||||
),
|
|
||||||
borderRadius: BorderRadius.circular(16),
|
|
||||||
boxShadow: [
|
|
||||||
BoxShadow(
|
|
||||||
color: AppColor.primary.withOpacity(0.4),
|
|
||||||
blurRadius: 15,
|
|
||||||
offset: const Offset(0, 8),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
child: ElevatedButton.icon(
|
|
||||||
onPressed: widget.onRetry,
|
|
||||||
icon: const Icon(
|
|
||||||
Icons.refresh_rounded,
|
|
||||||
color: AppColor.textWhite,
|
|
||||||
size: 24,
|
|
||||||
),
|
|
||||||
label: Text(
|
|
||||||
'Coba Lagi',
|
|
||||||
style: AppStyle.xl.copyWith(
|
|
||||||
color: AppColor.textWhite,
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
style: ElevatedButton.styleFrom(
|
|
||||||
backgroundColor: Colors.transparent,
|
|
||||||
shadowColor: Colors.transparent,
|
|
||||||
shape: RoundedRectangleBorder(
|
|
||||||
borderRadius: BorderRadius.circular(16),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
|
|
||||||
const SizedBox(height: 16),
|
|
||||||
|
|
||||||
// Back Button with modern design
|
|
||||||
if (widget.onBack != null)
|
|
||||||
Container(
|
|
||||||
width: double.infinity,
|
|
||||||
height: 60,
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: AppColor.surface,
|
|
||||||
borderRadius: BorderRadius.circular(16),
|
|
||||||
border: Border.all(
|
|
||||||
width: 2,
|
|
||||||
color: AppColor.primary.withOpacity(0.3),
|
|
||||||
),
|
|
||||||
boxShadow: [
|
|
||||||
BoxShadow(
|
|
||||||
color: AppColor.primary.withOpacity(0.1),
|
|
||||||
blurRadius: 10,
|
|
||||||
offset: const Offset(0, 4),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
child: OutlinedButton.icon(
|
|
||||||
onPressed: widget.onBack,
|
|
||||||
icon: Icon(
|
|
||||||
Icons.arrow_back_ios_rounded,
|
|
||||||
color: AppColor.primary,
|
|
||||||
size: 20,
|
|
||||||
),
|
|
||||||
label: Text(
|
|
||||||
'Kembali',
|
|
||||||
style: AppStyle.xl.copyWith(
|
|
||||||
color: AppColor.primary,
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
style: OutlinedButton.styleFrom(
|
|
||||||
backgroundColor: Colors.transparent,
|
|
||||||
side: BorderSide.none,
|
|
||||||
shape: RoundedRectangleBorder(
|
|
||||||
borderRadius: BorderRadius.circular(16),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
|
|
||||||
const SizedBox(height: 40),
|
|
||||||
|
|
||||||
// Help text with icon
|
|
||||||
FadeTransition(
|
|
||||||
opacity: _fadeAnimation,
|
|
||||||
child: Container(
|
|
||||||
padding: const EdgeInsets.all(16),
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: AppColor.info.withOpacity(0.05),
|
|
||||||
borderRadius: BorderRadius.circular(12),
|
|
||||||
border: Border.all(color: AppColor.info.withOpacity(0.1)),
|
|
||||||
),
|
|
||||||
child: Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
|
||||||
children: [
|
|
||||||
Icon(
|
|
||||||
Icons.help_outline_rounded,
|
|
||||||
size: 18,
|
|
||||||
color: AppColor.info,
|
|
||||||
),
|
|
||||||
const SizedBox(width: 8),
|
|
||||||
Flexible(
|
|
||||||
child: Text(
|
|
||||||
'Butuh bantuan? Hubungi tim support kami',
|
|
||||||
style: AppStyle.sm.copyWith(
|
|
||||||
color: AppColor.info,
|
|
||||||
fontWeight: FontWeight.w500,
|
|
||||||
),
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Usage Example dengan berbagai variasi
|
|
||||||
class ErrorPageExamples extends StatelessWidget {
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return Column(
|
|
||||||
children: [
|
|
||||||
// Network Error
|
|
||||||
ElevatedButton(
|
|
||||||
onPressed: () => Navigator.push(
|
|
||||||
context,
|
|
||||||
MaterialPageRoute(
|
|
||||||
builder: (context) => ErrorPage(
|
|
||||||
title: 'Koneksi Terputus',
|
|
||||||
message:
|
|
||||||
'Sepertinya koneksi internet Anda bermasalah. Periksa jaringan dan coba lagi.',
|
|
||||||
errorCode: 'NET_404',
|
|
||||||
errorIcon: Icons.wifi_off_rounded,
|
|
||||||
onRetry: () => Navigator.pop(context),
|
|
||||||
onBack: () => Navigator.pop(context),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
child: Text('Network Error'),
|
|
||||||
),
|
|
||||||
|
|
||||||
// Server Error
|
|
||||||
ElevatedButton(
|
|
||||||
onPressed: () => Navigator.push(
|
|
||||||
context,
|
|
||||||
MaterialPageRoute(
|
|
||||||
builder: (context) => ErrorPage(
|
|
||||||
title: 'Server Sibuk',
|
|
||||||
message:
|
|
||||||
'Server sedang mengalami gangguan. Tim kami sedang memperbaikinya.',
|
|
||||||
errorCode: 'SRV_500',
|
|
||||||
errorIcon: Icons.dns_rounded,
|
|
||||||
onRetry: () => Navigator.pop(context),
|
|
||||||
onBack: () => Navigator.pop(context),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
child: Text('Server Error'),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,43 +1,20 @@
|
|||||||
import 'package:auto_route/auto_route.dart';
|
import 'package:auto_route/auto_route.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
|
||||||
import 'package:line_icons/line_icons.dart';
|
import 'package:line_icons/line_icons.dart';
|
||||||
|
|
||||||
import '../../../application/analytic/category_analytic_loader/category_analytic_loader_bloc.dart';
|
|
||||||
import '../../../application/analytic/profit_loss_loader/profit_loss_loader_bloc.dart';
|
|
||||||
import '../../../common/extension/extension.dart';
|
|
||||||
import '../../../common/theme/theme.dart';
|
import '../../../common/theme/theme.dart';
|
||||||
import '../../../domain/analytic/analytic.dart';
|
|
||||||
import '../../../injection.dart';
|
|
||||||
import '../../components/appbar/appbar.dart';
|
import '../../components/appbar/appbar.dart';
|
||||||
import 'widgets/cash_flow.dart';
|
import 'widgets/cash_flow.dart';
|
||||||
import 'widgets/category.dart';
|
import 'widgets/category.dart';
|
||||||
import 'widgets/product.dart';
|
|
||||||
import 'widgets/profit_loss.dart';
|
import 'widgets/profit_loss.dart';
|
||||||
import 'widgets/summary_card.dart';
|
import 'widgets/summary_card.dart';
|
||||||
|
|
||||||
@RoutePage()
|
@RoutePage()
|
||||||
class FinancePage extends StatefulWidget implements AutoRouteWrapper {
|
class FinancePage extends StatefulWidget {
|
||||||
const FinancePage({super.key});
|
const FinancePage({super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<FinancePage> createState() => _FinancePageState();
|
State<FinancePage> createState() => _FinancePageState();
|
||||||
|
|
||||||
@override
|
|
||||||
Widget wrappedRoute(BuildContext context) => MultiBlocProvider(
|
|
||||||
providers: [
|
|
||||||
BlocProvider(
|
|
||||||
create: (_) =>
|
|
||||||
getIt<ProfitLossLoaderBloc>()..add(ProfitLossLoaderEvent.fetched()),
|
|
||||||
),
|
|
||||||
BlocProvider(
|
|
||||||
create: (context) =>
|
|
||||||
getIt<CategoryAnalyticLoaderBloc>()
|
|
||||||
..add(CategoryAnalyticLoaderEvent.fetched()),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
child: this,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class _FinancePageState extends State<FinancePage>
|
class _FinancePageState extends State<FinancePage>
|
||||||
@ -113,83 +90,69 @@ class _FinancePageState extends State<FinancePage>
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
backgroundColor: AppColor.background,
|
backgroundColor: AppColor.background,
|
||||||
body: BlocBuilder<ProfitLossLoaderBloc, ProfitLossLoaderState>(
|
body: CustomScrollView(
|
||||||
builder: (context, state) {
|
slivers: [
|
||||||
return CustomScrollView(
|
// SliverAppBar with animated background
|
||||||
slivers: [
|
SliverAppBar(
|
||||||
// SliverAppBar with animated background
|
expandedHeight: 120,
|
||||||
SliverAppBar(
|
floating: false,
|
||||||
expandedHeight: 120,
|
pinned: true,
|
||||||
floating: false,
|
backgroundColor: AppColor.primary,
|
||||||
pinned: true,
|
elevation: 0,
|
||||||
backgroundColor: AppColor.primary,
|
flexibleSpace: CustomAppBar(title: 'Keuangan'),
|
||||||
elevation: 0,
|
),
|
||||||
flexibleSpace: CustomAppBar(title: 'Keuangan'),
|
|
||||||
),
|
|
||||||
|
|
||||||
// Header dengan filter periode
|
// Header dengan filter periode
|
||||||
SliverToBoxAdapter(
|
SliverToBoxAdapter(
|
||||||
child: FadeTransition(
|
child: FadeTransition(
|
||||||
opacity: _fadeAnimation,
|
opacity: _fadeAnimation,
|
||||||
child: _buildPeriodSelector(),
|
child: _buildPeriodSelector(),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
||||||
// Summary Cards
|
// Summary Cards
|
||||||
SliverToBoxAdapter(
|
SliverToBoxAdapter(
|
||||||
child: SlideTransition(
|
child: SlideTransition(
|
||||||
position: _slideAnimation,
|
position: _slideAnimation,
|
||||||
child: _buildSummaryCards(state.profitLoss.summary),
|
child: _buildSummaryCards(),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
||||||
// Cash Flow Analysis
|
// Cash Flow Analysis
|
||||||
SliverToBoxAdapter(
|
SliverToBoxAdapter(
|
||||||
child: ScaleTransition(
|
child: ScaleTransition(
|
||||||
scale: _scaleAnimation,
|
scale: _scaleAnimation,
|
||||||
child: FinanceCashFlow(dailyData: state.profitLoss.data),
|
child: FinanceCashFlow(),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
||||||
// Profit Loss Detail
|
// Profit Loss Detail
|
||||||
SliverToBoxAdapter(
|
SliverToBoxAdapter(
|
||||||
child: FadeTransition(
|
child: FadeTransition(
|
||||||
opacity: _fadeAnimation,
|
opacity: _fadeAnimation,
|
||||||
child: FinanceProfitLoss(data: state.profitLoss.summary),
|
child: FinanceProfitLoss(),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
||||||
BlocBuilder<
|
// Transaction Categories
|
||||||
CategoryAnalyticLoaderBloc,
|
SliverToBoxAdapter(
|
||||||
CategoryAnalyticLoaderState
|
child: SlideTransition(
|
||||||
>(
|
position: _slideAnimation,
|
||||||
builder: (context, stateCategory) {
|
child: FinanceCategory(),
|
||||||
return SliverToBoxAdapter(
|
),
|
||||||
child: SlideTransition(
|
),
|
||||||
position: _slideAnimation,
|
|
||||||
child: FinanceCategory(
|
|
||||||
categories: stateCategory.categoryAnalytic.data,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
|
|
||||||
// Product Analysis Section
|
// Monthly Comparison
|
||||||
SliverToBoxAdapter(
|
SliverToBoxAdapter(
|
||||||
child: SlideTransition(
|
child: ScaleTransition(
|
||||||
position: _slideAnimation,
|
scale: _scaleAnimation,
|
||||||
child: _buildProductAnalysis(state.profitLoss.productData),
|
child: _buildMonthlyComparison(),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
||||||
// Transaction Categories
|
// Bottom spacing
|
||||||
|
const SliverToBoxAdapter(child: SizedBox(height: 100)),
|
||||||
// Bottom spacing
|
],
|
||||||
const SliverToBoxAdapter(child: SizedBox(height: 100)),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -247,7 +210,7 @@ class _FinancePageState extends State<FinancePage>
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildSummaryCards(ProfitLossSummary summary) {
|
Widget _buildSummaryCards() {
|
||||||
return Padding(
|
return Padding(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 16),
|
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||||
child: Column(
|
child: Column(
|
||||||
@ -257,9 +220,10 @@ class _FinancePageState extends State<FinancePage>
|
|||||||
Expanded(
|
Expanded(
|
||||||
child: FinanceSummaryCard(
|
child: FinanceSummaryCard(
|
||||||
title: 'Total Pendapatan',
|
title: 'Total Pendapatan',
|
||||||
amount: summary.totalRevenue.currencyFormatRp,
|
amount: 'Rp 25.840.000',
|
||||||
icon: LineIcons.arrowUp,
|
icon: LineIcons.arrowUp,
|
||||||
color: AppColor.success,
|
color: AppColor.success,
|
||||||
|
change: '+12.5%',
|
||||||
isPositive: true,
|
isPositive: true,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -267,9 +231,10 @@ class _FinancePageState extends State<FinancePage>
|
|||||||
Expanded(
|
Expanded(
|
||||||
child: FinanceSummaryCard(
|
child: FinanceSummaryCard(
|
||||||
title: 'Total Pengeluaran',
|
title: 'Total Pengeluaran',
|
||||||
amount: summary.totalCost.currencyFormatRp,
|
amount: 'Rp 18.320.000',
|
||||||
icon: LineIcons.arrowDown,
|
icon: LineIcons.arrowDown,
|
||||||
color: AppColor.error,
|
color: AppColor.error,
|
||||||
|
change: '+8.2%',
|
||||||
isPositive: false,
|
isPositive: false,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -281,9 +246,10 @@ class _FinancePageState extends State<FinancePage>
|
|||||||
Expanded(
|
Expanded(
|
||||||
child: FinanceSummaryCard(
|
child: FinanceSummaryCard(
|
||||||
title: 'Keuntungan Bersih',
|
title: 'Keuntungan Bersih',
|
||||||
amount: summary.netProfit.currencyFormatRp,
|
amount: 'Rp 7.520.000',
|
||||||
icon: LineIcons.lineChart,
|
icon: LineIcons.lineChart,
|
||||||
color: AppColor.info,
|
color: AppColor.info,
|
||||||
|
change: '+15.3%',
|
||||||
isPositive: true,
|
isPositive: true,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -291,9 +257,10 @@ class _FinancePageState extends State<FinancePage>
|
|||||||
Expanded(
|
Expanded(
|
||||||
child: FinanceSummaryCard(
|
child: FinanceSummaryCard(
|
||||||
title: 'Margin Profit',
|
title: 'Margin Profit',
|
||||||
amount: '${summary.profitabilityRatio.round()}%',
|
amount: '29.1%',
|
||||||
icon: LineIcons.percent,
|
icon: LineIcons.percent,
|
||||||
color: AppColor.warning,
|
color: AppColor.warning,
|
||||||
|
change: '+2.1%',
|
||||||
isPositive: true,
|
isPositive: true,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -304,7 +271,7 @@ class _FinancePageState extends State<FinancePage>
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildProductAnalysis(List<ProfitLossProductData> products) {
|
Widget _buildMonthlyComparison() {
|
||||||
return Container(
|
return Container(
|
||||||
margin: const EdgeInsets.all(16),
|
margin: const EdgeInsets.all(16),
|
||||||
padding: const EdgeInsets.all(20),
|
padding: const EdgeInsets.all(20),
|
||||||
@ -328,41 +295,138 @@ class _FinancePageState extends State<FinancePage>
|
|||||||
Container(
|
Container(
|
||||||
padding: const EdgeInsets.all(8),
|
padding: const EdgeInsets.all(8),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: AppColor.info.withOpacity(0.1),
|
color: AppColor.warning.withOpacity(0.1),
|
||||||
borderRadius: BorderRadius.circular(8),
|
borderRadius: BorderRadius.circular(8),
|
||||||
),
|
),
|
||||||
child: const Icon(
|
child: const Icon(
|
||||||
LineIcons.shoppingBag,
|
LineIcons.calendarCheck,
|
||||||
color: AppColor.info,
|
color: AppColor.warning,
|
||||||
size: 20,
|
size: 20,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(width: 12),
|
const SizedBox(width: 12),
|
||||||
Text(
|
Text(
|
||||||
'Analisis Produk',
|
'Perbandingan Bulanan',
|
||||||
style: AppStyle.lg.copyWith(fontWeight: FontWeight.bold),
|
style: AppStyle.lg.copyWith(fontWeight: FontWeight.bold),
|
||||||
),
|
),
|
||||||
const Spacer(),
|
],
|
||||||
TextButton(
|
),
|
||||||
onPressed: () {},
|
const SizedBox(height: 20),
|
||||||
child: Text(
|
|
||||||
'Lihat Semua',
|
Row(
|
||||||
style: AppStyle.sm.copyWith(color: AppColor.primary),
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: _buildComparisonCard(
|
||||||
|
'Bulan Ini',
|
||||||
|
'Rp 7.52M',
|
||||||
|
'+15.3%',
|
||||||
|
true,
|
||||||
|
AppColor.primary,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(width: 12),
|
||||||
|
Expanded(
|
||||||
|
child: _buildComparisonCard(
|
||||||
|
'Bulan Lalu',
|
||||||
|
'Rp 6.53M',
|
||||||
|
'-2.1%',
|
||||||
|
false,
|
||||||
|
AppColor.textSecondary,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
// Product list
|
const SizedBox(height: 16),
|
||||||
ListView.separated(
|
|
||||||
shrinkWrap: true,
|
Container(
|
||||||
physics: const NeverScrollableScrollPhysics(),
|
padding: const EdgeInsets.all(16),
|
||||||
padding: const EdgeInsets.only(top: 12),
|
decoration: BoxDecoration(
|
||||||
itemCount: products.length,
|
color: AppColor.success.withOpacity(0.05),
|
||||||
separatorBuilder: (context, index) => const SizedBox(height: 12),
|
borderRadius: BorderRadius.circular(12),
|
||||||
itemBuilder: (context, index) {
|
border: Border.all(color: AppColor.success.withOpacity(0.2)),
|
||||||
final product = products[index];
|
),
|
||||||
return ProfitLossProduct(product: product);
|
child: Row(
|
||||||
},
|
children: [
|
||||||
|
const Icon(
|
||||||
|
LineIcons.thumbsUp,
|
||||||
|
color: AppColor.success,
|
||||||
|
size: 20,
|
||||||
|
),
|
||||||
|
const SizedBox(width: 12),
|
||||||
|
Expanded(
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'Performa Bagus!',
|
||||||
|
style: AppStyle.md.copyWith(
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
color: AppColor.success,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
'Keuntungan meningkat 15.3% dari bulan lalu',
|
||||||
|
style: AppStyle.sm.copyWith(
|
||||||
|
color: AppColor.textSecondary,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildComparisonCard(
|
||||||
|
String period,
|
||||||
|
String amount,
|
||||||
|
String change,
|
||||||
|
bool isPositive,
|
||||||
|
Color color,
|
||||||
|
) {
|
||||||
|
return Container(
|
||||||
|
padding: const EdgeInsets.all(16),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: color.withOpacity(0.05),
|
||||||
|
borderRadius: BorderRadius.circular(12),
|
||||||
|
border: Border.all(color: color.withOpacity(0.2)),
|
||||||
|
),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
period,
|
||||||
|
style: AppStyle.sm.copyWith(color: AppColor.textSecondary),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
Text(
|
||||||
|
amount,
|
||||||
|
style: AppStyle.lg.copyWith(
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
color: color,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 4),
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
Icon(
|
||||||
|
isPositive ? LineIcons.arrowUp : LineIcons.arrowDown,
|
||||||
|
size: 14,
|
||||||
|
color: isPositive ? AppColor.success : AppColor.error,
|
||||||
|
),
|
||||||
|
const SizedBox(width: 4),
|
||||||
|
Text(
|
||||||
|
change,
|
||||||
|
style: AppStyle.xs.copyWith(
|
||||||
|
color: isPositive ? AppColor.success : AppColor.error,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|||||||
@ -1,23 +1,14 @@
|
|||||||
import 'package:fl_chart/fl_chart.dart';
|
import 'package:fl_chart/fl_chart.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:line_icons/line_icons.dart';
|
import 'package:line_icons/line_icons.dart';
|
||||||
import 'package:intl/intl.dart';
|
|
||||||
|
|
||||||
import '../../../../common/theme/theme.dart';
|
import '../../../../common/theme/theme.dart';
|
||||||
import '../../../../domain/analytic/analytic.dart';
|
|
||||||
|
|
||||||
class FinanceCashFlow extends StatelessWidget {
|
class FinanceCashFlow extends StatelessWidget {
|
||||||
final List<ProfitLossDailyData> dailyData;
|
const FinanceCashFlow({super.key});
|
||||||
|
|
||||||
const FinanceCashFlow({super.key, required this.dailyData});
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
// Calculate totals from daily data
|
|
||||||
final totalCashIn = _calculateTotalCashIn();
|
|
||||||
final totalCashOut = _calculateTotalCashOut();
|
|
||||||
final netFlow = totalCashIn - totalCashOut;
|
|
||||||
|
|
||||||
return Container(
|
return Container(
|
||||||
margin: const EdgeInsets.all(16),
|
margin: const EdgeInsets.all(16),
|
||||||
padding: const EdgeInsets.all(20),
|
padding: const EdgeInsets.all(20),
|
||||||
@ -79,7 +70,7 @@ class FinanceCashFlow extends StatelessWidget {
|
|||||||
Expanded(
|
Expanded(
|
||||||
child: _buildCashFlowIndicator(
|
child: _buildCashFlowIndicator(
|
||||||
'Cash In',
|
'Cash In',
|
||||||
_formatCurrency(totalCashIn),
|
'Rp 28.5M',
|
||||||
LineIcons.arrowUp,
|
LineIcons.arrowUp,
|
||||||
AppColor.success,
|
AppColor.success,
|
||||||
),
|
),
|
||||||
@ -88,7 +79,7 @@ class FinanceCashFlow extends StatelessWidget {
|
|||||||
Expanded(
|
Expanded(
|
||||||
child: _buildCashFlowIndicator(
|
child: _buildCashFlowIndicator(
|
||||||
'Cash Out',
|
'Cash Out',
|
||||||
_formatCurrency(totalCashOut),
|
'Rp 21.2M',
|
||||||
LineIcons.arrowDown,
|
LineIcons.arrowDown,
|
||||||
AppColor.error,
|
AppColor.error,
|
||||||
),
|
),
|
||||||
@ -97,7 +88,7 @@ class FinanceCashFlow extends StatelessWidget {
|
|||||||
Expanded(
|
Expanded(
|
||||||
child: _buildCashFlowIndicator(
|
child: _buildCashFlowIndicator(
|
||||||
'Net Flow',
|
'Net Flow',
|
||||||
_formatCurrency(netFlow),
|
'Rp 7.3M',
|
||||||
LineIcons.equals,
|
LineIcons.equals,
|
||||||
AppColor.info,
|
AppColor.info,
|
||||||
),
|
),
|
||||||
@ -119,7 +110,7 @@ class FinanceCashFlow extends StatelessWidget {
|
|||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
'Grafik Cash Flow ${dailyData.length} Hari Terakhir',
|
'Grafik Cash Flow 7 Hari Terakhir',
|
||||||
style: AppStyle.sm.copyWith(
|
style: AppStyle.sm.copyWith(
|
||||||
color: AppColor.textSecondary,
|
color: AppColor.textSecondary,
|
||||||
fontWeight: FontWeight.w600,
|
fontWeight: FontWeight.w600,
|
||||||
@ -127,9 +118,207 @@ class FinanceCashFlow extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
const SizedBox(height: 16),
|
const SizedBox(height: 16),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: dailyData.isEmpty
|
child: LineChart(
|
||||||
? _buildEmptyChart()
|
LineChartData(
|
||||||
: LineChart(_buildLineChartData()),
|
gridData: FlGridData(
|
||||||
|
show: true,
|
||||||
|
drawVerticalLine: false,
|
||||||
|
horizontalInterval: 5000000, // 5M interval
|
||||||
|
getDrawingHorizontalLine: (value) {
|
||||||
|
return FlLine(
|
||||||
|
color: AppColor.borderLight,
|
||||||
|
strokeWidth: 1,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
titlesData: FlTitlesData(
|
||||||
|
show: true,
|
||||||
|
rightTitles: AxisTitles(
|
||||||
|
sideTitles: SideTitles(showTitles: false),
|
||||||
|
),
|
||||||
|
topTitles: AxisTitles(
|
||||||
|
sideTitles: SideTitles(showTitles: false),
|
||||||
|
),
|
||||||
|
bottomTitles: AxisTitles(
|
||||||
|
sideTitles: SideTitles(
|
||||||
|
showTitles: true,
|
||||||
|
reservedSize: 30,
|
||||||
|
interval: 1,
|
||||||
|
getTitlesWidget: (double value, TitleMeta meta) {
|
||||||
|
const style = TextStyle(
|
||||||
|
color: AppColor.textSecondary,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
fontSize: 10,
|
||||||
|
);
|
||||||
|
Widget text;
|
||||||
|
switch (value.toInt()) {
|
||||||
|
case 0:
|
||||||
|
text = const Text('Sen', style: style);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
text = const Text('Sel', style: style);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
text = const Text('Rab', style: style);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
text = const Text('Kam', style: style);
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
text = const Text('Jum', style: style);
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
text = const Text('Sab', style: style);
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
text = const Text('Min', style: style);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
text = const Text('', style: style);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return SideTitleWidget(meta: meta, child: text);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
leftTitles: AxisTitles(
|
||||||
|
sideTitles: SideTitles(
|
||||||
|
showTitles: true,
|
||||||
|
interval: 10000000, // 10M interval
|
||||||
|
reservedSize: 42,
|
||||||
|
getTitlesWidget: (double value, TitleMeta meta) {
|
||||||
|
return Text(
|
||||||
|
'${(value / 1000000).toInt()}M',
|
||||||
|
style: const TextStyle(
|
||||||
|
color: AppColor.textSecondary,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
fontSize: 10,
|
||||||
|
),
|
||||||
|
textAlign: TextAlign.left,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
borderData: FlBorderData(
|
||||||
|
show: true,
|
||||||
|
border: Border.all(color: AppColor.borderLight),
|
||||||
|
),
|
||||||
|
minX: 0,
|
||||||
|
maxX: 6,
|
||||||
|
minY: -5000000,
|
||||||
|
maxY: 30000000,
|
||||||
|
lineBarsData: [
|
||||||
|
// Cash In Line
|
||||||
|
LineChartBarData(
|
||||||
|
spots: const [
|
||||||
|
FlSpot(0, 25000000), // Monday
|
||||||
|
FlSpot(1, 22000000), // Tuesday
|
||||||
|
FlSpot(2, 28000000), // Wednesday
|
||||||
|
FlSpot(3, 24000000), // Thursday
|
||||||
|
FlSpot(4, 30000000), // Friday
|
||||||
|
FlSpot(5, 18000000), // Saturday
|
||||||
|
FlSpot(6, 26000000), // Sunday
|
||||||
|
],
|
||||||
|
isCurved: true,
|
||||||
|
gradient: LinearGradient(
|
||||||
|
colors: [
|
||||||
|
AppColor.success.withOpacity(0.8),
|
||||||
|
AppColor.success,
|
||||||
|
],
|
||||||
|
),
|
||||||
|
barWidth: 3,
|
||||||
|
isStrokeCapRound: true,
|
||||||
|
dotData: FlDotData(
|
||||||
|
show: true,
|
||||||
|
getDotPainter: (spot, percent, barData, index) {
|
||||||
|
return FlDotCirclePainter(
|
||||||
|
radius: 4,
|
||||||
|
color: AppColor.success,
|
||||||
|
strokeWidth: 2,
|
||||||
|
strokeColor: AppColor.white,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
belowBarData: BarAreaData(
|
||||||
|
show: true,
|
||||||
|
gradient: LinearGradient(
|
||||||
|
colors: [
|
||||||
|
AppColor.success.withOpacity(0.1),
|
||||||
|
AppColor.success.withOpacity(0.0),
|
||||||
|
],
|
||||||
|
begin: Alignment.topCenter,
|
||||||
|
end: Alignment.bottomCenter,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
// Cash Out Line
|
||||||
|
LineChartBarData(
|
||||||
|
spots: const [
|
||||||
|
FlSpot(0, 20000000), // Monday
|
||||||
|
FlSpot(1, 18000000), // Tuesday
|
||||||
|
FlSpot(2, 23000000), // Wednesday
|
||||||
|
FlSpot(3, 19000000), // Thursday
|
||||||
|
FlSpot(4, 25000000), // Friday
|
||||||
|
FlSpot(5, 15000000), // Saturday
|
||||||
|
FlSpot(6, 21000000), // Sunday
|
||||||
|
],
|
||||||
|
isCurved: true,
|
||||||
|
gradient: LinearGradient(
|
||||||
|
colors: [
|
||||||
|
AppColor.error.withOpacity(0.8),
|
||||||
|
AppColor.error,
|
||||||
|
],
|
||||||
|
),
|
||||||
|
barWidth: 3,
|
||||||
|
isStrokeCapRound: true,
|
||||||
|
dotData: FlDotData(
|
||||||
|
show: true,
|
||||||
|
getDotPainter: (spot, percent, barData, index) {
|
||||||
|
return FlDotCirclePainter(
|
||||||
|
radius: 4,
|
||||||
|
color: AppColor.error,
|
||||||
|
strokeWidth: 2,
|
||||||
|
strokeColor: AppColor.white,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
// Net Flow Line
|
||||||
|
LineChartBarData(
|
||||||
|
spots: const [
|
||||||
|
FlSpot(0, 5000000), // Monday
|
||||||
|
FlSpot(1, 4000000), // Tuesday
|
||||||
|
FlSpot(2, 5000000), // Wednesday
|
||||||
|
FlSpot(3, 5000000), // Thursday
|
||||||
|
FlSpot(4, 5000000), // Friday
|
||||||
|
FlSpot(5, 3000000), // Saturday
|
||||||
|
FlSpot(6, 5000000), // Sunday
|
||||||
|
],
|
||||||
|
isCurved: true,
|
||||||
|
gradient: LinearGradient(
|
||||||
|
colors: [
|
||||||
|
AppColor.info.withOpacity(0.8),
|
||||||
|
AppColor.info,
|
||||||
|
],
|
||||||
|
),
|
||||||
|
barWidth: 3,
|
||||||
|
isStrokeCapRound: true,
|
||||||
|
dotData: FlDotData(
|
||||||
|
show: true,
|
||||||
|
getDotPainter: (spot, percent, barData, index) {
|
||||||
|
return FlDotCirclePainter(
|
||||||
|
radius: 4,
|
||||||
|
color: AppColor.info,
|
||||||
|
strokeWidth: 2,
|
||||||
|
strokeColor: AppColor.white,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 12),
|
const SizedBox(height: 12),
|
||||||
// Legend
|
// Legend
|
||||||
@ -151,273 +340,6 @@ class FinanceCashFlow extends StatelessWidget {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
LineChartData _buildLineChartData() {
|
|
||||||
final maxValue = _getMaxChartValue();
|
|
||||||
final minValue = _getMinChartValue();
|
|
||||||
|
|
||||||
return LineChartData(
|
|
||||||
gridData: FlGridData(
|
|
||||||
show: true,
|
|
||||||
drawVerticalLine: false,
|
|
||||||
horizontalInterval: (maxValue / 5).roundToDouble(),
|
|
||||||
getDrawingHorizontalLine: (value) {
|
|
||||||
return FlLine(color: AppColor.borderLight, strokeWidth: 1);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
titlesData: FlTitlesData(
|
|
||||||
show: true,
|
|
||||||
rightTitles: AxisTitles(sideTitles: SideTitles(showTitles: false)),
|
|
||||||
topTitles: AxisTitles(sideTitles: SideTitles(showTitles: false)),
|
|
||||||
bottomTitles: AxisTitles(
|
|
||||||
sideTitles: SideTitles(
|
|
||||||
showTitles: true,
|
|
||||||
reservedSize: 30,
|
|
||||||
interval: 1,
|
|
||||||
getTitlesWidget: (double value, TitleMeta meta) {
|
|
||||||
final index = value.toInt();
|
|
||||||
if (index >= 0 && index < dailyData.length) {
|
|
||||||
final date = DateTime.parse(dailyData[index].date);
|
|
||||||
final dayName = _getDayName(date.weekday);
|
|
||||||
return SideTitleWidget(
|
|
||||||
meta: meta,
|
|
||||||
child: Text(
|
|
||||||
dayName,
|
|
||||||
style: const TextStyle(
|
|
||||||
color: AppColor.textSecondary,
|
|
||||||
fontWeight: FontWeight.w500,
|
|
||||||
fontSize: 10,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return SideTitleWidget(meta: meta, child: Text(''));
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
leftTitles: AxisTitles(
|
|
||||||
sideTitles: SideTitles(
|
|
||||||
showTitles: true,
|
|
||||||
interval: (maxValue / 3).roundToDouble(),
|
|
||||||
reservedSize: 42,
|
|
||||||
getTitlesWidget: (double value, TitleMeta meta) {
|
|
||||||
return Text(
|
|
||||||
_formatChartValue(value),
|
|
||||||
style: const TextStyle(
|
|
||||||
color: AppColor.textSecondary,
|
|
||||||
fontWeight: FontWeight.w500,
|
|
||||||
fontSize: 10,
|
|
||||||
),
|
|
||||||
textAlign: TextAlign.left,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
borderData: FlBorderData(
|
|
||||||
show: true,
|
|
||||||
border: Border.all(color: AppColor.borderLight),
|
|
||||||
),
|
|
||||||
minX: 0,
|
|
||||||
maxX: (dailyData.length - 1).toDouble(),
|
|
||||||
minY: minValue,
|
|
||||||
maxY: maxValue,
|
|
||||||
lineBarsData: [
|
|
||||||
// Cash In Line (Revenue)
|
|
||||||
LineChartBarData(
|
|
||||||
spots: _buildCashInSpots(),
|
|
||||||
isCurved: true,
|
|
||||||
gradient: LinearGradient(
|
|
||||||
colors: [AppColor.success.withOpacity(0.8), AppColor.success],
|
|
||||||
),
|
|
||||||
barWidth: 3,
|
|
||||||
isStrokeCapRound: true,
|
|
||||||
dotData: FlDotData(
|
|
||||||
show: true,
|
|
||||||
getDotPainter: (spot, percent, barData, index) {
|
|
||||||
return FlDotCirclePainter(
|
|
||||||
radius: 4,
|
|
||||||
color: AppColor.success,
|
|
||||||
strokeWidth: 2,
|
|
||||||
strokeColor: AppColor.white,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
belowBarData: BarAreaData(
|
|
||||||
show: true,
|
|
||||||
gradient: LinearGradient(
|
|
||||||
colors: [
|
|
||||||
AppColor.success.withOpacity(0.1),
|
|
||||||
AppColor.success.withOpacity(0.0),
|
|
||||||
],
|
|
||||||
begin: Alignment.topCenter,
|
|
||||||
end: Alignment.bottomCenter,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
// Cash Out Line (Total Cost)
|
|
||||||
LineChartBarData(
|
|
||||||
spots: _buildCashOutSpots(),
|
|
||||||
isCurved: true,
|
|
||||||
gradient: LinearGradient(
|
|
||||||
colors: [AppColor.error.withOpacity(0.8), AppColor.error],
|
|
||||||
),
|
|
||||||
barWidth: 3,
|
|
||||||
isStrokeCapRound: true,
|
|
||||||
dotData: FlDotData(
|
|
||||||
show: true,
|
|
||||||
getDotPainter: (spot, percent, barData, index) {
|
|
||||||
return FlDotCirclePainter(
|
|
||||||
radius: 4,
|
|
||||||
color: AppColor.error,
|
|
||||||
strokeWidth: 2,
|
|
||||||
strokeColor: AppColor.white,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
// Net Flow Line (Net Profit)
|
|
||||||
LineChartBarData(
|
|
||||||
spots: _buildNetFlowSpots(),
|
|
||||||
isCurved: true,
|
|
||||||
gradient: LinearGradient(
|
|
||||||
colors: [AppColor.info.withOpacity(0.8), AppColor.info],
|
|
||||||
),
|
|
||||||
barWidth: 3,
|
|
||||||
isStrokeCapRound: true,
|
|
||||||
dotData: FlDotData(
|
|
||||||
show: true,
|
|
||||||
getDotPainter: (spot, percent, barData, index) {
|
|
||||||
return FlDotCirclePainter(
|
|
||||||
radius: 4,
|
|
||||||
color: AppColor.info,
|
|
||||||
strokeWidth: 2,
|
|
||||||
strokeColor: AppColor.white,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _buildEmptyChart() {
|
|
||||||
return Center(
|
|
||||||
child: Column(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
|
||||||
children: [
|
|
||||||
Icon(
|
|
||||||
LineIcons.lineChart,
|
|
||||||
size: 48,
|
|
||||||
color: AppColor.textSecondary.withOpacity(0.3),
|
|
||||||
),
|
|
||||||
const SizedBox(height: 12),
|
|
||||||
Text(
|
|
||||||
'Tidak ada data untuk ditampilkan',
|
|
||||||
style: AppStyle.sm.copyWith(color: AppColor.textSecondary),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Helper methods for calculating data
|
|
||||||
int _calculateTotalCashIn() {
|
|
||||||
return dailyData.fold(0, (sum, data) => sum + data.revenue);
|
|
||||||
}
|
|
||||||
|
|
||||||
int _calculateTotalCashOut() {
|
|
||||||
return dailyData.fold(
|
|
||||||
0,
|
|
||||||
(sum, data) => sum + data.cost + data.tax + data.discount,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
double _getMaxChartValue() {
|
|
||||||
if (dailyData.isEmpty) return 30000000;
|
|
||||||
|
|
||||||
final maxRevenue = dailyData
|
|
||||||
.map((e) => e.revenue)
|
|
||||||
.reduce((a, b) => a > b ? a : b);
|
|
||||||
final maxCost = dailyData
|
|
||||||
.map((e) => e.cost + e.tax + e.discount)
|
|
||||||
.reduce((a, b) => a > b ? a : b);
|
|
||||||
final maxValue = maxRevenue > maxCost ? maxRevenue : maxCost;
|
|
||||||
|
|
||||||
return (maxValue * 1.2).toDouble(); // Add 20% padding
|
|
||||||
}
|
|
||||||
|
|
||||||
double _getMinChartValue() {
|
|
||||||
if (dailyData.isEmpty) return -5000000;
|
|
||||||
|
|
||||||
final minNetProfit = dailyData
|
|
||||||
.map((e) => e.netProfit)
|
|
||||||
.reduce((a, b) => a < b ? a : b);
|
|
||||||
return minNetProfit < 0 ? (minNetProfit * 1.2).toDouble() : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
List<FlSpot> _buildCashInSpots() {
|
|
||||||
return dailyData.asMap().entries.map((entry) {
|
|
||||||
return FlSpot(entry.key.toDouble(), entry.value.revenue.toDouble());
|
|
||||||
}).toList();
|
|
||||||
}
|
|
||||||
|
|
||||||
List<FlSpot> _buildCashOutSpots() {
|
|
||||||
return dailyData.asMap().entries.map((entry) {
|
|
||||||
final totalCost =
|
|
||||||
entry.value.cost + entry.value.tax + entry.value.discount;
|
|
||||||
return FlSpot(entry.key.toDouble(), totalCost.toDouble());
|
|
||||||
}).toList();
|
|
||||||
}
|
|
||||||
|
|
||||||
List<FlSpot> _buildNetFlowSpots() {
|
|
||||||
return dailyData.asMap().entries.map((entry) {
|
|
||||||
return FlSpot(entry.key.toDouble(), entry.value.netProfit.toDouble());
|
|
||||||
}).toList();
|
|
||||||
}
|
|
||||||
|
|
||||||
String _getDayName(int weekday) {
|
|
||||||
switch (weekday) {
|
|
||||||
case 1:
|
|
||||||
return 'Sen';
|
|
||||||
case 2:
|
|
||||||
return 'Sel';
|
|
||||||
case 3:
|
|
||||||
return 'Rab';
|
|
||||||
case 4:
|
|
||||||
return 'Kam';
|
|
||||||
case 5:
|
|
||||||
return 'Jum';
|
|
||||||
case 6:
|
|
||||||
return 'Sab';
|
|
||||||
case 7:
|
|
||||||
return 'Min';
|
|
||||||
default:
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
String _formatChartValue(double value) {
|
|
||||||
if (value.abs() >= 1000000) {
|
|
||||||
return '${(value / 1000000).toStringAsFixed(0)}M';
|
|
||||||
} else if (value.abs() >= 1000) {
|
|
||||||
return '${(value / 1000).toStringAsFixed(0)}K';
|
|
||||||
} else {
|
|
||||||
return value.toStringAsFixed(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
String _formatCurrency(int amount) {
|
|
||||||
if (amount.abs() >= 1000000000) {
|
|
||||||
return 'Rp ${(amount / 1000000000).toStringAsFixed(1)}B';
|
|
||||||
} else if (amount.abs() >= 1000000) {
|
|
||||||
return 'Rp ${(amount / 1000000).toStringAsFixed(1)}M';
|
|
||||||
} else if (amount.abs() >= 1000) {
|
|
||||||
return 'Rp ${(amount / 1000).toStringAsFixed(1)}K';
|
|
||||||
} else {
|
|
||||||
return 'Rp ${NumberFormat('#,###', 'id_ID').format(amount)}';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _buildChartLegend(String label, Color color) {
|
Widget _buildChartLegend(String label, Color color) {
|
||||||
return Row(
|
return Row(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
|||||||
@ -1,21 +1,33 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:line_icons/line_icons.dart';
|
import 'package:line_icons/line_icons.dart';
|
||||||
import 'package:intl/intl.dart';
|
|
||||||
|
|
||||||
import '../../../../common/extension/extension.dart';
|
|
||||||
import '../../../../common/theme/theme.dart';
|
import '../../../../common/theme/theme.dart';
|
||||||
import '../../../../domain/analytic/analytic.dart';
|
|
||||||
import '../../../components/widgets/empty_widget.dart';
|
|
||||||
|
|
||||||
class FinanceCategory extends StatelessWidget {
|
class FinanceCategory extends StatelessWidget {
|
||||||
final List<CategoryAnalyticItem> categories;
|
const FinanceCategory({super.key});
|
||||||
|
|
||||||
const FinanceCategory({super.key, required this.categories});
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final totalRevenue = _calculateTotalRevenue();
|
final categories = [
|
||||||
final sortedCategories = _sortCategoriesByRevenue();
|
{
|
||||||
|
'name': 'Makanan & Minuman',
|
||||||
|
'amount': 'Rp 18.5M',
|
||||||
|
'percentage': 72,
|
||||||
|
'color': AppColor.primary,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'name': 'Produk Retail',
|
||||||
|
'amount': 'Rp 4.2M',
|
||||||
|
'percentage': 16,
|
||||||
|
'color': AppColor.secondary,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'name': 'Jasa & Lainnya',
|
||||||
|
'amount': 'Rp 3.1M',
|
||||||
|
'percentage': 12,
|
||||||
|
'color': AppColor.info,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
return Container(
|
return Container(
|
||||||
margin: const EdgeInsets.all(16),
|
margin: const EdgeInsets.all(16),
|
||||||
@ -58,25 +70,25 @@ class FinanceCategory extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
const SizedBox(height: 20),
|
const SizedBox(height: 20),
|
||||||
|
|
||||||
// Show empty state if no categories
|
...categories
|
||||||
if (categories.isEmpty)
|
.map(
|
||||||
_buildEmptyState()
|
(category) => _buildCategoryItem(
|
||||||
else
|
category['name'] as String,
|
||||||
...sortedCategories.asMap().entries.map(
|
category['amount'] as String,
|
||||||
(entry) => _buildCategoryItem(
|
category['percentage'] as int,
|
||||||
entry.value,
|
category['color'] as Color,
|
||||||
_calculatePercentage(entry.value.totalRevenue, totalRevenue),
|
),
|
||||||
_getCategoryColor(entry.key),
|
)
|
||||||
),
|
.toList(),
|
||||||
),
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildCategoryItem(
|
Widget _buildCategoryItem(
|
||||||
CategoryAnalyticItem category,
|
String name,
|
||||||
double percentage,
|
String amount,
|
||||||
|
int percentage,
|
||||||
Color color,
|
Color color,
|
||||||
) {
|
) {
|
||||||
return Container(
|
return Container(
|
||||||
@ -86,59 +98,30 @@ class FinanceCategory extends StatelessWidget {
|
|||||||
Row(
|
Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
children: [
|
children: [
|
||||||
Expanded(
|
Row(
|
||||||
child: Row(
|
|
||||||
children: [
|
|
||||||
Container(
|
|
||||||
width: 12,
|
|
||||||
height: 12,
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: color,
|
|
||||||
borderRadius: BorderRadius.circular(6),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(width: 12),
|
|
||||||
Expanded(
|
|
||||||
child: Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
category.categoryName,
|
|
||||||
style: AppStyle.md.copyWith(
|
|
||||||
fontWeight: FontWeight.w600,
|
|
||||||
),
|
|
||||||
overflow: TextOverflow.ellipsis,
|
|
||||||
),
|
|
||||||
const SizedBox(height: 2),
|
|
||||||
Text(
|
|
||||||
'${category.productCount} produk • ${category.orderCount} pesanan',
|
|
||||||
style: AppStyle.xs.copyWith(
|
|
||||||
color: AppColor.textSecondary,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(width: 12),
|
|
||||||
Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.end,
|
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Container(
|
||||||
category.totalRevenue.currencyFormatRp,
|
width: 12,
|
||||||
style: AppStyle.md.copyWith(
|
height: 12,
|
||||||
fontWeight: FontWeight.bold,
|
decoration: BoxDecoration(
|
||||||
color: color,
|
color: color,
|
||||||
|
borderRadius: BorderRadius.circular(6),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
const SizedBox(width: 12),
|
||||||
Text(
|
Text(
|
||||||
'${NumberFormat('#,###', 'id_ID').format(category.totalQuantity)} unit',
|
name,
|
||||||
style: AppStyle.xs.copyWith(color: AppColor.textSecondary),
|
style: AppStyle.md.copyWith(fontWeight: FontWeight.w600),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
Text(
|
||||||
|
amount,
|
||||||
|
style: AppStyle.md.copyWith(
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
color: color,
|
||||||
|
),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
const SizedBox(height: 8),
|
const SizedBox(height: 8),
|
||||||
@ -152,7 +135,7 @@ class FinanceCategory extends StatelessWidget {
|
|||||||
Align(
|
Align(
|
||||||
alignment: Alignment.centerRight,
|
alignment: Alignment.centerRight,
|
||||||
child: Text(
|
child: Text(
|
||||||
'${percentage.toStringAsFixed(1)}%',
|
'$percentage%',
|
||||||
style: AppStyle.xs.copyWith(color: AppColor.textSecondary),
|
style: AppStyle.xs.copyWith(color: AppColor.textSecondary),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -160,48 +143,4 @@ class FinanceCategory extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildEmptyState() {
|
|
||||||
return EmptyWidget(
|
|
||||||
title: 'Belum ada data kategori',
|
|
||||||
message: 'Data kategori penjualan akan muncul di sini',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Helper methods
|
|
||||||
int _calculateTotalRevenue() {
|
|
||||||
return categories.fold(0, (sum, category) => sum + category.totalRevenue);
|
|
||||||
}
|
|
||||||
|
|
||||||
List<CategoryAnalyticItem> _sortCategoriesByRevenue() {
|
|
||||||
final sorted = List<CategoryAnalyticItem>.from(categories);
|
|
||||||
sorted.sort((a, b) => b.totalRevenue.compareTo(a.totalRevenue));
|
|
||||||
return sorted;
|
|
||||||
}
|
|
||||||
|
|
||||||
double _calculatePercentage(int categoryRevenue, int totalRevenue) {
|
|
||||||
if (totalRevenue == 0) return 0;
|
|
||||||
return (categoryRevenue / totalRevenue) * 100;
|
|
||||||
}
|
|
||||||
|
|
||||||
Color _getCategoryColor(int index) {
|
|
||||||
// Predefined color palette for categories
|
|
||||||
const colors = [
|
|
||||||
AppColor.primary,
|
|
||||||
AppColor.secondary,
|
|
||||||
AppColor.success,
|
|
||||||
AppColor.warning,
|
|
||||||
AppColor.error,
|
|
||||||
AppColor.info,
|
|
||||||
];
|
|
||||||
|
|
||||||
// Generate additional colors if needed
|
|
||||||
if (index < colors.length) {
|
|
||||||
return colors[index];
|
|
||||||
} else {
|
|
||||||
// Generate colors based on index for unlimited categories
|
|
||||||
final hue = (index * 137.5) % 360; // Golden angle approximation
|
|
||||||
return HSLColor.fromAHSL(1.0, hue, 0.7, 0.5).toColor();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,148 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
|
|
||||||
import '../../../../common/extension/extension.dart';
|
|
||||||
import '../../../../common/theme/theme.dart';
|
|
||||||
import '../../../../domain/analytic/analytic.dart';
|
|
||||||
|
|
||||||
class ProfitLossProduct extends StatelessWidget {
|
|
||||||
final ProfitLossProductData product;
|
|
||||||
const ProfitLossProduct({super.key, required this.product});
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return Container(
|
|
||||||
padding: const EdgeInsets.all(16),
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: AppColor.background,
|
|
||||||
borderRadius: BorderRadius.circular(12),
|
|
||||||
border: Border.all(color: AppColor.border.withOpacity(0.5)),
|
|
||||||
),
|
|
||||||
child: Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
// Product header
|
|
||||||
Row(
|
|
||||||
children: [
|
|
||||||
Expanded(
|
|
||||||
child: Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
product.productName,
|
|
||||||
style: AppStyle.md.copyWith(fontWeight: FontWeight.bold),
|
|
||||||
maxLines: 2,
|
|
||||||
overflow: TextOverflow.ellipsis,
|
|
||||||
),
|
|
||||||
const SizedBox(height: 2),
|
|
||||||
Container(
|
|
||||||
padding: const EdgeInsets.symmetric(
|
|
||||||
horizontal: 8,
|
|
||||||
vertical: 2,
|
|
||||||
),
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: AppColor.primary.withOpacity(0.1),
|
|
||||||
borderRadius: BorderRadius.circular(8),
|
|
||||||
),
|
|
||||||
child: Text(
|
|
||||||
product.categoryName,
|
|
||||||
style: AppStyle.xs.copyWith(color: AppColor.primary),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(width: 12),
|
|
||||||
Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.end,
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
'${product.quantitySold} terjual',
|
|
||||||
style: AppStyle.sm.copyWith(color: AppColor.textSecondary),
|
|
||||||
),
|
|
||||||
Text(
|
|
||||||
'${product.grossProfitMargin.toStringAsFixed(1)}%',
|
|
||||||
style: AppStyle.md.copyWith(
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
color: product.grossProfitMargin > 25
|
|
||||||
? AppColor.success
|
|
||||||
: product.grossProfitMargin > 15
|
|
||||||
? AppColor.warning
|
|
||||||
: AppColor.error,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
const SizedBox(height: 16),
|
|
||||||
|
|
||||||
// Financial metrics
|
|
||||||
Row(
|
|
||||||
children: [
|
|
||||||
Expanded(
|
|
||||||
child: _buildMetricColumn(
|
|
||||||
'Pendapatan',
|
|
||||||
product.revenue.currencyFormatRp,
|
|
||||||
AppColor.success,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Expanded(
|
|
||||||
child: _buildMetricColumn(
|
|
||||||
'Biaya',
|
|
||||||
product.cost.currencyFormatRp,
|
|
||||||
AppColor.error,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Expanded(
|
|
||||||
child: _buildMetricColumn(
|
|
||||||
'Laba Kotor',
|
|
||||||
product.grossProfit.currencyFormatRp,
|
|
||||||
AppColor.info,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
const SizedBox(height: 12),
|
|
||||||
|
|
||||||
// Average metrics
|
|
||||||
Row(
|
|
||||||
children: [
|
|
||||||
Expanded(
|
|
||||||
child: _buildMetricColumn(
|
|
||||||
'Harga Rata-rata',
|
|
||||||
product.averagePrice.currencyFormatRp,
|
|
||||||
AppColor.textSecondary,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Expanded(
|
|
||||||
child: _buildMetricColumn(
|
|
||||||
'Laba per Unit',
|
|
||||||
product.profitPerUnit.currencyFormatRp,
|
|
||||||
AppColor.primary,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const Expanded(child: SizedBox()),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _buildMetricColumn(String label, String value, Color color) {
|
|
||||||
return Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
Text(label, style: AppStyle.xs.copyWith(color: AppColor.textSecondary)),
|
|
||||||
const SizedBox(height: 2),
|
|
||||||
Text(
|
|
||||||
value,
|
|
||||||
style: AppStyle.sm.copyWith(
|
|
||||||
fontWeight: FontWeight.w600,
|
|
||||||
color: color,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,14 +1,10 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:line_icons/line_icons.dart';
|
import 'package:line_icons/line_icons.dart';
|
||||||
|
|
||||||
import '../../../../common/extension/extension.dart';
|
|
||||||
import '../../../../common/theme/theme.dart';
|
import '../../../../common/theme/theme.dart';
|
||||||
import '../../../../domain/analytic/analytic.dart';
|
|
||||||
|
|
||||||
class FinanceProfitLoss extends StatelessWidget {
|
class FinanceProfitLoss extends StatelessWidget {
|
||||||
final ProfitLossSummary data;
|
const FinanceProfitLoss({super.key});
|
||||||
|
|
||||||
const FinanceProfitLoss({super.key, required this.data});
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@ -53,77 +49,52 @@ class FinanceProfitLoss extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
const SizedBox(height: 20),
|
const SizedBox(height: 20),
|
||||||
|
|
||||||
// Total Revenue (Penjualan Kotor)
|
|
||||||
_buildPLItem(
|
_buildPLItem(
|
||||||
'Penjualan Kotor',
|
'Penjualan Kotor',
|
||||||
data.totalRevenue.currencyFormatRp,
|
'Rp 25.840.000',
|
||||||
AppColor.success,
|
AppColor.success,
|
||||||
true,
|
true,
|
||||||
),
|
),
|
||||||
|
_buildPLItem('Diskon & Retur', '- Rp 560.000', AppColor.error, false),
|
||||||
// Discount (Diskon & Retur)
|
|
||||||
_buildPLItem(
|
|
||||||
'Diskon & Retur',
|
|
||||||
'- ${data.totalDiscount.currencyFormatRp}',
|
|
||||||
AppColor.error,
|
|
||||||
false,
|
|
||||||
),
|
|
||||||
|
|
||||||
const Divider(height: 24),
|
const Divider(height: 24),
|
||||||
|
|
||||||
// Net Sales (Penjualan Bersih = Total Revenue - Discount)
|
|
||||||
_buildPLItem(
|
_buildPLItem(
|
||||||
'Penjualan Bersih',
|
'Penjualan Bersih',
|
||||||
(data.totalRevenue - data.totalDiscount).currencyFormatRp,
|
'Rp 25.280.000',
|
||||||
AppColor.textPrimary,
|
AppColor.textPrimary,
|
||||||
true,
|
true,
|
||||||
isHeader: true,
|
isHeader: true,
|
||||||
),
|
),
|
||||||
|
|
||||||
const SizedBox(height: 12),
|
const SizedBox(height: 12),
|
||||||
|
|
||||||
// Cost of Goods Sold (HPP)
|
|
||||||
_buildPLItem(
|
_buildPLItem(
|
||||||
'HPP (Harga Pokok Penjualan)',
|
'HPP (Harga Pokok Penjualan)',
|
||||||
'- ${data.totalCost.currencyFormatRp}',
|
'- Rp 15.120.000',
|
||||||
AppColor.error,
|
AppColor.error,
|
||||||
false,
|
false,
|
||||||
),
|
),
|
||||||
|
|
||||||
const Divider(height: 24),
|
const Divider(height: 24),
|
||||||
|
|
||||||
// Gross Profit (Laba Kotor)
|
|
||||||
_buildPLItem(
|
_buildPLItem(
|
||||||
'Laba Kotor',
|
'Laba Kotor',
|
||||||
data.grossProfit.currencyFormatRp,
|
'Rp 10.160.000',
|
||||||
AppColor.success,
|
AppColor.success,
|
||||||
true,
|
true,
|
||||||
isHeader: true,
|
isHeader: true,
|
||||||
showPercentage: true,
|
|
||||||
percentage: '${data.grossProfitMargin.toStringAsFixed(1)}%',
|
|
||||||
),
|
),
|
||||||
|
|
||||||
const SizedBox(height: 12),
|
const SizedBox(height: 12),
|
||||||
|
|
||||||
// Operational Cost (Biaya Operasional) - calculated as difference
|
|
||||||
_buildPLItem(
|
_buildPLItem(
|
||||||
'Biaya Operasional',
|
'Biaya Operasional',
|
||||||
'- ${_calculateOperationalCost().currencyFormatRp}',
|
'- Rp 2.640.000',
|
||||||
AppColor.error,
|
AppColor.error,
|
||||||
false,
|
false,
|
||||||
),
|
),
|
||||||
|
|
||||||
const Divider(height: 24),
|
const Divider(height: 24),
|
||||||
|
|
||||||
// Net Profit (Laba Bersih)
|
|
||||||
_buildPLItem(
|
_buildPLItem(
|
||||||
'Laba Bersih',
|
'Laba Bersih',
|
||||||
data.netProfit.currencyFormatRp,
|
'Rp 7.520.000',
|
||||||
AppColor.primary,
|
AppColor.primary,
|
||||||
true,
|
true,
|
||||||
isHeader: true,
|
isHeader: true,
|
||||||
showPercentage: true,
|
showPercentage: true,
|
||||||
percentage: '${data.netProfitMargin.round()}%',
|
percentage: '29.8%',
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@ -184,9 +155,4 @@ class FinanceProfitLoss extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate operational cost as the difference between gross profit and net profit
|
|
||||||
int _calculateOperationalCost() {
|
|
||||||
return data.grossProfit - data.netProfit - data.totalTax;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,6 +9,7 @@ class FinanceSummaryCard extends StatelessWidget {
|
|||||||
required this.amount,
|
required this.amount,
|
||||||
required this.icon,
|
required this.icon,
|
||||||
required this.color,
|
required this.color,
|
||||||
|
required this.change,
|
||||||
required this.isPositive,
|
required this.isPositive,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -16,6 +17,7 @@ class FinanceSummaryCard extends StatelessWidget {
|
|||||||
final String amount;
|
final String amount;
|
||||||
final IconData icon;
|
final IconData icon;
|
||||||
final Color color;
|
final Color color;
|
||||||
|
final String change;
|
||||||
final bool isPositive;
|
final bool isPositive;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -48,6 +50,22 @@ class FinanceSummaryCard extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
child: Icon(icon, color: color, size: 20),
|
child: Icon(icon, color: color, size: 20),
|
||||||
),
|
),
|
||||||
|
Container(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: isPositive
|
||||||
|
? AppColor.success.withOpacity(0.1)
|
||||||
|
: AppColor.error.withOpacity(0.1),
|
||||||
|
borderRadius: BorderRadius.circular(12),
|
||||||
|
),
|
||||||
|
child: Text(
|
||||||
|
change,
|
||||||
|
style: AppStyle.xs.copyWith(
|
||||||
|
color: isPositive ? AppColor.success : AppColor.error,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
const SizedBox(height: 12),
|
const SizedBox(height: 12),
|
||||||
|
|||||||
@ -1,13 +1,9 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
|
||||||
import 'dart:math' as math;
|
import 'dart:math' as math;
|
||||||
|
|
||||||
import '../../../../application/auth/auth_bloc.dart';
|
|
||||||
import '../../../../common/constant/app_constant.dart';
|
|
||||||
import '../../../../common/extension/extension.dart';
|
import '../../../../common/extension/extension.dart';
|
||||||
import '../../../../common/painter/wave_painter.dart';
|
import '../../../../common/painter/wave_painter.dart';
|
||||||
import '../../../../common/theme/theme.dart';
|
import '../../../../common/theme/theme.dart';
|
||||||
import '../../../../domain/auth/auth.dart';
|
|
||||||
import '../../../components/spacer/spacer.dart';
|
import '../../../components/spacer/spacer.dart';
|
||||||
|
|
||||||
class HomeHeader extends StatefulWidget {
|
class HomeHeader extends StatefulWidget {
|
||||||
@ -106,47 +102,43 @@ class _HomeHeaderState extends State<HomeHeader> with TickerProviderStateMixin {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return BlocBuilder<AuthBloc, AuthState>(
|
return AnimatedBuilder(
|
||||||
builder: (context, state) {
|
animation: Listenable.merge([
|
||||||
return AnimatedBuilder(
|
_particleController,
|
||||||
animation: Listenable.merge([
|
_waveController,
|
||||||
_particleController,
|
_breathController,
|
||||||
_waveController,
|
]),
|
||||||
_breathController,
|
builder: (context, child) {
|
||||||
]),
|
return Container(
|
||||||
builder: (context, child) {
|
height: 280,
|
||||||
return Container(
|
decoration: BoxDecoration(
|
||||||
height: 280,
|
gradient: LinearGradient(
|
||||||
decoration: BoxDecoration(
|
colors: [
|
||||||
gradient: LinearGradient(
|
AppColor.primary,
|
||||||
colors: [
|
AppColor.primaryLight,
|
||||||
AppColor.primary,
|
AppColor.primaryLight.withOpacity(0.8),
|
||||||
AppColor.primaryLight,
|
],
|
||||||
AppColor.primaryLight.withOpacity(0.8),
|
begin: Alignment.topLeft,
|
||||||
],
|
end: Alignment.bottomRight,
|
||||||
begin: Alignment.topLeft,
|
stops: const [0.0, 0.7, 1.0],
|
||||||
end: Alignment.bottomRight,
|
),
|
||||||
stops: const [0.0, 0.7, 1.0],
|
boxShadow: [
|
||||||
),
|
BoxShadow(
|
||||||
boxShadow: [
|
color: AppColor.primary.withOpacity(0.3),
|
||||||
BoxShadow(
|
blurRadius: 20,
|
||||||
color: AppColor.primary.withOpacity(0.3),
|
offset: const Offset(0, 10),
|
||||||
blurRadius: 20,
|
|
||||||
offset: const Offset(0, 10),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
child: Stack(
|
],
|
||||||
children: [
|
),
|
||||||
// Enhanced animated background
|
child: Stack(
|
||||||
_buildAnimatedBackground(),
|
children: [
|
||||||
|
// Enhanced animated background
|
||||||
|
_buildAnimatedBackground(),
|
||||||
|
|
||||||
// Main content
|
// Main content
|
||||||
SafeArea(child: _buildContent(context, state.user)),
|
SafeArea(child: _buildContent(context)),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
|
||||||
},
|
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
@ -263,7 +255,7 @@ class _HomeHeaderState extends State<HomeHeader> with TickerProviderStateMixin {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildContent(BuildContext context, User user) {
|
Widget _buildContent(BuildContext context) {
|
||||||
String greeting(BuildContext context) {
|
String greeting(BuildContext context) {
|
||||||
final hour = DateTime.now().hour;
|
final hour = DateTime.now().hour;
|
||||||
|
|
||||||
@ -299,7 +291,7 @@ class _HomeHeaderState extends State<HomeHeader> with TickerProviderStateMixin {
|
|||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
AppConstant.appName,
|
'AppSkel POS Owner',
|
||||||
style: AppStyle.lg.copyWith(
|
style: AppStyle.lg.copyWith(
|
||||||
color: AppColor.white.withOpacity(0.9),
|
color: AppColor.white.withOpacity(0.9),
|
||||||
fontWeight: FontWeight.w600,
|
fontWeight: FontWeight.w600,
|
||||||
@ -315,7 +307,7 @@ class _HomeHeaderState extends State<HomeHeader> with TickerProviderStateMixin {
|
|||||||
),
|
),
|
||||||
const SpaceHeight(2),
|
const SpaceHeight(2),
|
||||||
Text(
|
Text(
|
||||||
user.role.toTitleCase,
|
'Manager',
|
||||||
style: AppStyle.sm.copyWith(
|
style: AppStyle.sm.copyWith(
|
||||||
color: AppColor.white.withOpacity(0.7),
|
color: AppColor.white.withOpacity(0.7),
|
||||||
fontSize: 11,
|
fontSize: 11,
|
||||||
@ -391,7 +383,7 @@ class _HomeHeaderState extends State<HomeHeader> with TickerProviderStateMixin {
|
|||||||
),
|
),
|
||||||
const SpaceHeight(2),
|
const SpaceHeight(2),
|
||||||
Text(
|
Text(
|
||||||
'${user.name}! đź‘‹',
|
'Vira Vania! đź‘‹',
|
||||||
style: AppStyle.h4.copyWith(
|
style: AppStyle.h4.copyWith(
|
||||||
color: AppColor.white,
|
color: AppColor.white,
|
||||||
fontWeight: FontWeight.w800,
|
fontWeight: FontWeight.w800,
|
||||||
|
|||||||
@ -1,53 +1,130 @@
|
|||||||
import 'package:auto_route/auto_route.dart';
|
import 'package:auto_route/auto_route.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
|
||||||
import 'package:line_icons/line_icons.dart';
|
import 'package:line_icons/line_icons.dart';
|
||||||
import 'package:shimmer/shimmer.dart';
|
|
||||||
|
|
||||||
import '../../../application/category/category_loader/category_loader_bloc.dart';
|
|
||||||
import '../../../application/product/product_loader/product_loader_bloc.dart';
|
|
||||||
import '../../../common/theme/theme.dart';
|
import '../../../common/theme/theme.dart';
|
||||||
import '../../../domain/category/category.dart';
|
|
||||||
import '../../../domain/product/product.dart';
|
|
||||||
import '../../../injection.dart';
|
|
||||||
import '../../components/appbar/appbar.dart';
|
import '../../components/appbar/appbar.dart';
|
||||||
import '../../components/button/button.dart';
|
import '../../components/button/button.dart';
|
||||||
import '../../components/widgets/empty_widget.dart';
|
|
||||||
import 'widgets/category_delegate.dart';
|
import 'widgets/category_delegate.dart';
|
||||||
import 'widgets/product_card.dart';
|
|
||||||
import 'widgets/product_tile.dart';
|
import 'widgets/product_tile.dart';
|
||||||
|
|
||||||
@RoutePage()
|
@RoutePage()
|
||||||
class ProductPage extends StatefulWidget implements AutoRouteWrapper {
|
class ProductPage extends StatefulWidget {
|
||||||
const ProductPage({super.key});
|
const ProductPage({super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<ProductPage> createState() => _ProductPageState();
|
State<ProductPage> createState() => _ProductPageState();
|
||||||
|
|
||||||
@override
|
|
||||||
Widget wrappedRoute(BuildContext context) => MultiBlocProvider(
|
|
||||||
providers: [
|
|
||||||
BlocProvider(
|
|
||||||
create: (context) =>
|
|
||||||
getIt<CategoryLoaderBloc>()..add(CategoryLoaderEvent.fetched()),
|
|
||||||
),
|
|
||||||
BlocProvider(
|
|
||||||
create: (context) =>
|
|
||||||
getIt<ProductLoaderBloc>()
|
|
||||||
..add(ProductLoaderEvent.fetched(isRefresh: true)),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
child: this,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
enum ViewType { grid, list }
|
enum ViewType { grid, list }
|
||||||
|
|
||||||
class _ProductPageState extends State<ProductPage>
|
class _ProductPageState extends State<ProductPage>
|
||||||
with TickerProviderStateMixin {
|
with TickerProviderStateMixin {
|
||||||
Category selectedCategory = Category.addAllData();
|
String selectedCategory = 'Semua';
|
||||||
|
List<String> categories = ['Semua', 'Makanan', 'Minuman', 'Snack', 'Dessert'];
|
||||||
ViewType currentViewType = ViewType.grid;
|
ViewType currentViewType = ViewType.grid;
|
||||||
ScrollController scrollController = ScrollController();
|
|
||||||
|
// Sample product data
|
||||||
|
List<Product> products = [
|
||||||
|
Product(
|
||||||
|
id: '1',
|
||||||
|
name: 'Nasi Goreng Special',
|
||||||
|
price: 25000,
|
||||||
|
category: 'Makanan',
|
||||||
|
stock: 50,
|
||||||
|
imageUrl: 'assets/images/nasi_goreng.jpg',
|
||||||
|
isActive: true,
|
||||||
|
),
|
||||||
|
Product(
|
||||||
|
id: '8',
|
||||||
|
name: 'Nasi Goreng',
|
||||||
|
price: 15000,
|
||||||
|
category: 'Makanan',
|
||||||
|
stock: 50,
|
||||||
|
imageUrl: 'assets/images/nasi_goreng.jpg',
|
||||||
|
isActive: true,
|
||||||
|
),
|
||||||
|
Product(
|
||||||
|
id: '9',
|
||||||
|
name: 'Nasi Goreng Telor',
|
||||||
|
price: 18000,
|
||||||
|
category: 'Makanan',
|
||||||
|
stock: 50,
|
||||||
|
imageUrl: 'assets/images/nasi_goreng.jpg',
|
||||||
|
isActive: true,
|
||||||
|
),
|
||||||
|
Product(
|
||||||
|
id: '10',
|
||||||
|
name: 'Mie Goreng ',
|
||||||
|
price: 18000,
|
||||||
|
category: 'Makanan',
|
||||||
|
stock: 50,
|
||||||
|
imageUrl: 'assets/images/nasi_goreng.jpg',
|
||||||
|
isActive: true,
|
||||||
|
),
|
||||||
|
Product(
|
||||||
|
id: '2',
|
||||||
|
name: 'Es Teh Manis',
|
||||||
|
price: 8000,
|
||||||
|
category: 'Minuman',
|
||||||
|
stock: 100,
|
||||||
|
imageUrl: 'assets/images/es_teh.jpg',
|
||||||
|
isActive: true,
|
||||||
|
),
|
||||||
|
Product(
|
||||||
|
id: '6',
|
||||||
|
name: 'Es Jeruk',
|
||||||
|
price: 10000,
|
||||||
|
category: 'Minuman',
|
||||||
|
stock: 100,
|
||||||
|
imageUrl: 'assets/images/es_teh.jpg',
|
||||||
|
isActive: true,
|
||||||
|
),
|
||||||
|
Product(
|
||||||
|
id: '7',
|
||||||
|
name: 'Es Kelapa',
|
||||||
|
price: 12000,
|
||||||
|
category: 'Minuman',
|
||||||
|
stock: 100,
|
||||||
|
imageUrl: 'assets/images/es_teh.jpg',
|
||||||
|
isActive: true,
|
||||||
|
),
|
||||||
|
Product(
|
||||||
|
id: '3',
|
||||||
|
name: 'Keripik Singkong',
|
||||||
|
price: 15000,
|
||||||
|
category: 'Snack',
|
||||||
|
stock: 25,
|
||||||
|
imageUrl: 'assets/images/keripik.jpg',
|
||||||
|
isActive: true,
|
||||||
|
),
|
||||||
|
Product(
|
||||||
|
id: '4',
|
||||||
|
name: 'Es Krim Vanilla',
|
||||||
|
price: 12000,
|
||||||
|
category: 'Dessert',
|
||||||
|
stock: 30,
|
||||||
|
imageUrl: 'assets/images/ice_cream.jpg',
|
||||||
|
isActive: false,
|
||||||
|
),
|
||||||
|
Product(
|
||||||
|
id: '5',
|
||||||
|
name: 'Ayam Bakar',
|
||||||
|
price: 35000,
|
||||||
|
category: 'Makanan',
|
||||||
|
stock: 20,
|
||||||
|
imageUrl: 'assets/images/ayam_bakar.jpg',
|
||||||
|
isActive: true,
|
||||||
|
),
|
||||||
|
];
|
||||||
|
|
||||||
|
List<Product> get filteredProducts {
|
||||||
|
return products.where((product) {
|
||||||
|
bool matchesCategory =
|
||||||
|
selectedCategory == 'Semua' || product.category == selectedCategory;
|
||||||
|
return matchesCategory;
|
||||||
|
}).toList();
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
initState() {
|
initState() {
|
||||||
@ -55,42 +132,21 @@ class _ProductPageState extends State<ProductPage>
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
void dispose() {
|
||||||
return BlocListener<ProductLoaderBloc, ProductLoaderState>(
|
super.dispose();
|
||||||
listenWhen: (previous, current) =>
|
}
|
||||||
previous.categoryId != current.categoryId,
|
|
||||||
listener: (context, state) {
|
|
||||||
context.read<ProductLoaderBloc>().add(
|
|
||||||
ProductLoaderEvent.fetched(isRefresh: true),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
child: BlocBuilder<ProductLoaderBloc, ProductLoaderState>(
|
|
||||||
builder: (context, state) {
|
|
||||||
return Scaffold(
|
|
||||||
backgroundColor: AppColor.background,
|
|
||||||
body: NotificationListener<ScrollNotification>(
|
|
||||||
onNotification: (notification) {
|
|
||||||
if (notification is ScrollEndNotification &&
|
|
||||||
scrollController.position.extentAfter == 0) {
|
|
||||||
context.read<ProductLoaderBloc>().add(
|
|
||||||
ProductLoaderEvent.fetched(),
|
|
||||||
);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
@override
|
||||||
},
|
Widget build(BuildContext context) {
|
||||||
child: CustomScrollView(
|
return Scaffold(
|
||||||
controller: scrollController,
|
backgroundColor: AppColor.background,
|
||||||
slivers: [
|
body: CustomScrollView(
|
||||||
_buildSliverAppBar(),
|
slivers: [
|
||||||
_buildCategoryFilter(),
|
_buildSliverAppBar(),
|
||||||
_buildProductContent(state),
|
_buildCategoryFilter(),
|
||||||
],
|
_buildProductContent(),
|
||||||
),
|
_buildEmptyState(),
|
||||||
),
|
],
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -104,97 +160,44 @@ class _ProductPageState extends State<ProductPage>
|
|||||||
flexibleSpace: CustomAppBar(title: 'Produk'),
|
flexibleSpace: CustomAppBar(title: 'Produk'),
|
||||||
actions: [
|
actions: [
|
||||||
ActionIconButton(onTap: () {}, icon: LineIcons.search),
|
ActionIconButton(onTap: () {}, icon: LineIcons.search),
|
||||||
|
ActionIconButton(onTap: _showAddProductDialog, icon: LineIcons.plus),
|
||||||
ActionIconButton(
|
ActionIconButton(
|
||||||
onTap: _toggleViewType,
|
onTap: _toggleViewType,
|
||||||
icon: currentViewType == ViewType.grid
|
icon: currentViewType == ViewType.grid
|
||||||
? LineIcons.list
|
? LineIcons.list
|
||||||
: LineIcons.thLarge,
|
: LineIcons.thLarge,
|
||||||
),
|
),
|
||||||
|
ActionIconButton(onTap: _showOptionsMenu, icon: LineIcons.filter),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildCategoryFilter() {
|
Widget _buildCategoryFilter() {
|
||||||
return BlocBuilder<CategoryLoaderBloc, CategoryLoaderState>(
|
return SliverPersistentHeader(
|
||||||
builder: (context, state) {
|
pinned: true,
|
||||||
if (state.isFetching && state.categories.isEmpty) {
|
delegate: ProductCategoryHeaderDelegate(
|
||||||
return _buildCategoryShimmer();
|
categories: categories,
|
||||||
}
|
selectedCategory: selectedCategory,
|
||||||
|
onCategoryChanged: (category) {
|
||||||
return SliverPersistentHeader(
|
setState(() {
|
||||||
pinned: true,
|
selectedCategory = category;
|
||||||
delegate: ProductCategoryHeaderDelegate(
|
});
|
||||||
categories: state.categories,
|
},
|
||||||
selectedCategory: selectedCategory,
|
|
||||||
onCategoryChanged: (category) {
|
|
||||||
setState(() {
|
|
||||||
selectedCategory = category;
|
|
||||||
});
|
|
||||||
if (category.id == Category.addAllData().id) {
|
|
||||||
context.read<ProductLoaderBloc>().add(
|
|
||||||
ProductLoaderEvent.categoryIdChanged(''),
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
context.read<ProductLoaderBloc>().add(
|
|
||||||
ProductLoaderEvent.categoryIdChanged(category.id),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _buildCategoryShimmer() {
|
|
||||||
return SliverToBoxAdapter(
|
|
||||||
child: Container(
|
|
||||||
height: 60,
|
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
|
|
||||||
child: Shimmer.fromColors(
|
|
||||||
baseColor: Colors.grey[300]!,
|
|
||||||
highlightColor: Colors.grey[100]!,
|
|
||||||
child: Row(
|
|
||||||
children: List.generate(
|
|
||||||
4,
|
|
||||||
(index) => Container(
|
|
||||||
margin: EdgeInsets.only(right: index < 3 ? 12 : 0),
|
|
||||||
width: 80,
|
|
||||||
height: 35,
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: Colors.white,
|
|
||||||
borderRadius: BorderRadius.circular(20),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildProductContent(ProductLoaderState state) {
|
Widget _buildProductContent() {
|
||||||
if (state.isFetching && state.products.isEmpty) {
|
if (filteredProducts.isEmpty) {
|
||||||
return currentViewType == ViewType.grid
|
return const SliverToBoxAdapter(child: SizedBox.shrink());
|
||||||
? _buildProductGridShimmer()
|
|
||||||
: _buildProductListShimmer();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (state.products.isEmpty && !state.isFetching) {
|
|
||||||
return SliverToBoxAdapter(
|
|
||||||
child: EmptyWidget(
|
|
||||||
title: 'Tidak ada produk ditemukan',
|
|
||||||
message: 'Coba ubah filter atau tambah produk baru',
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return currentViewType == ViewType.grid
|
return currentViewType == ViewType.grid
|
||||||
? _buildProductGrid(state.products)
|
? _buildProductGrid()
|
||||||
: _buildProductList(state.products);
|
: _buildProductList();
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildProductGridShimmer() {
|
Widget _buildProductGrid() {
|
||||||
return SliverPadding(
|
return SliverPadding(
|
||||||
padding: const EdgeInsets.all(16.0),
|
padding: const EdgeInsets.all(16.0),
|
||||||
sliver: SliverGrid(
|
sliver: SliverGrid(
|
||||||
@ -205,74 +208,26 @@ class _ProductPageState extends State<ProductPage>
|
|||||||
mainAxisSpacing: 16.0,
|
mainAxisSpacing: 16.0,
|
||||||
),
|
),
|
||||||
delegate: SliverChildBuilderDelegate((context, index) {
|
delegate: SliverChildBuilderDelegate((context, index) {
|
||||||
return _buildProductTileShimmer();
|
final product = filteredProducts[index];
|
||||||
}, childCount: 6), // Show 6 shimmer items
|
return ProductTile(product: product, onTap: () {});
|
||||||
|
}, childCount: filteredProducts.length),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildProductTileShimmer() {
|
Widget _buildProductList() {
|
||||||
return Shimmer.fromColors(
|
|
||||||
baseColor: Colors.grey[300]!,
|
|
||||||
highlightColor: Colors.grey[100]!,
|
|
||||||
child: Container(
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: Colors.white,
|
|
||||||
borderRadius: BorderRadius.circular(12),
|
|
||||||
),
|
|
||||||
child: Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
// Image shimmer
|
|
||||||
Expanded(
|
|
||||||
flex: 3,
|
|
||||||
child: Container(
|
|
||||||
width: double.infinity,
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: Colors.white,
|
|
||||||
borderRadius: BorderRadius.circular(12),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
// Content shimmer
|
|
||||||
Expanded(
|
|
||||||
flex: 2,
|
|
||||||
child: Padding(
|
|
||||||
padding: const EdgeInsets.all(12.0),
|
|
||||||
child: Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
Container(
|
|
||||||
width: double.infinity,
|
|
||||||
height: 16,
|
|
||||||
color: Colors.white,
|
|
||||||
),
|
|
||||||
const SizedBox(height: 8),
|
|
||||||
Container(width: 100, height: 12, color: Colors.white),
|
|
||||||
const Spacer(),
|
|
||||||
Container(width: 80, height: 14, color: Colors.white),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _buildProductListShimmer() {
|
|
||||||
return SliverPadding(
|
return SliverPadding(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0),
|
padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0),
|
||||||
sliver: SliverList(
|
sliver: SliverList(
|
||||||
delegate: SliverChildBuilderDelegate((context, index) {
|
delegate: SliverChildBuilderDelegate((context, index) {
|
||||||
return _buildProductListItemShimmer();
|
final product = filteredProducts[index];
|
||||||
}, childCount: 8), // Show 8 shimmer items
|
return _buildProductListItem(product);
|
||||||
|
}, childCount: filteredProducts.length),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildProductListItemShimmer() {
|
Widget _buildProductListItem(Product product) {
|
||||||
return Container(
|
return Container(
|
||||||
margin: const EdgeInsets.only(bottom: 12.0),
|
margin: const EdgeInsets.only(bottom: 12.0),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
@ -287,56 +242,104 @@ class _ProductPageState extends State<ProductPage>
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
child: Shimmer.fromColors(
|
child: InkWell(
|
||||||
baseColor: Colors.grey[300]!,
|
onTap: () {},
|
||||||
highlightColor: Colors.grey[100]!,
|
borderRadius: BorderRadius.circular(12),
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.all(12.0),
|
padding: const EdgeInsets.all(12.0),
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
// Image shimmer
|
// Product Image
|
||||||
Container(
|
Container(
|
||||||
width: 80,
|
width: 80,
|
||||||
height: 80,
|
height: 80,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: Colors.white,
|
|
||||||
borderRadius: BorderRadius.circular(8),
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
color: AppColor.background,
|
||||||
|
),
|
||||||
|
child: ClipRRect(
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
child: Image.asset(
|
||||||
|
product.imageUrl,
|
||||||
|
fit: BoxFit.cover,
|
||||||
|
errorBuilder: (context, error, stackTrace) {
|
||||||
|
return Container(
|
||||||
|
color: AppColor.background,
|
||||||
|
child: Icon(
|
||||||
|
Icons.image_outlined,
|
||||||
|
color: AppColor.textLight,
|
||||||
|
size: 32,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(width: 12),
|
const SizedBox(width: 12),
|
||||||
// Content shimmer
|
// Product Info
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Container(
|
Text(
|
||||||
width: double.infinity,
|
product.name,
|
||||||
height: 16,
|
style: const TextStyle(
|
||||||
color: Colors.white,
|
fontSize: 16,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
),
|
||||||
|
maxLines: 2,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
),
|
||||||
|
const SizedBox(height: 4),
|
||||||
|
Text(
|
||||||
|
product.category,
|
||||||
|
style: TextStyle(fontSize: 12, color: AppColor.textLight),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 8),
|
const SizedBox(height: 8),
|
||||||
Container(width: 120, height: 12, color: Colors.white),
|
|
||||||
const SizedBox(height: 12),
|
|
||||||
Row(
|
Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
children: [
|
children: [
|
||||||
Container(width: 100, height: 16, color: Colors.white),
|
Text(
|
||||||
|
'Rp ${_formatPrice(product.price)}',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 16,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
color: AppColor.primary,
|
||||||
|
),
|
||||||
|
),
|
||||||
Container(
|
Container(
|
||||||
width: 60,
|
padding: const EdgeInsets.symmetric(
|
||||||
height: 24,
|
horizontal: 8,
|
||||||
|
vertical: 4,
|
||||||
|
),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: Colors.white,
|
color: product.isActive
|
||||||
|
? Colors.green.withOpacity(0.1)
|
||||||
|
: Colors.red.withOpacity(0.1),
|
||||||
borderRadius: BorderRadius.circular(12),
|
borderRadius: BorderRadius.circular(12),
|
||||||
),
|
),
|
||||||
|
child: Text(
|
||||||
|
'Stock: ${product.stock}',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 12,
|
||||||
|
color: product.isActive
|
||||||
|
? Colors.green
|
||||||
|
: Colors.red,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(width: 8),
|
// Action Button
|
||||||
// Action button shimmer
|
IconButton(
|
||||||
Container(width: 24, height: 24, color: Colors.white),
|
onPressed: () {},
|
||||||
|
icon: const Icon(Icons.more_vert),
|
||||||
|
color: AppColor.textLight,
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -344,33 +347,10 @@ class _ProductPageState extends State<ProductPage>
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildProductGrid(List<Product> products) {
|
String _formatPrice(int price) {
|
||||||
return SliverPadding(
|
return price.toString().replaceAllMapped(
|
||||||
padding: const EdgeInsets.all(16.0),
|
RegExp(r'(\d{1,3})(?=(\d{3})+(?!\d))'),
|
||||||
sliver: SliverGrid(
|
(Match m) => '${m[1]}.',
|
||||||
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
|
|
||||||
crossAxisCount: 2,
|
|
||||||
childAspectRatio: 0.75,
|
|
||||||
crossAxisSpacing: 16.0,
|
|
||||||
mainAxisSpacing: 16.0,
|
|
||||||
),
|
|
||||||
delegate: SliverChildBuilderDelegate((context, index) {
|
|
||||||
final product = products[index];
|
|
||||||
return ProductTile(product: product, onTap: () {});
|
|
||||||
}, childCount: products.length),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _buildProductList(List<Product> products) {
|
|
||||||
return SliverPadding(
|
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0),
|
|
||||||
sliver: SliverList(
|
|
||||||
delegate: SliverChildBuilderDelegate((context, index) {
|
|
||||||
final product = products[index];
|
|
||||||
return ProductCard(product: product);
|
|
||||||
}, childCount: products.length),
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -381,4 +361,128 @@ class _ProductPageState extends State<ProductPage>
|
|||||||
: ViewType.grid;
|
: ViewType.grid;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Widget _buildEmptyState() {
|
||||||
|
if (filteredProducts.isNotEmpty) {
|
||||||
|
return const SliverToBoxAdapter(child: SizedBox.shrink());
|
||||||
|
}
|
||||||
|
|
||||||
|
return SliverToBoxAdapter(
|
||||||
|
child: Container(
|
||||||
|
height: 300,
|
||||||
|
margin: const EdgeInsets.all(32.0),
|
||||||
|
child: Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Icon(
|
||||||
|
Icons.inventory_2_outlined,
|
||||||
|
size: 64,
|
||||||
|
color: AppColor.textLight,
|
||||||
|
),
|
||||||
|
const SizedBox(height: 16),
|
||||||
|
Text(
|
||||||
|
'Tidak ada produk ditemukan',
|
||||||
|
style: TextStyle(
|
||||||
|
color: AppColor.textSecondary,
|
||||||
|
fontSize: 16,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
Text(
|
||||||
|
'Coba ubah filter atau tambah produk baru',
|
||||||
|
style: TextStyle(color: AppColor.textLight, fontSize: 14),
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _showAddProductDialog() {
|
||||||
|
showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (context) => AlertDialog(
|
||||||
|
title: const Text('Tambah Produk'),
|
||||||
|
content: const Text(
|
||||||
|
'Dialog tambah produk akan diimplementasikan di sini',
|
||||||
|
),
|
||||||
|
actions: [
|
||||||
|
TextButton(
|
||||||
|
onPressed: () => Navigator.pop(context),
|
||||||
|
child: const Text('Batal'),
|
||||||
|
),
|
||||||
|
ElevatedButton(
|
||||||
|
onPressed: () => Navigator.pop(context),
|
||||||
|
child: const Text('Simpan'),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _showOptionsMenu() {
|
||||||
|
showModalBottomSheet(
|
||||||
|
context: context,
|
||||||
|
builder: (context) => Container(
|
||||||
|
padding: const EdgeInsets.all(16.0),
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
ListTile(
|
||||||
|
leading: Icon(
|
||||||
|
currentViewType == ViewType.grid ? Icons.list : Icons.grid_view,
|
||||||
|
),
|
||||||
|
title: Text(
|
||||||
|
currentViewType == ViewType.grid
|
||||||
|
? 'Tampilan List'
|
||||||
|
: 'Tampilan Grid',
|
||||||
|
),
|
||||||
|
onTap: () {
|
||||||
|
Navigator.pop(context);
|
||||||
|
_toggleViewType();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
ListTile(
|
||||||
|
leading: const Icon(Icons.sort),
|
||||||
|
title: const Text('Urutkan'),
|
||||||
|
onTap: () => Navigator.pop(context),
|
||||||
|
),
|
||||||
|
ListTile(
|
||||||
|
leading: const Icon(Icons.filter_list),
|
||||||
|
title: const Text('Filter Lanjutan'),
|
||||||
|
onTap: () => Navigator.pop(context),
|
||||||
|
),
|
||||||
|
ListTile(
|
||||||
|
leading: const Icon(Icons.download),
|
||||||
|
title: const Text('Export Data'),
|
||||||
|
onTap: () => Navigator.pop(context),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Product Model
|
||||||
|
class Product {
|
||||||
|
final String id;
|
||||||
|
final String name;
|
||||||
|
final int price;
|
||||||
|
final String category;
|
||||||
|
final int stock;
|
||||||
|
final String imageUrl;
|
||||||
|
bool isActive;
|
||||||
|
|
||||||
|
Product({
|
||||||
|
required this.id,
|
||||||
|
required this.name,
|
||||||
|
required this.price,
|
||||||
|
required this.category,
|
||||||
|
required this.stock,
|
||||||
|
required this.imageUrl,
|
||||||
|
required this.isActive,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,12 +1,11 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
import '../../../../common/theme/theme.dart';
|
import '../../../../common/theme/theme.dart';
|
||||||
import '../../../../domain/category/category.dart';
|
|
||||||
|
|
||||||
class ProductCategoryHeaderDelegate extends SliverPersistentHeaderDelegate {
|
class ProductCategoryHeaderDelegate extends SliverPersistentHeaderDelegate {
|
||||||
final List<Category> categories;
|
final List<String> categories;
|
||||||
final Category selectedCategory;
|
final String selectedCategory;
|
||||||
final ValueChanged<Category> onCategoryChanged;
|
final ValueChanged<String> onCategoryChanged;
|
||||||
|
|
||||||
ProductCategoryHeaderDelegate({
|
ProductCategoryHeaderDelegate({
|
||||||
required this.categories,
|
required this.categories,
|
||||||
@ -36,7 +35,7 @@ class ProductCategoryHeaderDelegate extends SliverPersistentHeaderDelegate {
|
|||||||
return Container(
|
return Container(
|
||||||
margin: const EdgeInsets.only(right: 12.0),
|
margin: const EdgeInsets.only(right: 12.0),
|
||||||
child: FilterChip(
|
child: FilterChip(
|
||||||
label: Text(category.name),
|
label: Text(category),
|
||||||
selected: isSelected,
|
selected: isSelected,
|
||||||
onSelected: (selected) => onCategoryChanged(category),
|
onSelected: (selected) => onCategoryChanged(category),
|
||||||
backgroundColor: AppColor.surface,
|
backgroundColor: AppColor.surface,
|
||||||
@ -65,7 +64,6 @@ class ProductCategoryHeaderDelegate extends SliverPersistentHeaderDelegate {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
bool shouldRebuild(ProductCategoryHeaderDelegate oldDelegate) {
|
bool shouldRebuild(ProductCategoryHeaderDelegate oldDelegate) {
|
||||||
return oldDelegate.categories != categories ||
|
return oldDelegate.selectedCategory != selectedCategory;
|
||||||
oldDelegate.selectedCategory != selectedCategory;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,117 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
|
|
||||||
import '../../../../common/extension/extension.dart';
|
|
||||||
import '../../../../common/theme/theme.dart';
|
|
||||||
import '../../../../domain/product/product.dart';
|
|
||||||
import '../../../components/image/image.dart';
|
|
||||||
|
|
||||||
class ProductCard extends StatelessWidget {
|
|
||||||
const ProductCard({super.key, required this.product, this.onTap});
|
|
||||||
|
|
||||||
final Product product;
|
|
||||||
final VoidCallback? onTap;
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return Container(
|
|
||||||
margin: const EdgeInsets.only(bottom: 12.0),
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: Colors.white,
|
|
||||||
borderRadius: BorderRadius.circular(12),
|
|
||||||
boxShadow: [
|
|
||||||
BoxShadow(
|
|
||||||
color: Colors.grey.withOpacity(0.1),
|
|
||||||
spreadRadius: 1,
|
|
||||||
blurRadius: 6,
|
|
||||||
offset: const Offset(0, 2),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
child: InkWell(
|
|
||||||
onTap: onTap,
|
|
||||||
borderRadius: BorderRadius.circular(12),
|
|
||||||
child: Padding(
|
|
||||||
padding: const EdgeInsets.all(12.0),
|
|
||||||
child: Row(
|
|
||||||
children: [
|
|
||||||
// Product Image
|
|
||||||
_buildProductImage(),
|
|
||||||
const SizedBox(width: 12),
|
|
||||||
// Product Info
|
|
||||||
Expanded(child: _buildProductInfo()),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _buildProductImage() {
|
|
||||||
return Container(
|
|
||||||
width: 80,
|
|
||||||
height: 80,
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
borderRadius: BorderRadius.circular(8),
|
|
||||||
color: AppColor.background,
|
|
||||||
),
|
|
||||||
child: ClipRRect(
|
|
||||||
borderRadius: BorderRadius.circular(8),
|
|
||||||
child: AppNetworkImage(url: product.imageUrl, fit: BoxFit.cover),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _buildProductInfo() {
|
|
||||||
return Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
product.name,
|
|
||||||
style: const TextStyle(fontSize: 16, fontWeight: FontWeight.w600),
|
|
||||||
maxLines: 2,
|
|
||||||
overflow: TextOverflow.ellipsis,
|
|
||||||
),
|
|
||||||
const SizedBox(height: 4),
|
|
||||||
Text(
|
|
||||||
product.description,
|
|
||||||
style: TextStyle(fontSize: 12, color: AppColor.textLight),
|
|
||||||
maxLines: 1,
|
|
||||||
overflow: TextOverflow.ellipsis,
|
|
||||||
),
|
|
||||||
const SizedBox(height: 8),
|
|
||||||
Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
product.price.currencyFormatRp,
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 16,
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
color: AppColor.primary,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Container(
|
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: _getStatusColor().withOpacity(0.1),
|
|
||||||
borderRadius: BorderRadius.circular(12),
|
|
||||||
),
|
|
||||||
child: Text(
|
|
||||||
product.isActive ? 'AKTIF' : 'NONAKTIF',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 12,
|
|
||||||
color: _getStatusColor(),
|
|
||||||
fontWeight: FontWeight.w500,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Color _getStatusColor() {
|
|
||||||
return product.isActive ? Colors.green : Colors.red;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,10 +1,8 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
import '../../../../common/extension/extension.dart';
|
|
||||||
import '../../../../common/theme/theme.dart';
|
import '../../../../common/theme/theme.dart';
|
||||||
import '../../../../domain/product/product.dart';
|
|
||||||
import '../../../components/image/image.dart';
|
|
||||||
import '../../../components/spacer/spacer.dart';
|
import '../../../components/spacer/spacer.dart';
|
||||||
|
import '../product_page.dart';
|
||||||
|
|
||||||
class ProductTile extends StatelessWidget {
|
class ProductTile extends StatelessWidget {
|
||||||
final Product product;
|
final Product product;
|
||||||
@ -92,7 +90,7 @@ class ProductTile extends StatelessWidget {
|
|||||||
|
|
||||||
Widget _buildProductImage() {
|
Widget _buildProductImage() {
|
||||||
return Expanded(
|
return Expanded(
|
||||||
flex: 3,
|
flex: 2,
|
||||||
child: Container(
|
child: Container(
|
||||||
width: double.infinity,
|
width: double.infinity,
|
||||||
decoration: const BoxDecoration(
|
decoration: const BoxDecoration(
|
||||||
@ -102,12 +100,12 @@ class ProductTile extends StatelessWidget {
|
|||||||
topRight: Radius.circular(12.0),
|
topRight: Radius.circular(12.0),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
child: ClipRRect(
|
child: Stack(
|
||||||
borderRadius: const BorderRadius.only(
|
children: [
|
||||||
topLeft: Radius.circular(12.0),
|
Center(
|
||||||
topRight: Radius.circular(12.0),
|
child: Icon(Icons.image, size: 32, color: AppColor.textLight),
|
||||||
),
|
),
|
||||||
child: AppNetworkImage(url: product.imageUrl, fit: BoxFit.cover),
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@ -135,7 +133,7 @@ class ProductTile extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
const SizedBox(height: 2),
|
const SizedBox(height: 2),
|
||||||
Text(
|
Text(
|
||||||
product.price.currencyFormatRp,
|
_formatPrice(product.price),
|
||||||
style: AppStyle.xs.copyWith(
|
style: AppStyle.xs.copyWith(
|
||||||
color: product.isActive
|
color: product.isActive
|
||||||
? AppColor.primary
|
? AppColor.primary
|
||||||
@ -153,20 +151,30 @@ class ProductTile extends StatelessWidget {
|
|||||||
|
|
||||||
Widget _buildBottomInfo() {
|
Widget _buildBottomInfo() {
|
||||||
return Row(
|
return Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.end,
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
crossAxisAlignment: CrossAxisAlignment.end,
|
crossAxisAlignment: CrossAxisAlignment.end,
|
||||||
children: [
|
children: [
|
||||||
|
Flexible(
|
||||||
|
child: Text(
|
||||||
|
'Stok: ${product.stock}',
|
||||||
|
style: AppStyle.xs.copyWith(
|
||||||
|
color: AppColor.textSecondary,
|
||||||
|
fontSize: 9,
|
||||||
|
),
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
),
|
||||||
|
),
|
||||||
Container(
|
Container(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 4, vertical: 1),
|
padding: const EdgeInsets.symmetric(horizontal: 4, vertical: 1),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: _getPrinterTypeColor().withOpacity(0.1),
|
color: AppColor.primaryLight.withOpacity(0.1),
|
||||||
borderRadius: BorderRadius.circular(3.0),
|
borderRadius: BorderRadius.circular(3.0),
|
||||||
),
|
),
|
||||||
child: Text(
|
child: Text(
|
||||||
product.printerType.toUpperCase(),
|
product.category,
|
||||||
style: AppStyle.xs.copyWith(
|
style: AppStyle.xs.copyWith(
|
||||||
color: product.isActive
|
color: product.isActive
|
||||||
? _getPrinterTypeColor()
|
? AppColor.primary
|
||||||
: AppColor.textSecondary,
|
: AppColor.textSecondary,
|
||||||
fontSize: 8,
|
fontSize: 8,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
@ -177,16 +185,7 @@ class ProductTile extends StatelessWidget {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Color _getPrinterTypeColor() {
|
String _formatPrice(int price) {
|
||||||
switch (product.printerType.toLowerCase()) {
|
return 'Rp ${price.toString().replaceAllMapped(RegExp(r'(\d{1,3})(?=(\d{3})+(?!\d))'), (Match m) => '${m[1]}.')}';
|
||||||
case 'kitchen':
|
|
||||||
return Colors.orange;
|
|
||||||
case 'bar':
|
|
||||||
return Colors.blue;
|
|
||||||
case 'receipt':
|
|
||||||
return AppColor.primary;
|
|
||||||
default:
|
|
||||||
return AppColor.primary;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,7 +4,6 @@ import 'package:flutter_bloc/flutter_bloc.dart';
|
|||||||
import 'package:line_icons/line_icons.dart';
|
import 'package:line_icons/line_icons.dart';
|
||||||
import 'package:loader_overlay/loader_overlay.dart';
|
import 'package:loader_overlay/loader_overlay.dart';
|
||||||
|
|
||||||
import '../../../application/auth/auth_bloc.dart';
|
|
||||||
import '../../../application/auth/logout_form/logout_form_bloc.dart';
|
import '../../../application/auth/logout_form/logout_form_bloc.dart';
|
||||||
import '../../../common/theme/theme.dart';
|
import '../../../common/theme/theme.dart';
|
||||||
import '../../../injection.dart';
|
import '../../../injection.dart';
|
||||||
@ -50,85 +49,78 @@ class ProfilePage extends StatelessWidget implements AutoRouteWrapper {
|
|||||||
},
|
},
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
child: BlocBuilder<AuthBloc, AuthState>(
|
child: Scaffold(
|
||||||
builder: (context, state) {
|
backgroundColor: AppColor.background,
|
||||||
return Scaffold(
|
body: CustomScrollView(
|
||||||
backgroundColor: AppColor.background,
|
slivers: [
|
||||||
body: CustomScrollView(
|
SliverAppBar(
|
||||||
slivers: [
|
backgroundColor: AppColor.primary,
|
||||||
SliverAppBar(
|
elevation: 0,
|
||||||
backgroundColor: AppColor.primary,
|
pinned: true,
|
||||||
elevation: 0,
|
expandedHeight: 264.0,
|
||||||
pinned: true,
|
flexibleSpace: LayoutBuilder(
|
||||||
expandedHeight: 264.0,
|
builder: (BuildContext context, BoxConstraints constraints) {
|
||||||
flexibleSpace: LayoutBuilder(
|
// Calculate the collapse ratio
|
||||||
builder:
|
final double top = constraints.biggest.height;
|
||||||
(BuildContext context, BoxConstraints constraints) {
|
final double collapsedHeight =
|
||||||
// Calculate the collapse ratio
|
MediaQuery.of(context).padding.top + kToolbarHeight;
|
||||||
final double top = constraints.biggest.height;
|
final double expandedHeight = 264.0;
|
||||||
final double collapsedHeight =
|
final double shrinkRatio =
|
||||||
MediaQuery.of(context).padding.top +
|
((expandedHeight - top) /
|
||||||
kToolbarHeight;
|
(expandedHeight - collapsedHeight))
|
||||||
final double expandedHeight = 264.0;
|
.clamp(0.0, 1.0);
|
||||||
final double shrinkRatio =
|
|
||||||
((expandedHeight - top) /
|
|
||||||
(expandedHeight - collapsedHeight))
|
|
||||||
.clamp(0.0, 1.0);
|
|
||||||
|
|
||||||
return FlexibleSpaceBar(
|
return FlexibleSpaceBar(
|
||||||
background: ProfileHeader(user: state.user),
|
background: ProfileHeader(),
|
||||||
titlePadding: const EdgeInsets.only(
|
titlePadding: const EdgeInsets.only(
|
||||||
left: 20,
|
left: 20,
|
||||||
right: 12,
|
right: 12,
|
||||||
bottom: 16,
|
bottom: 16,
|
||||||
|
),
|
||||||
|
title: Opacity(
|
||||||
|
opacity: shrinkRatio,
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'Profile',
|
||||||
|
style: AppStyle.xl.copyWith(
|
||||||
|
fontWeight: FontWeight.w700,
|
||||||
|
fontSize: 18,
|
||||||
|
letterSpacing: -0.5,
|
||||||
|
color: AppColor.white,
|
||||||
),
|
),
|
||||||
title: Opacity(
|
),
|
||||||
opacity: shrinkRatio,
|
ActionIconButton(
|
||||||
child: Row(
|
onTap: () {},
|
||||||
mainAxisAlignment:
|
icon: LineIcons.userEdit,
|
||||||
MainAxisAlignment.spaceBetween,
|
),
|
||||||
children: [
|
],
|
||||||
Text(
|
),
|
||||||
'Profile',
|
),
|
||||||
style: AppStyle.xl.copyWith(
|
);
|
||||||
fontWeight: FontWeight.w700,
|
},
|
||||||
fontSize: 18,
|
),
|
||||||
letterSpacing: -0.5,
|
|
||||||
color: AppColor.white,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
ActionIconButton(
|
|
||||||
onTap: () {},
|
|
||||||
icon: LineIcons.userEdit,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
SliverToBoxAdapter(
|
|
||||||
child: Column(
|
|
||||||
children: [
|
|
||||||
const SpaceHeight(20),
|
|
||||||
ProfileAccountInfo(user: state.user),
|
|
||||||
const SpaceHeight(12),
|
|
||||||
ProfileBusinessSetting(),
|
|
||||||
const SpaceHeight(12),
|
|
||||||
ProfileAppSetting(),
|
|
||||||
const SpaceHeight(12),
|
|
||||||
ProfileSupport(),
|
|
||||||
const SpaceHeight(12),
|
|
||||||
ProfileDangerZone(),
|
|
||||||
const SpaceHeight(30),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
);
|
SliverToBoxAdapter(
|
||||||
},
|
child: Column(
|
||||||
|
children: [
|
||||||
|
const SpaceHeight(20),
|
||||||
|
ProfileAccountInfo(),
|
||||||
|
const SpaceHeight(12),
|
||||||
|
ProfileBusinessSetting(),
|
||||||
|
const SpaceHeight(12),
|
||||||
|
ProfileAppSetting(),
|
||||||
|
const SpaceHeight(12),
|
||||||
|
ProfileSupport(),
|
||||||
|
const SpaceHeight(12),
|
||||||
|
ProfileDangerZone(),
|
||||||
|
const SpaceHeight(30),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,15 +1,11 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:line_icons/line_icons.dart';
|
|
||||||
|
|
||||||
import '../../../../common/extension/extension.dart';
|
|
||||||
import '../../../../common/theme/theme.dart';
|
import '../../../../common/theme/theme.dart';
|
||||||
import '../../../../domain/auth/auth.dart';
|
|
||||||
import 'divider.dart';
|
import 'divider.dart';
|
||||||
import 'profile_tile.dart';
|
import 'profile_tile.dart';
|
||||||
|
|
||||||
class ProfileAccountInfo extends StatelessWidget {
|
class ProfileAccountInfo extends StatelessWidget {
|
||||||
final User user;
|
const ProfileAccountInfo({super.key});
|
||||||
const ProfileAccountInfo({super.key, required this.user});
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@ -42,9 +38,9 @@ class ProfileAccountInfo extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
|
|
||||||
ProfileTile(
|
ProfileTile(
|
||||||
icon: LineIcons.envelope,
|
icon: Icons.email_outlined,
|
||||||
title: 'Email',
|
title: 'Email',
|
||||||
subtitle: user.email,
|
subtitle: 'john.doe@business.com',
|
||||||
onTap: () {
|
onTap: () {
|
||||||
// Edit email
|
// Edit email
|
||||||
},
|
},
|
||||||
@ -53,9 +49,31 @@ class ProfileAccountInfo extends StatelessWidget {
|
|||||||
ProfileDivider(),
|
ProfileDivider(),
|
||||||
|
|
||||||
ProfileTile(
|
ProfileTile(
|
||||||
icon: LineIcons.calendarAlt,
|
icon: Icons.phone_outlined,
|
||||||
|
title: 'Phone Number',
|
||||||
|
subtitle: '+62 812 3456 7890',
|
||||||
|
onTap: () {
|
||||||
|
// Edit phone
|
||||||
|
},
|
||||||
|
),
|
||||||
|
|
||||||
|
ProfileDivider(),
|
||||||
|
|
||||||
|
ProfileTile(
|
||||||
|
icon: Icons.location_on_outlined,
|
||||||
|
title: 'Address',
|
||||||
|
subtitle: 'Jl. Merdeka No. 123, Jakarta',
|
||||||
|
onTap: () {
|
||||||
|
// Edit address
|
||||||
|
},
|
||||||
|
),
|
||||||
|
|
||||||
|
ProfileDivider(),
|
||||||
|
|
||||||
|
ProfileTile(
|
||||||
|
icon: Icons.calendar_today_outlined,
|
||||||
title: 'Member Since',
|
title: 'Member Since',
|
||||||
subtitle: user.createdAt.toDate,
|
subtitle: 'January 15, 2024',
|
||||||
showArrow: false,
|
showArrow: false,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|||||||
@ -1,15 +1,12 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'dart:math' as math;
|
import 'dart:math' as math;
|
||||||
|
|
||||||
import '../../../../common/extension/extension.dart';
|
|
||||||
import '../../../../common/painter/wave_painter.dart';
|
import '../../../../common/painter/wave_painter.dart';
|
||||||
import '../../../../common/theme/theme.dart';
|
import '../../../../common/theme/theme.dart';
|
||||||
import '../../../../domain/auth/auth.dart';
|
|
||||||
import '../../../components/spacer/spacer.dart';
|
import '../../../components/spacer/spacer.dart';
|
||||||
|
|
||||||
class ProfileHeader extends StatefulWidget {
|
class ProfileHeader extends StatefulWidget {
|
||||||
final User user;
|
const ProfileHeader({super.key});
|
||||||
const ProfileHeader({super.key, required this.user});
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<ProfileHeader> createState() => _ProfileHeaderState();
|
State<ProfileHeader> createState() => _ProfileHeaderState();
|
||||||
@ -350,7 +347,7 @@ class _ProfileHeaderState extends State<ProfileHeader>
|
|||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
widget.user.name,
|
'John Doe',
|
||||||
style: AppStyle.h5.copyWith(
|
style: AppStyle.h5.copyWith(
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
color: AppColor.textWhite,
|
color: AppColor.textWhite,
|
||||||
@ -411,7 +408,7 @@ class _ProfileHeaderState extends State<ProfileHeader>
|
|||||||
),
|
),
|
||||||
const SpaceHeight(6),
|
const SpaceHeight(6),
|
||||||
Text(
|
Text(
|
||||||
widget.user.role.toTitleCase,
|
'Business Owner',
|
||||||
style: AppStyle.md.copyWith(
|
style: AppStyle.md.copyWith(
|
||||||
color: AppColor.textWhite,
|
color: AppColor.textWhite,
|
||||||
fontWeight: FontWeight.w600,
|
fontWeight: FontWeight.w600,
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -48,8 +48,5 @@ class AppRouter extends RootStackRouter {
|
|||||||
|
|
||||||
// Finance page
|
// Finance page
|
||||||
AutoRoute(page: FinanceRoute.page),
|
AutoRoute(page: FinanceRoute.page),
|
||||||
|
|
||||||
// Error
|
|
||||||
AutoRoute(page: ErrorRoute.page),
|
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,51 +10,48 @@
|
|||||||
|
|
||||||
// ignore_for_file: no_leading_underscores_for_library_prefixes
|
// ignore_for_file: no_leading_underscores_for_library_prefixes
|
||||||
import 'package:apskel_owner_flutter/presentation/pages/auth/login/login_page.dart'
|
import 'package:apskel_owner_flutter/presentation/pages/auth/login/login_page.dart'
|
||||||
as _i8;
|
as _i7;
|
||||||
import 'package:apskel_owner_flutter/presentation/pages/customer/customer_page.dart'
|
import 'package:apskel_owner_flutter/presentation/pages/customer/customer_page.dart'
|
||||||
as _i1;
|
as _i1;
|
||||||
import 'package:apskel_owner_flutter/presentation/pages/error/error_page.dart'
|
|
||||||
as _i3;
|
|
||||||
import 'package:apskel_owner_flutter/presentation/pages/finance/finance_page.dart'
|
import 'package:apskel_owner_flutter/presentation/pages/finance/finance_page.dart'
|
||||||
as _i4;
|
as _i3;
|
||||||
import 'package:apskel_owner_flutter/presentation/pages/form/daily_task_form_page.dart'
|
import 'package:apskel_owner_flutter/presentation/pages/form/daily_task_form_page.dart'
|
||||||
as _i2;
|
as _i2;
|
||||||
import 'package:apskel_owner_flutter/presentation/pages/home/home_page.dart'
|
import 'package:apskel_owner_flutter/presentation/pages/home/home_page.dart'
|
||||||
as _i5;
|
as _i4;
|
||||||
import 'package:apskel_owner_flutter/presentation/pages/inventory/inventory_page.dart'
|
import 'package:apskel_owner_flutter/presentation/pages/inventory/inventory_page.dart'
|
||||||
as _i6;
|
as _i5;
|
||||||
import 'package:apskel_owner_flutter/presentation/pages/language/language_page.dart'
|
import 'package:apskel_owner_flutter/presentation/pages/language/language_page.dart'
|
||||||
as _i7;
|
as _i6;
|
||||||
import 'package:apskel_owner_flutter/presentation/pages/main/main_page.dart'
|
import 'package:apskel_owner_flutter/presentation/pages/main/main_page.dart'
|
||||||
as _i9;
|
as _i8;
|
||||||
import 'package:apskel_owner_flutter/presentation/pages/product/product_page.dart'
|
import 'package:apskel_owner_flutter/presentation/pages/product/product_page.dart'
|
||||||
as _i10;
|
as _i9;
|
||||||
import 'package:apskel_owner_flutter/presentation/pages/profile/profile_page.dart'
|
import 'package:apskel_owner_flutter/presentation/pages/profile/profile_page.dart'
|
||||||
as _i11;
|
as _i10;
|
||||||
import 'package:apskel_owner_flutter/presentation/pages/purchase/purchase_page.dart'
|
import 'package:apskel_owner_flutter/presentation/pages/purchase/purchase_page.dart'
|
||||||
as _i12;
|
as _i11;
|
||||||
import 'package:apskel_owner_flutter/presentation/pages/report/report_page.dart'
|
import 'package:apskel_owner_flutter/presentation/pages/report/report_page.dart'
|
||||||
as _i13;
|
as _i12;
|
||||||
import 'package:apskel_owner_flutter/presentation/pages/sales/sales_page.dart'
|
import 'package:apskel_owner_flutter/presentation/pages/sales/sales_page.dart'
|
||||||
as _i14;
|
as _i13;
|
||||||
import 'package:apskel_owner_flutter/presentation/pages/schedule/schedule_page.dart'
|
import 'package:apskel_owner_flutter/presentation/pages/schedule/schedule_page.dart'
|
||||||
as _i15;
|
as _i14;
|
||||||
import 'package:apskel_owner_flutter/presentation/pages/splash/splash_page.dart'
|
import 'package:apskel_owner_flutter/presentation/pages/splash/splash_page.dart'
|
||||||
as _i16;
|
as _i15;
|
||||||
import 'package:apskel_owner_flutter/presentation/pages/transaction/transaction_page.dart'
|
import 'package:apskel_owner_flutter/presentation/pages/transaction/transaction_page.dart'
|
||||||
as _i17;
|
as _i16;
|
||||||
import 'package:auto_route/auto_route.dart' as _i18;
|
import 'package:auto_route/auto_route.dart' as _i17;
|
||||||
import 'package:flutter/material.dart' as _i19;
|
|
||||||
|
|
||||||
/// generated route for
|
/// generated route for
|
||||||
/// [_i1.CustomerPage]
|
/// [_i1.CustomerPage]
|
||||||
class CustomerRoute extends _i18.PageRouteInfo<void> {
|
class CustomerRoute extends _i17.PageRouteInfo<void> {
|
||||||
const CustomerRoute({List<_i18.PageRouteInfo>? children})
|
const CustomerRoute({List<_i17.PageRouteInfo>? children})
|
||||||
: super(CustomerRoute.name, initialChildren: children);
|
: super(CustomerRoute.name, initialChildren: children);
|
||||||
|
|
||||||
static const String name = 'CustomerRoute';
|
static const String name = 'CustomerRoute';
|
||||||
|
|
||||||
static _i18.PageInfo page = _i18.PageInfo(
|
static _i17.PageInfo page = _i17.PageInfo(
|
||||||
name,
|
name,
|
||||||
builder: (data) {
|
builder: (data) {
|
||||||
return const _i1.CustomerPage();
|
return const _i1.CustomerPage();
|
||||||
@ -64,13 +61,13 @@ class CustomerRoute extends _i18.PageRouteInfo<void> {
|
|||||||
|
|
||||||
/// generated route for
|
/// generated route for
|
||||||
/// [_i2.DailyTasksFormPage]
|
/// [_i2.DailyTasksFormPage]
|
||||||
class DailyTasksFormRoute extends _i18.PageRouteInfo<void> {
|
class DailyTasksFormRoute extends _i17.PageRouteInfo<void> {
|
||||||
const DailyTasksFormRoute({List<_i18.PageRouteInfo>? children})
|
const DailyTasksFormRoute({List<_i17.PageRouteInfo>? children})
|
||||||
: super(DailyTasksFormRoute.name, initialChildren: children);
|
: super(DailyTasksFormRoute.name, initialChildren: children);
|
||||||
|
|
||||||
static const String name = 'DailyTasksFormRoute';
|
static const String name = 'DailyTasksFormRoute';
|
||||||
|
|
||||||
static _i18.PageInfo page = _i18.PageInfo(
|
static _i17.PageInfo page = _i17.PageInfo(
|
||||||
name,
|
name,
|
||||||
builder: (data) {
|
builder: (data) {
|
||||||
return const _i2.DailyTasksFormPage();
|
return const _i2.DailyTasksFormPage();
|
||||||
@ -79,303 +76,225 @@ class DailyTasksFormRoute extends _i18.PageRouteInfo<void> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// generated route for
|
/// generated route for
|
||||||
/// [_i3.ErrorPage]
|
/// [_i3.FinancePage]
|
||||||
class ErrorRoute extends _i18.PageRouteInfo<ErrorRouteArgs> {
|
class FinanceRoute extends _i17.PageRouteInfo<void> {
|
||||||
ErrorRoute({
|
const FinanceRoute({List<_i17.PageRouteInfo>? children})
|
||||||
_i19.Key? key,
|
|
||||||
String? title,
|
|
||||||
String? message,
|
|
||||||
_i19.VoidCallback? onRetry,
|
|
||||||
_i19.VoidCallback? onBack,
|
|
||||||
String? errorCode,
|
|
||||||
_i19.IconData? errorIcon,
|
|
||||||
List<_i18.PageRouteInfo>? children,
|
|
||||||
}) : super(
|
|
||||||
ErrorRoute.name,
|
|
||||||
args: ErrorRouteArgs(
|
|
||||||
key: key,
|
|
||||||
title: title,
|
|
||||||
message: message,
|
|
||||||
onRetry: onRetry,
|
|
||||||
onBack: onBack,
|
|
||||||
errorCode: errorCode,
|
|
||||||
errorIcon: errorIcon,
|
|
||||||
),
|
|
||||||
initialChildren: children,
|
|
||||||
);
|
|
||||||
|
|
||||||
static const String name = 'ErrorRoute';
|
|
||||||
|
|
||||||
static _i18.PageInfo page = _i18.PageInfo(
|
|
||||||
name,
|
|
||||||
builder: (data) {
|
|
||||||
final args = data.argsAs<ErrorRouteArgs>(
|
|
||||||
orElse: () => const ErrorRouteArgs(),
|
|
||||||
);
|
|
||||||
return _i3.ErrorPage(
|
|
||||||
key: args.key,
|
|
||||||
title: args.title,
|
|
||||||
message: args.message,
|
|
||||||
onRetry: args.onRetry,
|
|
||||||
onBack: args.onBack,
|
|
||||||
errorCode: args.errorCode,
|
|
||||||
errorIcon: args.errorIcon,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
class ErrorRouteArgs {
|
|
||||||
const ErrorRouteArgs({
|
|
||||||
this.key,
|
|
||||||
this.title,
|
|
||||||
this.message,
|
|
||||||
this.onRetry,
|
|
||||||
this.onBack,
|
|
||||||
this.errorCode,
|
|
||||||
this.errorIcon,
|
|
||||||
});
|
|
||||||
|
|
||||||
final _i19.Key? key;
|
|
||||||
|
|
||||||
final String? title;
|
|
||||||
|
|
||||||
final String? message;
|
|
||||||
|
|
||||||
final _i19.VoidCallback? onRetry;
|
|
||||||
|
|
||||||
final _i19.VoidCallback? onBack;
|
|
||||||
|
|
||||||
final String? errorCode;
|
|
||||||
|
|
||||||
final _i19.IconData? errorIcon;
|
|
||||||
|
|
||||||
@override
|
|
||||||
String toString() {
|
|
||||||
return 'ErrorRouteArgs{key: $key, title: $title, message: $message, onRetry: $onRetry, onBack: $onBack, errorCode: $errorCode, errorIcon: $errorIcon}';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// generated route for
|
|
||||||
/// [_i4.FinancePage]
|
|
||||||
class FinanceRoute extends _i18.PageRouteInfo<void> {
|
|
||||||
const FinanceRoute({List<_i18.PageRouteInfo>? children})
|
|
||||||
: super(FinanceRoute.name, initialChildren: children);
|
: super(FinanceRoute.name, initialChildren: children);
|
||||||
|
|
||||||
static const String name = 'FinanceRoute';
|
static const String name = 'FinanceRoute';
|
||||||
|
|
||||||
static _i18.PageInfo page = _i18.PageInfo(
|
static _i17.PageInfo page = _i17.PageInfo(
|
||||||
name,
|
name,
|
||||||
builder: (data) {
|
builder: (data) {
|
||||||
return _i18.WrappedRoute(child: const _i4.FinancePage());
|
return const _i3.FinancePage();
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// generated route for
|
/// generated route for
|
||||||
/// [_i5.HomePage]
|
/// [_i4.HomePage]
|
||||||
class HomeRoute extends _i18.PageRouteInfo<void> {
|
class HomeRoute extends _i17.PageRouteInfo<void> {
|
||||||
const HomeRoute({List<_i18.PageRouteInfo>? children})
|
const HomeRoute({List<_i17.PageRouteInfo>? children})
|
||||||
: super(HomeRoute.name, initialChildren: children);
|
: super(HomeRoute.name, initialChildren: children);
|
||||||
|
|
||||||
static const String name = 'HomeRoute';
|
static const String name = 'HomeRoute';
|
||||||
|
|
||||||
static _i18.PageInfo page = _i18.PageInfo(
|
static _i17.PageInfo page = _i17.PageInfo(
|
||||||
name,
|
name,
|
||||||
builder: (data) {
|
builder: (data) {
|
||||||
return const _i5.HomePage();
|
return const _i4.HomePage();
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// generated route for
|
/// generated route for
|
||||||
/// [_i6.InventoryPage]
|
/// [_i5.InventoryPage]
|
||||||
class InventoryRoute extends _i18.PageRouteInfo<void> {
|
class InventoryRoute extends _i17.PageRouteInfo<void> {
|
||||||
const InventoryRoute({List<_i18.PageRouteInfo>? children})
|
const InventoryRoute({List<_i17.PageRouteInfo>? children})
|
||||||
: super(InventoryRoute.name, initialChildren: children);
|
: super(InventoryRoute.name, initialChildren: children);
|
||||||
|
|
||||||
static const String name = 'InventoryRoute';
|
static const String name = 'InventoryRoute';
|
||||||
|
|
||||||
static _i18.PageInfo page = _i18.PageInfo(
|
static _i17.PageInfo page = _i17.PageInfo(
|
||||||
name,
|
name,
|
||||||
builder: (data) {
|
builder: (data) {
|
||||||
return const _i6.InventoryPage();
|
return const _i5.InventoryPage();
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// generated route for
|
/// generated route for
|
||||||
/// [_i7.LanguagePage]
|
/// [_i6.LanguagePage]
|
||||||
class LanguageRoute extends _i18.PageRouteInfo<void> {
|
class LanguageRoute extends _i17.PageRouteInfo<void> {
|
||||||
const LanguageRoute({List<_i18.PageRouteInfo>? children})
|
const LanguageRoute({List<_i17.PageRouteInfo>? children})
|
||||||
: super(LanguageRoute.name, initialChildren: children);
|
: super(LanguageRoute.name, initialChildren: children);
|
||||||
|
|
||||||
static const String name = 'LanguageRoute';
|
static const String name = 'LanguageRoute';
|
||||||
|
|
||||||
static _i18.PageInfo page = _i18.PageInfo(
|
static _i17.PageInfo page = _i17.PageInfo(
|
||||||
name,
|
name,
|
||||||
builder: (data) {
|
builder: (data) {
|
||||||
return const _i7.LanguagePage();
|
return const _i6.LanguagePage();
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// generated route for
|
/// generated route for
|
||||||
/// [_i8.LoginPage]
|
/// [_i7.LoginPage]
|
||||||
class LoginRoute extends _i18.PageRouteInfo<void> {
|
class LoginRoute extends _i17.PageRouteInfo<void> {
|
||||||
const LoginRoute({List<_i18.PageRouteInfo>? children})
|
const LoginRoute({List<_i17.PageRouteInfo>? children})
|
||||||
: super(LoginRoute.name, initialChildren: children);
|
: super(LoginRoute.name, initialChildren: children);
|
||||||
|
|
||||||
static const String name = 'LoginRoute';
|
static const String name = 'LoginRoute';
|
||||||
|
|
||||||
static _i18.PageInfo page = _i18.PageInfo(
|
static _i17.PageInfo page = _i17.PageInfo(
|
||||||
name,
|
name,
|
||||||
builder: (data) {
|
builder: (data) {
|
||||||
return _i18.WrappedRoute(child: const _i8.LoginPage());
|
return _i17.WrappedRoute(child: const _i7.LoginPage());
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// generated route for
|
/// generated route for
|
||||||
/// [_i9.MainPage]
|
/// [_i8.MainPage]
|
||||||
class MainRoute extends _i18.PageRouteInfo<void> {
|
class MainRoute extends _i17.PageRouteInfo<void> {
|
||||||
const MainRoute({List<_i18.PageRouteInfo>? children})
|
const MainRoute({List<_i17.PageRouteInfo>? children})
|
||||||
: super(MainRoute.name, initialChildren: children);
|
: super(MainRoute.name, initialChildren: children);
|
||||||
|
|
||||||
static const String name = 'MainRoute';
|
static const String name = 'MainRoute';
|
||||||
|
|
||||||
static _i18.PageInfo page = _i18.PageInfo(
|
static _i17.PageInfo page = _i17.PageInfo(
|
||||||
name,
|
name,
|
||||||
builder: (data) {
|
builder: (data) {
|
||||||
return const _i9.MainPage();
|
return const _i8.MainPage();
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// generated route for
|
/// generated route for
|
||||||
/// [_i10.ProductPage]
|
/// [_i9.ProductPage]
|
||||||
class ProductRoute extends _i18.PageRouteInfo<void> {
|
class ProductRoute extends _i17.PageRouteInfo<void> {
|
||||||
const ProductRoute({List<_i18.PageRouteInfo>? children})
|
const ProductRoute({List<_i17.PageRouteInfo>? children})
|
||||||
: super(ProductRoute.name, initialChildren: children);
|
: super(ProductRoute.name, initialChildren: children);
|
||||||
|
|
||||||
static const String name = 'ProductRoute';
|
static const String name = 'ProductRoute';
|
||||||
|
|
||||||
static _i18.PageInfo page = _i18.PageInfo(
|
static _i17.PageInfo page = _i17.PageInfo(
|
||||||
name,
|
name,
|
||||||
builder: (data) {
|
builder: (data) {
|
||||||
return _i18.WrappedRoute(child: const _i10.ProductPage());
|
return const _i9.ProductPage();
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// generated route for
|
/// generated route for
|
||||||
/// [_i11.ProfilePage]
|
/// [_i10.ProfilePage]
|
||||||
class ProfileRoute extends _i18.PageRouteInfo<void> {
|
class ProfileRoute extends _i17.PageRouteInfo<void> {
|
||||||
const ProfileRoute({List<_i18.PageRouteInfo>? children})
|
const ProfileRoute({List<_i17.PageRouteInfo>? children})
|
||||||
: super(ProfileRoute.name, initialChildren: children);
|
: super(ProfileRoute.name, initialChildren: children);
|
||||||
|
|
||||||
static const String name = 'ProfileRoute';
|
static const String name = 'ProfileRoute';
|
||||||
|
|
||||||
static _i18.PageInfo page = _i18.PageInfo(
|
static _i17.PageInfo page = _i17.PageInfo(
|
||||||
name,
|
name,
|
||||||
builder: (data) {
|
builder: (data) {
|
||||||
return _i18.WrappedRoute(child: const _i11.ProfilePage());
|
return const _i10.ProfilePage();
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// generated route for
|
/// generated route for
|
||||||
/// [_i12.PurchasePage]
|
/// [_i11.PurchasePage]
|
||||||
class PurchaseRoute extends _i18.PageRouteInfo<void> {
|
class PurchaseRoute extends _i17.PageRouteInfo<void> {
|
||||||
const PurchaseRoute({List<_i18.PageRouteInfo>? children})
|
const PurchaseRoute({List<_i17.PageRouteInfo>? children})
|
||||||
: super(PurchaseRoute.name, initialChildren: children);
|
: super(PurchaseRoute.name, initialChildren: children);
|
||||||
|
|
||||||
static const String name = 'PurchaseRoute';
|
static const String name = 'PurchaseRoute';
|
||||||
|
|
||||||
static _i18.PageInfo page = _i18.PageInfo(
|
static _i17.PageInfo page = _i17.PageInfo(
|
||||||
name,
|
name,
|
||||||
builder: (data) {
|
builder: (data) {
|
||||||
return const _i12.PurchasePage();
|
return const _i11.PurchasePage();
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// generated route for
|
/// generated route for
|
||||||
/// [_i13.ReportPage]
|
/// [_i12.ReportPage]
|
||||||
class ReportRoute extends _i18.PageRouteInfo<void> {
|
class ReportRoute extends _i17.PageRouteInfo<void> {
|
||||||
const ReportRoute({List<_i18.PageRouteInfo>? children})
|
const ReportRoute({List<_i17.PageRouteInfo>? children})
|
||||||
: super(ReportRoute.name, initialChildren: children);
|
: super(ReportRoute.name, initialChildren: children);
|
||||||
|
|
||||||
static const String name = 'ReportRoute';
|
static const String name = 'ReportRoute';
|
||||||
|
|
||||||
static _i18.PageInfo page = _i18.PageInfo(
|
static _i17.PageInfo page = _i17.PageInfo(
|
||||||
name,
|
name,
|
||||||
builder: (data) {
|
builder: (data) {
|
||||||
return const _i13.ReportPage();
|
return const _i12.ReportPage();
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// generated route for
|
/// generated route for
|
||||||
/// [_i14.SalesPage]
|
/// [_i13.SalesPage]
|
||||||
class SalesRoute extends _i18.PageRouteInfo<void> {
|
class SalesRoute extends _i17.PageRouteInfo<void> {
|
||||||
const SalesRoute({List<_i18.PageRouteInfo>? children})
|
const SalesRoute({List<_i17.PageRouteInfo>? children})
|
||||||
: super(SalesRoute.name, initialChildren: children);
|
: super(SalesRoute.name, initialChildren: children);
|
||||||
|
|
||||||
static const String name = 'SalesRoute';
|
static const String name = 'SalesRoute';
|
||||||
|
|
||||||
static _i18.PageInfo page = _i18.PageInfo(
|
static _i17.PageInfo page = _i17.PageInfo(
|
||||||
name,
|
name,
|
||||||
builder: (data) {
|
builder: (data) {
|
||||||
return _i18.WrappedRoute(child: const _i14.SalesPage());
|
return const _i13.SalesPage();
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// generated route for
|
/// generated route for
|
||||||
/// [_i15.SchedulePage]
|
/// [_i14.SchedulePage]
|
||||||
class ScheduleRoute extends _i18.PageRouteInfo<void> {
|
class ScheduleRoute extends _i17.PageRouteInfo<void> {
|
||||||
const ScheduleRoute({List<_i18.PageRouteInfo>? children})
|
const ScheduleRoute({List<_i17.PageRouteInfo>? children})
|
||||||
: super(ScheduleRoute.name, initialChildren: children);
|
: super(ScheduleRoute.name, initialChildren: children);
|
||||||
|
|
||||||
static const String name = 'ScheduleRoute';
|
static const String name = 'ScheduleRoute';
|
||||||
|
|
||||||
static _i18.PageInfo page = _i18.PageInfo(
|
static _i17.PageInfo page = _i17.PageInfo(
|
||||||
name,
|
name,
|
||||||
builder: (data) {
|
builder: (data) {
|
||||||
return const _i15.SchedulePage();
|
return const _i14.SchedulePage();
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// generated route for
|
/// generated route for
|
||||||
/// [_i16.SplashPage]
|
/// [_i15.SplashPage]
|
||||||
class SplashRoute extends _i18.PageRouteInfo<void> {
|
class SplashRoute extends _i17.PageRouteInfo<void> {
|
||||||
const SplashRoute({List<_i18.PageRouteInfo>? children})
|
const SplashRoute({List<_i17.PageRouteInfo>? children})
|
||||||
: super(SplashRoute.name, initialChildren: children);
|
: super(SplashRoute.name, initialChildren: children);
|
||||||
|
|
||||||
static const String name = 'SplashRoute';
|
static const String name = 'SplashRoute';
|
||||||
|
|
||||||
static _i18.PageInfo page = _i18.PageInfo(
|
static _i17.PageInfo page = _i17.PageInfo(
|
||||||
name,
|
name,
|
||||||
builder: (data) {
|
builder: (data) {
|
||||||
return const _i16.SplashPage();
|
return const _i15.SplashPage();
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// generated route for
|
/// generated route for
|
||||||
/// [_i17.TransactionPage]
|
/// [_i16.TransactionPage]
|
||||||
class TransactionRoute extends _i18.PageRouteInfo<void> {
|
class TransactionRoute extends _i17.PageRouteInfo<void> {
|
||||||
const TransactionRoute({List<_i18.PageRouteInfo>? children})
|
const TransactionRoute({List<_i17.PageRouteInfo>? children})
|
||||||
: super(TransactionRoute.name, initialChildren: children);
|
: super(TransactionRoute.name, initialChildren: children);
|
||||||
|
|
||||||
static const String name = 'TransactionRoute';
|
static const String name = 'TransactionRoute';
|
||||||
|
|
||||||
static _i18.PageInfo page = _i18.PageInfo(
|
static _i17.PageInfo page = _i17.PageInfo(
|
||||||
name,
|
name,
|
||||||
builder: (data) {
|
builder: (data) {
|
||||||
return const _i17.TransactionPage();
|
return const _i16.TransactionPage();
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,7 +10,6 @@ import file_selector_macos
|
|||||||
import package_info_plus
|
import package_info_plus
|
||||||
import path_provider_foundation
|
import path_provider_foundation
|
||||||
import shared_preferences_foundation
|
import shared_preferences_foundation
|
||||||
import sqflite_darwin
|
|
||||||
|
|
||||||
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
||||||
ConnectivityPlusPlugin.register(with: registry.registrar(forPlugin: "ConnectivityPlusPlugin"))
|
ConnectivityPlusPlugin.register(with: registry.registrar(forPlugin: "ConnectivityPlusPlugin"))
|
||||||
@ -18,5 +17,4 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
|||||||
FPPPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FPPPackageInfoPlusPlugin"))
|
FPPPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FPPPackageInfoPlusPlugin"))
|
||||||
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
|
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
|
||||||
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
|
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
|
||||||
SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin"))
|
|
||||||
}
|
}
|
||||||
|
|||||||
120
pubspec.lock
120
pubspec.lock
@ -161,30 +161,6 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "8.11.1"
|
version: "8.11.1"
|
||||||
cached_network_image:
|
|
||||||
dependency: "direct main"
|
|
||||||
description:
|
|
||||||
name: cached_network_image
|
|
||||||
sha256: "7c1183e361e5c8b0a0f21a28401eecdbde252441106a9816400dd4c2b2424916"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "3.4.1"
|
|
||||||
cached_network_image_platform_interface:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: cached_network_image_platform_interface
|
|
||||||
sha256: "35814b016e37fbdc91f7ae18c8caf49ba5c88501813f73ce8a07027a395e2829"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "4.1.1"
|
|
||||||
cached_network_image_web:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: cached_network_image_web
|
|
||||||
sha256: "980842f4e8e2535b8dbd3d5ca0b1f0ba66bf61d14cc3a17a9b4788a3685ba062"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "1.3.1"
|
|
||||||
characters:
|
characters:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -446,14 +422,6 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "9.1.1"
|
version: "9.1.1"
|
||||||
flutter_cache_manager:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: flutter_cache_manager
|
|
||||||
sha256: "400b6592f16a4409a7f2bb929a9a7e38c72cceb8ffb99ee57bbf2cb2cecf8386"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "3.4.1"
|
|
||||||
flutter_gen_core:
|
flutter_gen_core:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -845,14 +813,6 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.5.0"
|
version: "0.5.0"
|
||||||
octo_image:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: octo_image
|
|
||||||
sha256: "34faa6639a78c7e3cbe79be6f9f96535867e879748ade7d17c9b1ae7536293bd"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "2.1.0"
|
|
||||||
package_config:
|
package_config:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -1013,14 +973,6 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.1.0"
|
version: "4.1.0"
|
||||||
rxdart:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: rxdart
|
|
||||||
sha256: "5c3004a4a8dbb94bd4bf5412a4def4acdaa12e12f269737a5751369e12d1a962"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "0.28.0"
|
|
||||||
shared_preferences:
|
shared_preferences:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@ -1093,14 +1045,6 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.0.0"
|
version: "3.0.0"
|
||||||
shimmer:
|
|
||||||
dependency: "direct main"
|
|
||||||
description:
|
|
||||||
name: shimmer
|
|
||||||
sha256: "5f88c883a22e9f9f299e5ba0e4f7e6054857224976a5d9f839d4ebdc94a14ac9"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "3.0.0"
|
|
||||||
simple_gesture_detector:
|
simple_gesture_detector:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -1138,54 +1082,6 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.10.1"
|
version: "1.10.1"
|
||||||
sprintf:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: sprintf
|
|
||||||
sha256: "1fc9ffe69d4df602376b52949af107d8f5703b77cda567c4d7d86a0693120f23"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "7.0.0"
|
|
||||||
sqflite:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: sqflite
|
|
||||||
sha256: e2297b1da52f127bc7a3da11439985d9b536f75070f3325e62ada69a5c585d03
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "2.4.2"
|
|
||||||
sqflite_android:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: sqflite_android
|
|
||||||
sha256: "2b3070c5fa881839f8b402ee4a39c1b4d561704d4ebbbcfb808a119bc2a1701b"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "2.4.1"
|
|
||||||
sqflite_common:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: sqflite_common
|
|
||||||
sha256: "6ef422a4525ecc601db6c0a2233ff448c731307906e92cabc9ba292afaae16a6"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "2.5.6"
|
|
||||||
sqflite_darwin:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: sqflite_darwin
|
|
||||||
sha256: "279832e5cde3fe99e8571879498c9211f3ca6391b0d818df4e17d9fff5c6ccb3"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "2.4.2"
|
|
||||||
sqflite_platform_interface:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: sqflite_platform_interface
|
|
||||||
sha256: "8dd4515c7bdcae0a785b0062859336de775e8c65db81ae33dd5445f35be61920"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "2.4.0"
|
|
||||||
stack_trace:
|
stack_trace:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -1218,14 +1114,6 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.4.1"
|
version: "1.4.1"
|
||||||
synchronized:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: synchronized
|
|
||||||
sha256: c254ade258ec8282947a0acbbc90b9575b4f19673533ee46f2f6e9b3aeefd7c0
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "3.4.0"
|
|
||||||
table_calendar:
|
table_calendar:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@ -1274,14 +1162,6 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.4.0"
|
version: "1.4.0"
|
||||||
uuid:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: uuid
|
|
||||||
sha256: a5be9ef6618a7ac1e964353ef476418026db906c4facdedaa299b7a2e71690ff
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "4.5.1"
|
|
||||||
vector_graphics:
|
vector_graphics:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|||||||
@ -40,8 +40,6 @@ dependencies:
|
|||||||
table_calendar: ^3.2.0
|
table_calendar: ^3.2.0
|
||||||
package_info_plus: ^8.3.1
|
package_info_plus: ^8.3.1
|
||||||
loader_overlay: ^5.0.0
|
loader_overlay: ^5.0.0
|
||||||
shimmer: ^3.0.0
|
|
||||||
cached_network_image: ^3.4.1
|
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user