Compare commits
5 Commits
bc95336a19
...
b4d2d859eb
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b4d2d859eb | ||
|
|
c367bd2cd9 | ||
|
|
d3f2cb300c | ||
|
|
62eb15b27f | ||
|
|
b8055c8eab |
90
lib/application/order/order_loader/order_loader_bloc.dart
Normal file
90
lib/application/order/order_loader/order_loader_bloc.dart
Normal file
@ -0,0 +1,90 @@
|
||||
import 'package:dartz/dartz.dart' hide Order;
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'package:injectable/injectable.dart' hide Order;
|
||||
|
||||
import '../../../domain/order/order.dart';
|
||||
|
||||
part 'order_loader_event.dart';
|
||||
part 'order_loader_state.dart';
|
||||
part 'order_loader_bloc.freezed.dart';
|
||||
|
||||
@injectable
|
||||
class OrderLoaderBloc extends Bloc<OrderLoaderEvent, OrderLoaderState> {
|
||||
final IOrderRepository _repository;
|
||||
OrderLoaderBloc(this._repository) : super(OrderLoaderState.initial()) {
|
||||
on<OrderLoaderEvent>(_onOrderLoaderEvent);
|
||||
}
|
||||
|
||||
Future<void> _onOrderLoaderEvent(
|
||||
OrderLoaderEvent event,
|
||||
Emitter<OrderLoaderState> emit,
|
||||
) {
|
||||
return event.map(
|
||||
statusChanged: (e) async {
|
||||
emit(state.copyWith(status: e.status));
|
||||
},
|
||||
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<OrderLoaderState> _mapFetchedToState(
|
||||
OrderLoaderState state, {
|
||||
bool isRefresh = false,
|
||||
}) async {
|
||||
state = state.copyWith(isFetching: false);
|
||||
|
||||
if (state.hasReachedMax && state.orders.isNotEmpty && !isRefresh) {
|
||||
return state;
|
||||
}
|
||||
|
||||
if (isRefresh) {
|
||||
state = state.copyWith(
|
||||
page: 1,
|
||||
failureOptionOrder: none(),
|
||||
hasReachedMax: false,
|
||||
orders: [],
|
||||
);
|
||||
}
|
||||
|
||||
final failureOrOrder = await _repository.get(
|
||||
status: state.status,
|
||||
page: state.page,
|
||||
search: state.search,
|
||||
);
|
||||
|
||||
state = failureOrOrder.fold(
|
||||
(f) {
|
||||
if (state.orders.isNotEmpty) {
|
||||
return state.copyWith(hasReachedMax: true);
|
||||
}
|
||||
return state.copyWith(failureOptionOrder: optionOf(f));
|
||||
},
|
||||
(orders) {
|
||||
return state.copyWith(
|
||||
orders: List.from(state.orders)..addAll(orders),
|
||||
failureOptionOrder: none(),
|
||||
page: state.page + 1,
|
||||
hasReachedMax: orders.length < 10,
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
return state;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,815 @@
|
||||
// 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 'order_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 _$OrderLoaderEvent {
|
||||
@optionalTypeArgs
|
||||
TResult when<TResult extends Object?>({
|
||||
required TResult Function(String status) statusChanged,
|
||||
required TResult Function(String search) searchChanged,
|
||||
required TResult Function(bool isRefresh) fetched,
|
||||
}) => throw _privateConstructorUsedError;
|
||||
@optionalTypeArgs
|
||||
TResult? whenOrNull<TResult extends Object?>({
|
||||
TResult? Function(String status)? statusChanged,
|
||||
TResult? Function(String search)? searchChanged,
|
||||
TResult? Function(bool isRefresh)? fetched,
|
||||
}) => throw _privateConstructorUsedError;
|
||||
@optionalTypeArgs
|
||||
TResult maybeWhen<TResult extends Object?>({
|
||||
TResult Function(String status)? statusChanged,
|
||||
TResult Function(String search)? searchChanged,
|
||||
TResult Function(bool isRefresh)? fetched,
|
||||
required TResult orElse(),
|
||||
}) => throw _privateConstructorUsedError;
|
||||
@optionalTypeArgs
|
||||
TResult map<TResult extends Object?>({
|
||||
required TResult Function(_StatusChanged value) statusChanged,
|
||||
required TResult Function(_SearchChanged value) searchChanged,
|
||||
required TResult Function(_Fetched value) fetched,
|
||||
}) => throw _privateConstructorUsedError;
|
||||
@optionalTypeArgs
|
||||
TResult? mapOrNull<TResult extends Object?>({
|
||||
TResult? Function(_StatusChanged value)? statusChanged,
|
||||
TResult? Function(_SearchChanged value)? searchChanged,
|
||||
TResult? Function(_Fetched value)? fetched,
|
||||
}) => throw _privateConstructorUsedError;
|
||||
@optionalTypeArgs
|
||||
TResult maybeMap<TResult extends Object?>({
|
||||
TResult Function(_StatusChanged value)? statusChanged,
|
||||
TResult Function(_SearchChanged value)? searchChanged,
|
||||
TResult Function(_Fetched value)? fetched,
|
||||
required TResult orElse(),
|
||||
}) => throw _privateConstructorUsedError;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class $OrderLoaderEventCopyWith<$Res> {
|
||||
factory $OrderLoaderEventCopyWith(
|
||||
OrderLoaderEvent value,
|
||||
$Res Function(OrderLoaderEvent) then,
|
||||
) = _$OrderLoaderEventCopyWithImpl<$Res, OrderLoaderEvent>;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class _$OrderLoaderEventCopyWithImpl<$Res, $Val extends OrderLoaderEvent>
|
||||
implements $OrderLoaderEventCopyWith<$Res> {
|
||||
_$OrderLoaderEventCopyWithImpl(this._value, this._then);
|
||||
|
||||
// ignore: unused_field
|
||||
final $Val _value;
|
||||
// ignore: unused_field
|
||||
final $Res Function($Val) _then;
|
||||
|
||||
/// Create a copy of OrderLoaderEvent
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class _$$StatusChangedImplCopyWith<$Res> {
|
||||
factory _$$StatusChangedImplCopyWith(
|
||||
_$StatusChangedImpl value,
|
||||
$Res Function(_$StatusChangedImpl) then,
|
||||
) = __$$StatusChangedImplCopyWithImpl<$Res>;
|
||||
@useResult
|
||||
$Res call({String status});
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class __$$StatusChangedImplCopyWithImpl<$Res>
|
||||
extends _$OrderLoaderEventCopyWithImpl<$Res, _$StatusChangedImpl>
|
||||
implements _$$StatusChangedImplCopyWith<$Res> {
|
||||
__$$StatusChangedImplCopyWithImpl(
|
||||
_$StatusChangedImpl _value,
|
||||
$Res Function(_$StatusChangedImpl) _then,
|
||||
) : super(_value, _then);
|
||||
|
||||
/// Create a copy of OrderLoaderEvent
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline')
|
||||
@override
|
||||
$Res call({Object? status = null}) {
|
||||
return _then(
|
||||
_$StatusChangedImpl(
|
||||
null == status
|
||||
? _value.status
|
||||
: status // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
|
||||
class _$StatusChangedImpl implements _StatusChanged {
|
||||
const _$StatusChangedImpl(this.status);
|
||||
|
||||
@override
|
||||
final String status;
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'OrderLoaderEvent.statusChanged(status: $status)';
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) ||
|
||||
(other.runtimeType == runtimeType &&
|
||||
other is _$StatusChangedImpl &&
|
||||
(identical(other.status, status) || other.status == status));
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType, status);
|
||||
|
||||
/// Create a copy of OrderLoaderEvent
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
@pragma('vm:prefer-inline')
|
||||
_$$StatusChangedImplCopyWith<_$StatusChangedImpl> get copyWith =>
|
||||
__$$StatusChangedImplCopyWithImpl<_$StatusChangedImpl>(this, _$identity);
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult when<TResult extends Object?>({
|
||||
required TResult Function(String status) statusChanged,
|
||||
required TResult Function(String search) searchChanged,
|
||||
required TResult Function(bool isRefresh) fetched,
|
||||
}) {
|
||||
return statusChanged(status);
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult? whenOrNull<TResult extends Object?>({
|
||||
TResult? Function(String status)? statusChanged,
|
||||
TResult? Function(String search)? searchChanged,
|
||||
TResult? Function(bool isRefresh)? fetched,
|
||||
}) {
|
||||
return statusChanged?.call(status);
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult maybeWhen<TResult extends Object?>({
|
||||
TResult Function(String status)? statusChanged,
|
||||
TResult Function(String search)? searchChanged,
|
||||
TResult Function(bool isRefresh)? fetched,
|
||||
required TResult orElse(),
|
||||
}) {
|
||||
if (statusChanged != null) {
|
||||
return statusChanged(status);
|
||||
}
|
||||
return orElse();
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult map<TResult extends Object?>({
|
||||
required TResult Function(_StatusChanged value) statusChanged,
|
||||
required TResult Function(_SearchChanged value) searchChanged,
|
||||
required TResult Function(_Fetched value) fetched,
|
||||
}) {
|
||||
return statusChanged(this);
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult? mapOrNull<TResult extends Object?>({
|
||||
TResult? Function(_StatusChanged value)? statusChanged,
|
||||
TResult? Function(_SearchChanged value)? searchChanged,
|
||||
TResult? Function(_Fetched value)? fetched,
|
||||
}) {
|
||||
return statusChanged?.call(this);
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult maybeMap<TResult extends Object?>({
|
||||
TResult Function(_StatusChanged value)? statusChanged,
|
||||
TResult Function(_SearchChanged value)? searchChanged,
|
||||
TResult Function(_Fetched value)? fetched,
|
||||
required TResult orElse(),
|
||||
}) {
|
||||
if (statusChanged != null) {
|
||||
return statusChanged(this);
|
||||
}
|
||||
return orElse();
|
||||
}
|
||||
}
|
||||
|
||||
abstract class _StatusChanged implements OrderLoaderEvent {
|
||||
const factory _StatusChanged(final String status) = _$StatusChangedImpl;
|
||||
|
||||
String get status;
|
||||
|
||||
/// Create a copy of OrderLoaderEvent
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
_$$StatusChangedImplCopyWith<_$StatusChangedImpl> 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 _$OrderLoaderEventCopyWithImpl<$Res, _$SearchChangedImpl>
|
||||
implements _$$SearchChangedImplCopyWith<$Res> {
|
||||
__$$SearchChangedImplCopyWithImpl(
|
||||
_$SearchChangedImpl _value,
|
||||
$Res Function(_$SearchChangedImpl) _then,
|
||||
) : super(_value, _then);
|
||||
|
||||
/// Create a copy of OrderLoaderEvent
|
||||
/// 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 'OrderLoaderEvent.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 OrderLoaderEvent
|
||||
/// 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 status) statusChanged,
|
||||
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 status)? statusChanged,
|
||||
TResult? Function(String search)? searchChanged,
|
||||
TResult? Function(bool isRefresh)? fetched,
|
||||
}) {
|
||||
return searchChanged?.call(search);
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult maybeWhen<TResult extends Object?>({
|
||||
TResult Function(String status)? statusChanged,
|
||||
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(_StatusChanged value) statusChanged,
|
||||
required TResult Function(_SearchChanged value) searchChanged,
|
||||
required TResult Function(_Fetched value) fetched,
|
||||
}) {
|
||||
return searchChanged(this);
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult? mapOrNull<TResult extends Object?>({
|
||||
TResult? Function(_StatusChanged value)? statusChanged,
|
||||
TResult? Function(_SearchChanged value)? searchChanged,
|
||||
TResult? Function(_Fetched value)? fetched,
|
||||
}) {
|
||||
return searchChanged?.call(this);
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult maybeMap<TResult extends Object?>({
|
||||
TResult Function(_StatusChanged value)? statusChanged,
|
||||
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 OrderLoaderEvent {
|
||||
const factory _SearchChanged(final String search) = _$SearchChangedImpl;
|
||||
|
||||
String get search;
|
||||
|
||||
/// Create a copy of OrderLoaderEvent
|
||||
/// 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 _$OrderLoaderEventCopyWithImpl<$Res, _$FetchedImpl>
|
||||
implements _$$FetchedImplCopyWith<$Res> {
|
||||
__$$FetchedImplCopyWithImpl(
|
||||
_$FetchedImpl _value,
|
||||
$Res Function(_$FetchedImpl) _then,
|
||||
) : super(_value, _then);
|
||||
|
||||
/// Create a copy of OrderLoaderEvent
|
||||
/// 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 'OrderLoaderEvent.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 OrderLoaderEvent
|
||||
/// 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 status) statusChanged,
|
||||
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 status)? statusChanged,
|
||||
TResult? Function(String search)? searchChanged,
|
||||
TResult? Function(bool isRefresh)? fetched,
|
||||
}) {
|
||||
return fetched?.call(isRefresh);
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult maybeWhen<TResult extends Object?>({
|
||||
TResult Function(String status)? statusChanged,
|
||||
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(_StatusChanged value) statusChanged,
|
||||
required TResult Function(_SearchChanged value) searchChanged,
|
||||
required TResult Function(_Fetched value) fetched,
|
||||
}) {
|
||||
return fetched(this);
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult? mapOrNull<TResult extends Object?>({
|
||||
TResult? Function(_StatusChanged value)? statusChanged,
|
||||
TResult? Function(_SearchChanged value)? searchChanged,
|
||||
TResult? Function(_Fetched value)? fetched,
|
||||
}) {
|
||||
return fetched?.call(this);
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult maybeMap<TResult extends Object?>({
|
||||
TResult Function(_StatusChanged value)? statusChanged,
|
||||
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 OrderLoaderEvent {
|
||||
const factory _Fetched({final bool isRefresh}) = _$FetchedImpl;
|
||||
|
||||
bool get isRefresh;
|
||||
|
||||
/// Create a copy of OrderLoaderEvent
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
_$$FetchedImplCopyWith<_$FetchedImpl> get copyWith =>
|
||||
throw _privateConstructorUsedError;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
mixin _$OrderLoaderState {
|
||||
List<Order> get orders => throw _privateConstructorUsedError;
|
||||
Option<OrderFailure> get failureOptionOrder =>
|
||||
throw _privateConstructorUsedError;
|
||||
String? get status => 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 OrderLoaderState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
$OrderLoaderStateCopyWith<OrderLoaderState> get copyWith =>
|
||||
throw _privateConstructorUsedError;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class $OrderLoaderStateCopyWith<$Res> {
|
||||
factory $OrderLoaderStateCopyWith(
|
||||
OrderLoaderState value,
|
||||
$Res Function(OrderLoaderState) then,
|
||||
) = _$OrderLoaderStateCopyWithImpl<$Res, OrderLoaderState>;
|
||||
@useResult
|
||||
$Res call({
|
||||
List<Order> orders,
|
||||
Option<OrderFailure> failureOptionOrder,
|
||||
String? status,
|
||||
String? search,
|
||||
bool isFetching,
|
||||
bool hasReachedMax,
|
||||
int page,
|
||||
});
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class _$OrderLoaderStateCopyWithImpl<$Res, $Val extends OrderLoaderState>
|
||||
implements $OrderLoaderStateCopyWith<$Res> {
|
||||
_$OrderLoaderStateCopyWithImpl(this._value, this._then);
|
||||
|
||||
// ignore: unused_field
|
||||
final $Val _value;
|
||||
// ignore: unused_field
|
||||
final $Res Function($Val) _then;
|
||||
|
||||
/// Create a copy of OrderLoaderState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline')
|
||||
@override
|
||||
$Res call({
|
||||
Object? orders = null,
|
||||
Object? failureOptionOrder = null,
|
||||
Object? status = freezed,
|
||||
Object? search = freezed,
|
||||
Object? isFetching = null,
|
||||
Object? hasReachedMax = null,
|
||||
Object? page = null,
|
||||
}) {
|
||||
return _then(
|
||||
_value.copyWith(
|
||||
orders: null == orders
|
||||
? _value.orders
|
||||
: orders // ignore: cast_nullable_to_non_nullable
|
||||
as List<Order>,
|
||||
failureOptionOrder: null == failureOptionOrder
|
||||
? _value.failureOptionOrder
|
||||
: failureOptionOrder // ignore: cast_nullable_to_non_nullable
|
||||
as Option<OrderFailure>,
|
||||
status: freezed == status
|
||||
? _value.status
|
||||
: status // 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 _$$OrderLoaderStateImplCopyWith<$Res>
|
||||
implements $OrderLoaderStateCopyWith<$Res> {
|
||||
factory _$$OrderLoaderStateImplCopyWith(
|
||||
_$OrderLoaderStateImpl value,
|
||||
$Res Function(_$OrderLoaderStateImpl) then,
|
||||
) = __$$OrderLoaderStateImplCopyWithImpl<$Res>;
|
||||
@override
|
||||
@useResult
|
||||
$Res call({
|
||||
List<Order> orders,
|
||||
Option<OrderFailure> failureOptionOrder,
|
||||
String? status,
|
||||
String? search,
|
||||
bool isFetching,
|
||||
bool hasReachedMax,
|
||||
int page,
|
||||
});
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class __$$OrderLoaderStateImplCopyWithImpl<$Res>
|
||||
extends _$OrderLoaderStateCopyWithImpl<$Res, _$OrderLoaderStateImpl>
|
||||
implements _$$OrderLoaderStateImplCopyWith<$Res> {
|
||||
__$$OrderLoaderStateImplCopyWithImpl(
|
||||
_$OrderLoaderStateImpl _value,
|
||||
$Res Function(_$OrderLoaderStateImpl) _then,
|
||||
) : super(_value, _then);
|
||||
|
||||
/// Create a copy of OrderLoaderState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline')
|
||||
@override
|
||||
$Res call({
|
||||
Object? orders = null,
|
||||
Object? failureOptionOrder = null,
|
||||
Object? status = freezed,
|
||||
Object? search = freezed,
|
||||
Object? isFetching = null,
|
||||
Object? hasReachedMax = null,
|
||||
Object? page = null,
|
||||
}) {
|
||||
return _then(
|
||||
_$OrderLoaderStateImpl(
|
||||
orders: null == orders
|
||||
? _value._orders
|
||||
: orders // ignore: cast_nullable_to_non_nullable
|
||||
as List<Order>,
|
||||
failureOptionOrder: null == failureOptionOrder
|
||||
? _value.failureOptionOrder
|
||||
: failureOptionOrder // ignore: cast_nullable_to_non_nullable
|
||||
as Option<OrderFailure>,
|
||||
status: freezed == status
|
||||
? _value.status
|
||||
: status // 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 _$OrderLoaderStateImpl implements _OrderLoaderState {
|
||||
const _$OrderLoaderStateImpl({
|
||||
required final List<Order> orders,
|
||||
required this.failureOptionOrder,
|
||||
this.status,
|
||||
this.search,
|
||||
this.isFetching = false,
|
||||
this.hasReachedMax = false,
|
||||
this.page = 1,
|
||||
}) : _orders = orders;
|
||||
|
||||
final List<Order> _orders;
|
||||
@override
|
||||
List<Order> get orders {
|
||||
if (_orders is EqualUnmodifiableListView) return _orders;
|
||||
// ignore: implicit_dynamic_type
|
||||
return EqualUnmodifiableListView(_orders);
|
||||
}
|
||||
|
||||
@override
|
||||
final Option<OrderFailure> failureOptionOrder;
|
||||
@override
|
||||
final String? status;
|
||||
@override
|
||||
final String? search;
|
||||
@override
|
||||
@JsonKey()
|
||||
final bool isFetching;
|
||||
@override
|
||||
@JsonKey()
|
||||
final bool hasReachedMax;
|
||||
@override
|
||||
@JsonKey()
|
||||
final int page;
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'OrderLoaderState(orders: $orders, failureOptionOrder: $failureOptionOrder, status: $status, search: $search, isFetching: $isFetching, hasReachedMax: $hasReachedMax, page: $page)';
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) ||
|
||||
(other.runtimeType == runtimeType &&
|
||||
other is _$OrderLoaderStateImpl &&
|
||||
const DeepCollectionEquality().equals(other._orders, _orders) &&
|
||||
(identical(other.failureOptionOrder, failureOptionOrder) ||
|
||||
other.failureOptionOrder == failureOptionOrder) &&
|
||||
(identical(other.status, status) || other.status == status) &&
|
||||
(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(_orders),
|
||||
failureOptionOrder,
|
||||
status,
|
||||
search,
|
||||
isFetching,
|
||||
hasReachedMax,
|
||||
page,
|
||||
);
|
||||
|
||||
/// Create a copy of OrderLoaderState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
@pragma('vm:prefer-inline')
|
||||
_$$OrderLoaderStateImplCopyWith<_$OrderLoaderStateImpl> get copyWith =>
|
||||
__$$OrderLoaderStateImplCopyWithImpl<_$OrderLoaderStateImpl>(
|
||||
this,
|
||||
_$identity,
|
||||
);
|
||||
}
|
||||
|
||||
abstract class _OrderLoaderState implements OrderLoaderState {
|
||||
const factory _OrderLoaderState({
|
||||
required final List<Order> orders,
|
||||
required final Option<OrderFailure> failureOptionOrder,
|
||||
final String? status,
|
||||
final String? search,
|
||||
final bool isFetching,
|
||||
final bool hasReachedMax,
|
||||
final int page,
|
||||
}) = _$OrderLoaderStateImpl;
|
||||
|
||||
@override
|
||||
List<Order> get orders;
|
||||
@override
|
||||
Option<OrderFailure> get failureOptionOrder;
|
||||
@override
|
||||
String? get status;
|
||||
@override
|
||||
String? get search;
|
||||
@override
|
||||
bool get isFetching;
|
||||
@override
|
||||
bool get hasReachedMax;
|
||||
@override
|
||||
int get page;
|
||||
|
||||
/// Create a copy of OrderLoaderState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
_$$OrderLoaderStateImplCopyWith<_$OrderLoaderStateImpl> get copyWith =>
|
||||
throw _privateConstructorUsedError;
|
||||
}
|
||||
@ -0,0 +1,9 @@
|
||||
part of 'order_loader_bloc.dart';
|
||||
|
||||
@freezed
|
||||
class OrderLoaderEvent with _$OrderLoaderEvent {
|
||||
const factory OrderLoaderEvent.statusChanged(String status) = _StatusChanged;
|
||||
const factory OrderLoaderEvent.searchChanged(String search) = _SearchChanged;
|
||||
const factory OrderLoaderEvent.fetched({@Default(false) bool isRefresh}) =
|
||||
_Fetched;
|
||||
}
|
||||
17
lib/application/order/order_loader/order_loader_state.dart
Normal file
17
lib/application/order/order_loader/order_loader_state.dart
Normal file
@ -0,0 +1,17 @@
|
||||
part of 'order_loader_bloc.dart';
|
||||
|
||||
@freezed
|
||||
class OrderLoaderState with _$OrderLoaderState {
|
||||
const factory OrderLoaderState({
|
||||
required List<Order> orders,
|
||||
required Option<OrderFailure> failureOptionOrder,
|
||||
String? status,
|
||||
String? search,
|
||||
@Default(false) bool isFetching,
|
||||
@Default(false) bool hasReachedMax,
|
||||
@Default(1) int page,
|
||||
}) = _OrderLoaderState;
|
||||
|
||||
factory OrderLoaderState.initial() =>
|
||||
OrderLoaderState(orders: [], failureOptionOrder: none());
|
||||
}
|
||||
@ -24,4 +24,7 @@ class ApiPath {
|
||||
|
||||
// Customer
|
||||
static const String customer = '/api/v1/customers';
|
||||
|
||||
// Order
|
||||
static const String order = '/api/v1/orders';
|
||||
}
|
||||
|
||||
161
lib/domain/order/entities/order_entity.dart
Normal file
161
lib/domain/order/entities/order_entity.dart
Normal file
@ -0,0 +1,161 @@
|
||||
part of '../order.dart';
|
||||
|
||||
@freezed
|
||||
class Order with _$Order {
|
||||
const factory Order({
|
||||
required String id,
|
||||
required String orderNumber,
|
||||
required String outletId,
|
||||
required String userId,
|
||||
required String tableNumber,
|
||||
required String orderType,
|
||||
required String status,
|
||||
required int subtotal,
|
||||
required int taxAmount,
|
||||
required int discountAmount,
|
||||
required int totalAmount,
|
||||
required int totalCost,
|
||||
required int remainingAmount,
|
||||
required String paymentStatus,
|
||||
required int refundAmount,
|
||||
required bool isVoid,
|
||||
required bool isRefund,
|
||||
required String notes,
|
||||
required Map<String, dynamic> metadata,
|
||||
required String createdAt,
|
||||
required String updatedAt,
|
||||
required List<OrderItem> orderItems,
|
||||
required List<OrderPayment> payments,
|
||||
required int totalPaid,
|
||||
required int paymentCount,
|
||||
required String splitType,
|
||||
}) = _Order;
|
||||
|
||||
factory Order.empty() => Order(
|
||||
id: '',
|
||||
orderNumber: '',
|
||||
outletId: '',
|
||||
userId: '',
|
||||
tableNumber: '',
|
||||
orderType: '',
|
||||
status: '',
|
||||
subtotal: 0,
|
||||
taxAmount: 0,
|
||||
discountAmount: 0,
|
||||
totalAmount: 0,
|
||||
totalCost: 0,
|
||||
remainingAmount: 0,
|
||||
paymentStatus: '',
|
||||
refundAmount: 0,
|
||||
isVoid: false,
|
||||
isRefund: false,
|
||||
notes: '',
|
||||
metadata: {},
|
||||
createdAt: '',
|
||||
updatedAt: '',
|
||||
orderItems: [],
|
||||
payments: [],
|
||||
totalPaid: 0,
|
||||
paymentCount: 0,
|
||||
splitType: '',
|
||||
);
|
||||
}
|
||||
|
||||
@freezed
|
||||
class OrderItem with _$OrderItem {
|
||||
const factory OrderItem({
|
||||
required String id,
|
||||
required String orderId,
|
||||
required String productId,
|
||||
required String productName,
|
||||
required int quantity,
|
||||
required int price,
|
||||
required int subtotal,
|
||||
required int discountAmount,
|
||||
required int total,
|
||||
required int cost,
|
||||
required Map<String, dynamic> metadata,
|
||||
required String createdAt,
|
||||
required String updatedAt,
|
||||
}) = _OrderItem;
|
||||
|
||||
factory OrderItem.empty() => OrderItem(
|
||||
id: '',
|
||||
orderId: '',
|
||||
productId: '',
|
||||
productName: '',
|
||||
quantity: 0,
|
||||
price: 0,
|
||||
subtotal: 0,
|
||||
discountAmount: 0,
|
||||
total: 0,
|
||||
cost: 0,
|
||||
metadata: {},
|
||||
createdAt: '',
|
||||
updatedAt: '',
|
||||
);
|
||||
}
|
||||
|
||||
@freezed
|
||||
class OrderPayment with _$OrderPayment {
|
||||
const factory OrderPayment({
|
||||
required String id,
|
||||
required String orderId,
|
||||
required String paymentMethodId,
|
||||
required String paymentMethodName,
|
||||
required String paymentMethodType,
|
||||
required int amount,
|
||||
required String status,
|
||||
required int splitNumber,
|
||||
required int splitTotal,
|
||||
required String splitType,
|
||||
required String splitDescription,
|
||||
required int refundAmount,
|
||||
required Map<String, dynamic> metadata,
|
||||
required String createdAt,
|
||||
required String updatedAt,
|
||||
required List<PaymentOrderItem> paymentOrderItems,
|
||||
}) = _OrderPayment;
|
||||
|
||||
factory OrderPayment.empty() => OrderPayment(
|
||||
id: '',
|
||||
orderId: '',
|
||||
paymentMethodId: '',
|
||||
paymentMethodName: '',
|
||||
paymentMethodType: '',
|
||||
amount: 0,
|
||||
status: '',
|
||||
splitNumber: 0,
|
||||
splitTotal: 0,
|
||||
splitType: '',
|
||||
splitDescription: '',
|
||||
refundAmount: 0,
|
||||
metadata: {},
|
||||
createdAt: '',
|
||||
updatedAt: '',
|
||||
paymentOrderItems: [],
|
||||
);
|
||||
}
|
||||
|
||||
@freezed
|
||||
class PaymentOrderItem with _$PaymentOrderItem {
|
||||
const factory PaymentOrderItem({
|
||||
required String id,
|
||||
required String orderPaymentId,
|
||||
required String orderItemId,
|
||||
required int amount,
|
||||
required int refundAmount,
|
||||
required String createdAt,
|
||||
required String updatedAt,
|
||||
}) = _PaymentOrderItem;
|
||||
|
||||
factory PaymentOrderItem.empty() => PaymentOrderItem(
|
||||
id: '',
|
||||
orderPaymentId: '',
|
||||
orderItemId: '',
|
||||
amount: 0,
|
||||
refundAmount: 0,
|
||||
createdAt: '',
|
||||
updatedAt: '',
|
||||
);
|
||||
}
|
||||
10
lib/domain/order/failures/order_failure.dart
Normal file
10
lib/domain/order/failures/order_failure.dart
Normal file
@ -0,0 +1,10 @@
|
||||
part of '../order.dart';
|
||||
|
||||
@freezed
|
||||
sealed class OrderFailure with _$OrderFailure {
|
||||
const factory OrderFailure.serverError(ApiFailure failure) = _ServerError;
|
||||
const factory OrderFailure.unexpectedError() = _UnexpectedError;
|
||||
const factory OrderFailure.empty() = _Empty;
|
||||
const factory OrderFailure.dynamicErrorMessage(String erroMessage) =
|
||||
_DynamicErrorMessage;
|
||||
}
|
||||
10
lib/domain/order/order.dart
Normal file
10
lib/domain/order/order.dart
Normal file
@ -0,0 +1,10 @@
|
||||
import 'package:dartz/dartz.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
import '../../common/api/api_failure.dart';
|
||||
|
||||
part 'order.freezed.dart';
|
||||
|
||||
part 'entities/order_entity.dart';
|
||||
part 'failures/order_failure.dart';
|
||||
part 'repositories/i_order_repository.dart';
|
||||
2538
lib/domain/order/order.freezed.dart
Normal file
2538
lib/domain/order/order.freezed.dart
Normal file
File diff suppressed because it is too large
Load Diff
10
lib/domain/order/repositories/i_order_repository.dart
Normal file
10
lib/domain/order/repositories/i_order_repository.dart
Normal file
@ -0,0 +1,10 @@
|
||||
part of '../order.dart';
|
||||
|
||||
abstract class IOrderRepository {
|
||||
Future<Either<OrderFailure, List<Order>>> get({
|
||||
int page = 1,
|
||||
int limit = 10,
|
||||
String? status,
|
||||
String? search,
|
||||
});
|
||||
}
|
||||
@ -0,0 +1,57 @@
|
||||
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/order/order.dart';
|
||||
import '../order_dtos.dart';
|
||||
|
||||
@injectable
|
||||
class OrderRemoteDataProvider {
|
||||
final ApiClient _apiClient;
|
||||
final String _logName = 'OrderRemoteDataProvider';
|
||||
|
||||
OrderRemoteDataProvider(this._apiClient);
|
||||
|
||||
Future<DC<OrderFailure, List<OrderDto>>> fetch({
|
||||
int page = 1,
|
||||
int limit = 10,
|
||||
String? status,
|
||||
String? search,
|
||||
}) async {
|
||||
try {
|
||||
Map<String, dynamic> params = {'page': page, 'limit': limit};
|
||||
|
||||
if (status != null && status.isNotEmpty) {
|
||||
params['status'] = status;
|
||||
}
|
||||
|
||||
if (search != null && search.isNotEmpty) {
|
||||
params['search'] = search;
|
||||
}
|
||||
|
||||
final response = await _apiClient.get(
|
||||
ApiPath.order,
|
||||
params: params,
|
||||
headers: getAuthorizationHeader(),
|
||||
);
|
||||
|
||||
if (response.data['data'] == null) {
|
||||
return DC.error(OrderFailure.empty());
|
||||
}
|
||||
|
||||
final dto = (response.data['data']['orders'] as List)
|
||||
.map((item) => OrderDto.fromJson(item))
|
||||
.toList();
|
||||
|
||||
return DC.data(dto);
|
||||
} on ApiFailure catch (e, s) {
|
||||
log('fetchOrderError', name: _logName, error: e, stackTrace: s);
|
||||
return DC.error(OrderFailure.serverError(e));
|
||||
}
|
||||
}
|
||||
}
|
||||
183
lib/infrastructure/order/dto/order_dto.dart
Normal file
183
lib/infrastructure/order/dto/order_dto.dart
Normal file
@ -0,0 +1,183 @@
|
||||
part of '../order_dtos.dart';
|
||||
|
||||
@freezed
|
||||
class OrderDto with _$OrderDto {
|
||||
const OrderDto._();
|
||||
|
||||
const factory OrderDto({
|
||||
@JsonKey(name: 'id') String? id,
|
||||
@JsonKey(name: 'order_number') String? orderNumber,
|
||||
@JsonKey(name: 'outlet_id') String? outletId,
|
||||
@JsonKey(name: 'user_id') String? userId,
|
||||
@JsonKey(name: 'table_number') String? tableNumber,
|
||||
@JsonKey(name: 'order_type') String? orderType,
|
||||
@JsonKey(name: 'status') String? status,
|
||||
@JsonKey(name: 'subtotal') int? subtotal,
|
||||
@JsonKey(name: 'tax_amount') int? taxAmount,
|
||||
@JsonKey(name: 'discount_amount') int? discountAmount,
|
||||
@JsonKey(name: 'total_amount') int? totalAmount,
|
||||
@JsonKey(name: 'total_cost') int? totalCost,
|
||||
@JsonKey(name: 'remaining_amount') int? remainingAmount,
|
||||
@JsonKey(name: 'payment_status') String? paymentStatus,
|
||||
@JsonKey(name: 'refund_amount') int? refundAmount,
|
||||
@JsonKey(name: 'is_void') bool? isVoid,
|
||||
@JsonKey(name: 'is_refund') bool? isRefund,
|
||||
@JsonKey(name: 'notes') String? notes,
|
||||
@JsonKey(name: 'metadata') Map<String, dynamic>? metadata,
|
||||
@JsonKey(name: 'created_at') String? createdAt,
|
||||
@JsonKey(name: 'updated_at') String? updatedAt,
|
||||
@JsonKey(name: 'order_items') List<OrderItemDto>? orderItems,
|
||||
@JsonKey(name: 'payments') List<OrderPaymentDto>? payments,
|
||||
@JsonKey(name: 'total_paid') int? totalPaid,
|
||||
@JsonKey(name: 'payment_count') int? paymentCount,
|
||||
@JsonKey(name: 'split_type') String? splitType,
|
||||
}) = _OrderDto;
|
||||
|
||||
factory OrderDto.fromJson(Map<String, dynamic> json) =>
|
||||
_$OrderDtoFromJson(json);
|
||||
|
||||
Order toDomain() => Order(
|
||||
id: id ?? '',
|
||||
orderNumber: orderNumber ?? '',
|
||||
outletId: outletId ?? '',
|
||||
userId: userId ?? '',
|
||||
tableNumber: tableNumber ?? '',
|
||||
orderType: orderType ?? '',
|
||||
status: status ?? '',
|
||||
subtotal: subtotal ?? 0,
|
||||
taxAmount: taxAmount ?? 0,
|
||||
discountAmount: discountAmount ?? 0,
|
||||
totalAmount: totalAmount ?? 0,
|
||||
totalCost: totalCost ?? 0,
|
||||
remainingAmount: remainingAmount ?? 0,
|
||||
paymentStatus: paymentStatus ?? '',
|
||||
refundAmount: refundAmount ?? 0,
|
||||
isVoid: isVoid ?? false,
|
||||
isRefund: isRefund ?? false,
|
||||
notes: notes ?? '',
|
||||
metadata: metadata ?? {},
|
||||
createdAt: createdAt ?? '',
|
||||
updatedAt: updatedAt ?? '',
|
||||
orderItems: orderItems?.map((e) => e.toDomain()).toList() ?? [],
|
||||
payments: payments?.map((e) => e.toDomain()).toList() ?? [],
|
||||
totalPaid: totalPaid ?? 0,
|
||||
paymentCount: paymentCount ?? 0,
|
||||
splitType: splitType ?? '',
|
||||
);
|
||||
}
|
||||
|
||||
@freezed
|
||||
class OrderItemDto with _$OrderItemDto {
|
||||
const OrderItemDto._();
|
||||
|
||||
const factory OrderItemDto({
|
||||
@JsonKey(name: 'id') String? id,
|
||||
@JsonKey(name: 'order_id') String? orderId,
|
||||
@JsonKey(name: 'product_id') String? productId,
|
||||
@JsonKey(name: 'product_name') String? productName,
|
||||
@JsonKey(name: 'quantity') int? quantity,
|
||||
@JsonKey(name: 'price') int? price,
|
||||
@JsonKey(name: 'subtotal') int? subtotal,
|
||||
@JsonKey(name: 'discount_amount') int? discountAmount,
|
||||
@JsonKey(name: 'total') int? total,
|
||||
@JsonKey(name: 'cost') int? cost,
|
||||
@JsonKey(name: 'metadata') Map<String, dynamic>? metadata,
|
||||
@JsonKey(name: 'created_at') String? createdAt,
|
||||
@JsonKey(name: 'updated_at') String? updatedAt,
|
||||
}) = _OrderItemDto;
|
||||
|
||||
factory OrderItemDto.fromJson(Map<String, dynamic> json) =>
|
||||
_$OrderItemDtoFromJson(json);
|
||||
|
||||
OrderItem toDomain() => OrderItem(
|
||||
id: id ?? '',
|
||||
orderId: orderId ?? '',
|
||||
productId: productId ?? '',
|
||||
productName: productName ?? '',
|
||||
quantity: quantity ?? 0,
|
||||
price: price ?? 0,
|
||||
subtotal: subtotal ?? 0,
|
||||
discountAmount: discountAmount ?? 0,
|
||||
total: total ?? 0,
|
||||
cost: cost ?? 0,
|
||||
metadata: metadata ?? {},
|
||||
createdAt: createdAt ?? '',
|
||||
updatedAt: updatedAt ?? '',
|
||||
);
|
||||
}
|
||||
|
||||
@freezed
|
||||
class OrderPaymentDto with _$OrderPaymentDto {
|
||||
const OrderPaymentDto._();
|
||||
|
||||
const factory OrderPaymentDto({
|
||||
@JsonKey(name: 'id') String? id,
|
||||
@JsonKey(name: 'order_id') String? orderId,
|
||||
@JsonKey(name: 'payment_method_id') String? paymentMethodId,
|
||||
@JsonKey(name: 'payment_method_name') String? paymentMethodName,
|
||||
@JsonKey(name: 'payment_method_type') String? paymentMethodType,
|
||||
@JsonKey(name: 'amount') int? amount,
|
||||
@JsonKey(name: 'status') String? status,
|
||||
@JsonKey(name: 'split_number') int? splitNumber,
|
||||
@JsonKey(name: 'split_total') int? splitTotal,
|
||||
@JsonKey(name: 'split_type') String? splitType,
|
||||
@JsonKey(name: 'split_description') String? splitDescription,
|
||||
@JsonKey(name: 'refund_amount') int? refundAmount,
|
||||
@JsonKey(name: 'metadata') Map<String, dynamic>? metadata,
|
||||
@JsonKey(name: 'created_at') String? createdAt,
|
||||
@JsonKey(name: 'updated_at') String? updatedAt,
|
||||
@JsonKey(name: 'payment_order_items')
|
||||
List<PaymentOrderItemDto>? paymentOrderItems,
|
||||
}) = _OrderPaymentDto;
|
||||
|
||||
factory OrderPaymentDto.fromJson(Map<String, dynamic> json) =>
|
||||
_$OrderPaymentDtoFromJson(json);
|
||||
|
||||
OrderPayment toDomain() => OrderPayment(
|
||||
id: id ?? '',
|
||||
orderId: orderId ?? '',
|
||||
paymentMethodId: paymentMethodId ?? '',
|
||||
paymentMethodName: paymentMethodName ?? '',
|
||||
paymentMethodType: paymentMethodType ?? '',
|
||||
amount: amount ?? 0,
|
||||
status: status ?? '',
|
||||
splitNumber: splitNumber ?? 0,
|
||||
splitTotal: splitTotal ?? 0,
|
||||
splitType: splitType ?? '',
|
||||
splitDescription: splitDescription ?? '',
|
||||
refundAmount: refundAmount ?? 0,
|
||||
metadata: metadata ?? {},
|
||||
createdAt: createdAt ?? '',
|
||||
updatedAt: updatedAt ?? '',
|
||||
paymentOrderItems:
|
||||
paymentOrderItems?.map((e) => e.toDomain()).toList() ?? [],
|
||||
);
|
||||
}
|
||||
|
||||
@freezed
|
||||
class PaymentOrderItemDto with _$PaymentOrderItemDto {
|
||||
const PaymentOrderItemDto._();
|
||||
|
||||
const factory PaymentOrderItemDto({
|
||||
@JsonKey(name: 'id') String? id,
|
||||
@JsonKey(name: 'order_payment_id') String? orderPaymentId,
|
||||
@JsonKey(name: 'order_item_id') String? orderItemId,
|
||||
@JsonKey(name: 'amount') int? amount,
|
||||
@JsonKey(name: 'refund_amount') int? refundAmount,
|
||||
@JsonKey(name: 'created_at') String? createdAt,
|
||||
@JsonKey(name: 'updated_at') String? updatedAt,
|
||||
}) = _PaymentOrderItemDto;
|
||||
|
||||
factory PaymentOrderItemDto.fromJson(Map<String, dynamic> json) =>
|
||||
_$PaymentOrderItemDtoFromJson(json);
|
||||
|
||||
PaymentOrderItem toDomain() => PaymentOrderItem(
|
||||
id: id ?? '',
|
||||
orderPaymentId: orderPaymentId ?? '',
|
||||
orderItemId: orderItemId ?? '',
|
||||
amount: amount ?? 0,
|
||||
refundAmount: refundAmount ?? 0,
|
||||
createdAt: createdAt ?? '',
|
||||
updatedAt: updatedAt ?? '',
|
||||
);
|
||||
}
|
||||
8
lib/infrastructure/order/order_dtos.dart
Normal file
8
lib/infrastructure/order/order_dtos.dart
Normal file
@ -0,0 +1,8 @@
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
import '../../domain/order/order.dart';
|
||||
|
||||
part 'order_dtos.freezed.dart';
|
||||
part 'order_dtos.g.dart';
|
||||
|
||||
part 'dto/order_dto.dart';
|
||||
2197
lib/infrastructure/order/order_dtos.freezed.dart
Normal file
2197
lib/infrastructure/order/order_dtos.freezed.dart
Normal file
File diff suppressed because it is too large
Load Diff
173
lib/infrastructure/order/order_dtos.g.dart
Normal file
173
lib/infrastructure/order/order_dtos.g.dart
Normal file
@ -0,0 +1,173 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'order_dtos.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
_$OrderDtoImpl _$$OrderDtoImplFromJson(Map<String, dynamic> json) =>
|
||||
_$OrderDtoImpl(
|
||||
id: json['id'] as String?,
|
||||
orderNumber: json['order_number'] as String?,
|
||||
outletId: json['outlet_id'] as String?,
|
||||
userId: json['user_id'] as String?,
|
||||
tableNumber: json['table_number'] as String?,
|
||||
orderType: json['order_type'] as String?,
|
||||
status: json['status'] as String?,
|
||||
subtotal: (json['subtotal'] as num?)?.toInt(),
|
||||
taxAmount: (json['tax_amount'] as num?)?.toInt(),
|
||||
discountAmount: (json['discount_amount'] as num?)?.toInt(),
|
||||
totalAmount: (json['total_amount'] as num?)?.toInt(),
|
||||
totalCost: (json['total_cost'] as num?)?.toInt(),
|
||||
remainingAmount: (json['remaining_amount'] as num?)?.toInt(),
|
||||
paymentStatus: json['payment_status'] as String?,
|
||||
refundAmount: (json['refund_amount'] as num?)?.toInt(),
|
||||
isVoid: json['is_void'] as bool?,
|
||||
isRefund: json['is_refund'] as bool?,
|
||||
notes: json['notes'] as String?,
|
||||
metadata: json['metadata'] as Map<String, dynamic>?,
|
||||
createdAt: json['created_at'] as String?,
|
||||
updatedAt: json['updated_at'] as String?,
|
||||
orderItems: (json['order_items'] as List<dynamic>?)
|
||||
?.map((e) => OrderItemDto.fromJson(e as Map<String, dynamic>))
|
||||
.toList(),
|
||||
payments: (json['payments'] as List<dynamic>?)
|
||||
?.map((e) => OrderPaymentDto.fromJson(e as Map<String, dynamic>))
|
||||
.toList(),
|
||||
totalPaid: (json['total_paid'] as num?)?.toInt(),
|
||||
paymentCount: (json['payment_count'] as num?)?.toInt(),
|
||||
splitType: json['split_type'] as String?,
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$$OrderDtoImplToJson(_$OrderDtoImpl instance) =>
|
||||
<String, dynamic>{
|
||||
'id': instance.id,
|
||||
'order_number': instance.orderNumber,
|
||||
'outlet_id': instance.outletId,
|
||||
'user_id': instance.userId,
|
||||
'table_number': instance.tableNumber,
|
||||
'order_type': instance.orderType,
|
||||
'status': instance.status,
|
||||
'subtotal': instance.subtotal,
|
||||
'tax_amount': instance.taxAmount,
|
||||
'discount_amount': instance.discountAmount,
|
||||
'total_amount': instance.totalAmount,
|
||||
'total_cost': instance.totalCost,
|
||||
'remaining_amount': instance.remainingAmount,
|
||||
'payment_status': instance.paymentStatus,
|
||||
'refund_amount': instance.refundAmount,
|
||||
'is_void': instance.isVoid,
|
||||
'is_refund': instance.isRefund,
|
||||
'notes': instance.notes,
|
||||
'metadata': instance.metadata,
|
||||
'created_at': instance.createdAt,
|
||||
'updated_at': instance.updatedAt,
|
||||
'order_items': instance.orderItems,
|
||||
'payments': instance.payments,
|
||||
'total_paid': instance.totalPaid,
|
||||
'payment_count': instance.paymentCount,
|
||||
'split_type': instance.splitType,
|
||||
};
|
||||
|
||||
_$OrderItemDtoImpl _$$OrderItemDtoImplFromJson(Map<String, dynamic> json) =>
|
||||
_$OrderItemDtoImpl(
|
||||
id: json['id'] as String?,
|
||||
orderId: json['order_id'] as String?,
|
||||
productId: json['product_id'] as String?,
|
||||
productName: json['product_name'] as String?,
|
||||
quantity: (json['quantity'] as num?)?.toInt(),
|
||||
price: (json['price'] as num?)?.toInt(),
|
||||
subtotal: (json['subtotal'] as num?)?.toInt(),
|
||||
discountAmount: (json['discount_amount'] as num?)?.toInt(),
|
||||
total: (json['total'] as num?)?.toInt(),
|
||||
cost: (json['cost'] as num?)?.toInt(),
|
||||
metadata: json['metadata'] as Map<String, dynamic>?,
|
||||
createdAt: json['created_at'] as String?,
|
||||
updatedAt: json['updated_at'] as String?,
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$$OrderItemDtoImplToJson(_$OrderItemDtoImpl instance) =>
|
||||
<String, dynamic>{
|
||||
'id': instance.id,
|
||||
'order_id': instance.orderId,
|
||||
'product_id': instance.productId,
|
||||
'product_name': instance.productName,
|
||||
'quantity': instance.quantity,
|
||||
'price': instance.price,
|
||||
'subtotal': instance.subtotal,
|
||||
'discount_amount': instance.discountAmount,
|
||||
'total': instance.total,
|
||||
'cost': instance.cost,
|
||||
'metadata': instance.metadata,
|
||||
'created_at': instance.createdAt,
|
||||
'updated_at': instance.updatedAt,
|
||||
};
|
||||
|
||||
_$OrderPaymentDtoImpl _$$OrderPaymentDtoImplFromJson(
|
||||
Map<String, dynamic> json,
|
||||
) => _$OrderPaymentDtoImpl(
|
||||
id: json['id'] as String?,
|
||||
orderId: json['order_id'] as String?,
|
||||
paymentMethodId: json['payment_method_id'] as String?,
|
||||
paymentMethodName: json['payment_method_name'] as String?,
|
||||
paymentMethodType: json['payment_method_type'] as String?,
|
||||
amount: (json['amount'] as num?)?.toInt(),
|
||||
status: json['status'] as String?,
|
||||
splitNumber: (json['split_number'] as num?)?.toInt(),
|
||||
splitTotal: (json['split_total'] as num?)?.toInt(),
|
||||
splitType: json['split_type'] as String?,
|
||||
splitDescription: json['split_description'] as String?,
|
||||
refundAmount: (json['refund_amount'] as num?)?.toInt(),
|
||||
metadata: json['metadata'] as Map<String, dynamic>?,
|
||||
createdAt: json['created_at'] as String?,
|
||||
updatedAt: json['updated_at'] as String?,
|
||||
paymentOrderItems: (json['payment_order_items'] as List<dynamic>?)
|
||||
?.map((e) => PaymentOrderItemDto.fromJson(e as Map<String, dynamic>))
|
||||
.toList(),
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$$OrderPaymentDtoImplToJson(
|
||||
_$OrderPaymentDtoImpl instance,
|
||||
) => <String, dynamic>{
|
||||
'id': instance.id,
|
||||
'order_id': instance.orderId,
|
||||
'payment_method_id': instance.paymentMethodId,
|
||||
'payment_method_name': instance.paymentMethodName,
|
||||
'payment_method_type': instance.paymentMethodType,
|
||||
'amount': instance.amount,
|
||||
'status': instance.status,
|
||||
'split_number': instance.splitNumber,
|
||||
'split_total': instance.splitTotal,
|
||||
'split_type': instance.splitType,
|
||||
'split_description': instance.splitDescription,
|
||||
'refund_amount': instance.refundAmount,
|
||||
'metadata': instance.metadata,
|
||||
'created_at': instance.createdAt,
|
||||
'updated_at': instance.updatedAt,
|
||||
'payment_order_items': instance.paymentOrderItems,
|
||||
};
|
||||
|
||||
_$PaymentOrderItemDtoImpl _$$PaymentOrderItemDtoImplFromJson(
|
||||
Map<String, dynamic> json,
|
||||
) => _$PaymentOrderItemDtoImpl(
|
||||
id: json['id'] as String?,
|
||||
orderPaymentId: json['order_payment_id'] as String?,
|
||||
orderItemId: json['order_item_id'] as String?,
|
||||
amount: (json['amount'] as num?)?.toInt(),
|
||||
refundAmount: (json['refund_amount'] as num?)?.toInt(),
|
||||
createdAt: json['created_at'] as String?,
|
||||
updatedAt: json['updated_at'] as String?,
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$$PaymentOrderItemDtoImplToJson(
|
||||
_$PaymentOrderItemDtoImpl instance,
|
||||
) => <String, dynamic>{
|
||||
'id': instance.id,
|
||||
'order_payment_id': instance.orderPaymentId,
|
||||
'order_item_id': instance.orderItemId,
|
||||
'amount': instance.amount,
|
||||
'refund_amount': instance.refundAmount,
|
||||
'created_at': instance.createdAt,
|
||||
'updated_at': instance.updatedAt,
|
||||
};
|
||||
43
lib/infrastructure/order/repositories/order_repository.dart
Normal file
43
lib/infrastructure/order/repositories/order_repository.dart
Normal file
@ -0,0 +1,43 @@
|
||||
import 'dart:developer';
|
||||
|
||||
import 'package:dartz/dartz.dart' hide Order;
|
||||
import 'package:injectable/injectable.dart' hide Order;
|
||||
|
||||
import '../../../domain/order/order.dart';
|
||||
import '../datasource/remote_data_provider.dart';
|
||||
|
||||
@Injectable(as: IOrderRepository)
|
||||
class OrderRepository implements IOrderRepository {
|
||||
final OrderRemoteDataProvider _dataProvider;
|
||||
final String _logName = 'OrderRepository';
|
||||
|
||||
OrderRepository(this._dataProvider);
|
||||
|
||||
@override
|
||||
Future<Either<OrderFailure, List<Order>>> get({
|
||||
int page = 1,
|
||||
int limit = 20,
|
||||
String? status,
|
||||
String? search,
|
||||
}) async {
|
||||
try {
|
||||
final result = await _dataProvider.fetch(
|
||||
page: page,
|
||||
limit: limit,
|
||||
status: status,
|
||||
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('getOrderError', name: _logName, error: e, stackTrace: s);
|
||||
return left(const OrderFailure.unexpectedError());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -34,6 +34,8 @@ import 'package:apskel_owner_flutter/application/customer/customer_loader/custom
|
||||
as _i972;
|
||||
import 'package:apskel_owner_flutter/application/language/language_bloc.dart'
|
||||
as _i455;
|
||||
import 'package:apskel_owner_flutter/application/order/order_loader/order_loader_bloc.dart'
|
||||
as _i1058;
|
||||
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;
|
||||
@ -50,6 +52,7 @@ import 'package:apskel_owner_flutter/domain/analytic/repositories/i_analytic_rep
|
||||
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/customer/customer.dart' as _i48;
|
||||
import 'package:apskel_owner_flutter/domain/order/order.dart' as _i219;
|
||||
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/infrastructure/analytic/datasource/remote_data_provider.dart'
|
||||
@ -70,6 +73,10 @@ import 'package:apskel_owner_flutter/infrastructure/customer/datasources/remote_
|
||||
as _i1006;
|
||||
import 'package:apskel_owner_flutter/infrastructure/customer/repositories/customer_repository.dart'
|
||||
as _i550;
|
||||
import 'package:apskel_owner_flutter/infrastructure/order/datasource/remote_data_provider.dart'
|
||||
as _i130;
|
||||
import 'package:apskel_owner_flutter/infrastructure/order/repositories/order_repository.dart'
|
||||
as _i641;
|
||||
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'
|
||||
@ -138,9 +145,15 @@ extension GetItInjectableX on _i174.GetIt {
|
||||
gh.factory<_i1006.CustomerRemoteDataProvider>(
|
||||
() => _i1006.CustomerRemoteDataProvider(gh<_i115.ApiClient>()),
|
||||
);
|
||||
gh.factory<_i130.OrderRemoteDataProvider>(
|
||||
() => _i130.OrderRemoteDataProvider(gh<_i115.ApiClient>()),
|
||||
);
|
||||
gh.factory<_i48.ICustomerRepository>(
|
||||
() => _i550.CustomerRepository(gh<_i1006.CustomerRemoteDataProvider>()),
|
||||
);
|
||||
gh.factory<_i219.IOrderRepository>(
|
||||
() => _i641.OrderRepository(gh<_i130.OrderRemoteDataProvider>()),
|
||||
);
|
||||
gh.factory<_i49.IAuthRepository>(
|
||||
() => _i1035.AuthRepository(
|
||||
gh<_i991.AuthLocalDataProvider>(),
|
||||
@ -200,6 +213,9 @@ extension GetItInjectableX on _i174.GetIt {
|
||||
gh.factory<_i574.LogoutFormBloc>(
|
||||
() => _i574.LogoutFormBloc(gh<_i49.IAuthRepository>()),
|
||||
);
|
||||
gh.factory<_i1058.OrderLoaderBloc>(
|
||||
() => _i1058.OrderLoaderBloc(gh<_i219.IOrderRepository>()),
|
||||
);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
@ -11,7 +11,7 @@ class MainPage extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return AutoTabsRouter.pageView(
|
||||
routes: [HomeRoute(), TransactionRoute(), ReportRoute(), ProfileRoute()],
|
||||
routes: [HomeRoute(), OrderRoute(), ReportRoute(), ProfileRoute()],
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
builder: (context, child, pageController) {
|
||||
final tabsRouter = AutoTabsRouter.of(context);
|
||||
|
||||
@ -33,8 +33,8 @@ class _MainBottomNavbarState extends State<MainBottomNavbar> {
|
||||
),
|
||||
BottomNavigationBarItem(
|
||||
icon: LineIcon(LineIcons.moneyBill),
|
||||
label: context.lang.transaction,
|
||||
tooltip: context.lang.transaction,
|
||||
label: 'Order',
|
||||
tooltip: 'Order',
|
||||
),
|
||||
BottomNavigationBarItem(
|
||||
icon: LineIcon(LineIcons.barChart),
|
||||
|
||||
1228
lib/presentation/pages/order/order_detail/order_detail_page.dart
Normal file
1228
lib/presentation/pages/order/order_detail/order_detail_page.dart
Normal file
File diff suppressed because it is too large
Load Diff
274
lib/presentation/pages/order/order_list/order_page.dart
Normal file
274
lib/presentation/pages/order/order_list/order_page.dart
Normal file
@ -0,0 +1,274 @@
|
||||
import 'package:auto_route/auto_route.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:line_icons/line_icons.dart';
|
||||
|
||||
import '../../../../application/order/order_loader/order_loader_bloc.dart';
|
||||
import '../../../../common/theme/theme.dart';
|
||||
import '../../../../injection.dart';
|
||||
import '../../../components/appbar/appbar.dart';
|
||||
import '../../../components/button/button.dart';
|
||||
import '../../../components/spacer/spacer.dart';
|
||||
import '../../../components/widgets/empty_widget.dart';
|
||||
import '../../../router/app_router.gr.dart';
|
||||
import 'widgets/status_tile.dart';
|
||||
import 'widgets/order_tile.dart';
|
||||
|
||||
@RoutePage()
|
||||
class OrderPage extends StatefulWidget implements AutoRouteWrapper {
|
||||
const OrderPage({super.key});
|
||||
|
||||
@override
|
||||
State<OrderPage> createState() => _OrderPageState();
|
||||
|
||||
@override
|
||||
Widget wrappedRoute(BuildContext context) => BlocProvider(
|
||||
create: (_) =>
|
||||
getIt<OrderLoaderBloc>()
|
||||
..add(OrderLoaderEvent.fetched(isRefresh: true)),
|
||||
child: this,
|
||||
);
|
||||
}
|
||||
|
||||
class _OrderPageState extends State<OrderPage> with TickerProviderStateMixin {
|
||||
late AnimationController _fadeController;
|
||||
late AnimationController _slideController;
|
||||
late Animation<double> _fadeAnimation;
|
||||
late Animation<Offset> _slideAnimation;
|
||||
final ScrollController _scrollController = ScrollController();
|
||||
|
||||
// Filter state
|
||||
String selectedFilter = 'All';
|
||||
final List<String> filterOptions = ['All', 'Completed', 'Pending'];
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
||||
_fadeController = AnimationController(
|
||||
duration: const Duration(milliseconds: 800),
|
||||
vsync: this,
|
||||
);
|
||||
|
||||
_slideController = AnimationController(
|
||||
duration: const Duration(milliseconds: 1000),
|
||||
vsync: this,
|
||||
);
|
||||
|
||||
_fadeAnimation = Tween<double>(begin: 0.0, end: 1.0).animate(
|
||||
CurvedAnimation(parent: _fadeController, curve: Curves.easeInOut),
|
||||
);
|
||||
|
||||
_slideAnimation =
|
||||
Tween<Offset>(begin: const Offset(0, 0.3), end: Offset.zero).animate(
|
||||
CurvedAnimation(parent: _slideController, curve: Curves.elasticOut),
|
||||
);
|
||||
|
||||
_fadeController.forward();
|
||||
_slideController.forward();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_fadeController.dispose();
|
||||
_slideController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
backgroundColor: AppColor.background,
|
||||
body: BlocListener<OrderLoaderBloc, OrderLoaderState>(
|
||||
listenWhen: (p, c) => p.status != c.status,
|
||||
listener: (context, state) {
|
||||
context.read<OrderLoaderBloc>().add(
|
||||
OrderLoaderEvent.fetched(isRefresh: true),
|
||||
);
|
||||
},
|
||||
child: BlocBuilder<OrderLoaderBloc, OrderLoaderState>(
|
||||
builder: (context, state) {
|
||||
return NotificationListener<ScrollNotification>(
|
||||
onNotification: (notification) {
|
||||
if (notification is ScrollEndNotification &&
|
||||
_scrollController.position.extentAfter == 0) {
|
||||
context.read<OrderLoaderBloc>().add(
|
||||
OrderLoaderEvent.fetched(),
|
||||
);
|
||||
return true;
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
child: CustomScrollView(
|
||||
controller: _scrollController,
|
||||
slivers: [
|
||||
// Custom App Bar with Hero Effect
|
||||
SliverAppBar(
|
||||
expandedHeight: 120,
|
||||
floating: true,
|
||||
pinned: true,
|
||||
backgroundColor: AppColor.primary,
|
||||
centerTitle: false,
|
||||
flexibleSpace: CustomAppBar(title: 'Order', isBack: false),
|
||||
actions: [
|
||||
ActionIconButton(onTap: () {}, icon: LineIcons.filter),
|
||||
SpaceWidth(8),
|
||||
],
|
||||
),
|
||||
|
||||
// Pinned Filter Section
|
||||
SliverPersistentHeader(
|
||||
pinned: true,
|
||||
delegate: _FilterHeaderDelegate(
|
||||
child: Container(
|
||||
color: AppColor.background,
|
||||
padding: EdgeInsets.fromLTRB(
|
||||
AppValue.padding,
|
||||
10,
|
||||
AppValue.padding,
|
||||
10,
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
SingleChildScrollView(
|
||||
scrollDirection: Axis.horizontal,
|
||||
child: Row(
|
||||
children: filterOptions.map((option) {
|
||||
final index = filterOptions.indexOf(option);
|
||||
return Padding(
|
||||
padding: EdgeInsets.only(
|
||||
right: index < filterOptions.length - 1
|
||||
? 8
|
||||
: 0,
|
||||
),
|
||||
child: OrderStatusTile(
|
||||
label: option,
|
||||
isSelected: option == selectedFilter,
|
||||
onSelected: (isSelected) {
|
||||
if (isSelected) {
|
||||
setState(() {
|
||||
selectedFilter = option;
|
||||
});
|
||||
if (option.toLowerCase() == 'all') {
|
||||
context.read<OrderLoaderBloc>().add(
|
||||
OrderLoaderEvent.statusChanged(
|
||||
'',
|
||||
),
|
||||
);
|
||||
} else {
|
||||
context.read<OrderLoaderBloc>().add(
|
||||
OrderLoaderEvent.statusChanged(
|
||||
option.toLowerCase(),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
},
|
||||
),
|
||||
);
|
||||
}).toList(),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
// Content
|
||||
SliverPadding(
|
||||
padding: EdgeInsets.all(AppValue.padding),
|
||||
sliver: SliverList(
|
||||
delegate: SliverChildListDelegate([
|
||||
FadeTransition(
|
||||
opacity: _fadeAnimation,
|
||||
child: SlideTransition(
|
||||
position: _slideAnimation,
|
||||
child: Column(
|
||||
children: [
|
||||
// Show filtered transaction count
|
||||
if (selectedFilter != 'All')
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(bottom: 16),
|
||||
child: Row(
|
||||
children: [
|
||||
Text(
|
||||
'${state.orders.length} ${selectedFilter.toLowerCase()} order${state.orders.length != 1 ? 's' : ''}',
|
||||
style: TextStyle(
|
||||
color: AppColor.textSecondary,
|
||||
fontSize: 14,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
// Transaction List
|
||||
state.orders.isEmpty
|
||||
? EmptyWidget(
|
||||
title: 'Order',
|
||||
message:
|
||||
'No ${selectedFilter.toLowerCase()} orders found',
|
||||
)
|
||||
: ListView.builder(
|
||||
itemCount: state.orders.length,
|
||||
shrinkWrap: true,
|
||||
physics:
|
||||
const NeverScrollableScrollPhysics(),
|
||||
padding: EdgeInsets.zero,
|
||||
itemBuilder: (context, index) {
|
||||
return OrderTile(
|
||||
onTap: () => context.router.push(
|
||||
OrderDetailRoute(
|
||||
order: state.orders[index],
|
||||
),
|
||||
),
|
||||
order: state.orders[index],
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
]),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Custom delegate for pinned filter header
|
||||
class _FilterHeaderDelegate extends SliverPersistentHeaderDelegate {
|
||||
final Widget child;
|
||||
|
||||
_FilterHeaderDelegate({required this.child});
|
||||
|
||||
@override
|
||||
double get minExtent => 70; // Minimum height when collapsed
|
||||
|
||||
@override
|
||||
double get maxExtent => 70; // Maximum height when expanded
|
||||
|
||||
@override
|
||||
Widget build(
|
||||
BuildContext context,
|
||||
double shrinkOffset,
|
||||
bool overlapsContent,
|
||||
) {
|
||||
return child;
|
||||
}
|
||||
|
||||
@override
|
||||
bool shouldRebuild(covariant SliverPersistentHeaderDelegate oldDelegate) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -1,42 +1,18 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
|
||||
import '../../../../common/theme/theme.dart';
|
||||
import '../../../../../common/theme/theme.dart';
|
||||
import '../../../../../domain/order/order.dart';
|
||||
|
||||
// Model untuk Transaction
|
||||
class Transaction {
|
||||
final String id;
|
||||
final String customerName;
|
||||
final DateTime date;
|
||||
final double totalAmount;
|
||||
final int itemCount;
|
||||
final String paymentMethod;
|
||||
final TransactionStatus status;
|
||||
final String? receiptNumber;
|
||||
|
||||
Transaction({
|
||||
required this.id,
|
||||
required this.customerName,
|
||||
required this.date,
|
||||
required this.totalAmount,
|
||||
required this.itemCount,
|
||||
required this.paymentMethod,
|
||||
required this.status,
|
||||
this.receiptNumber,
|
||||
});
|
||||
}
|
||||
|
||||
enum TransactionStatus { completed, pending, cancelled, refunded }
|
||||
|
||||
class TransactionTile extends StatelessWidget {
|
||||
final Transaction transaction;
|
||||
class OrderTile extends StatelessWidget {
|
||||
final Order order;
|
||||
final VoidCallback? onTap;
|
||||
final VoidCallback? onPrint;
|
||||
final VoidCallback? onRefund;
|
||||
|
||||
const TransactionTile({
|
||||
const OrderTile({
|
||||
super.key,
|
||||
required this.transaction,
|
||||
required this.order,
|
||||
this.onTap,
|
||||
this.onPrint,
|
||||
this.onRefund,
|
||||
@ -73,8 +49,8 @@ class TransactionTile extends StatelessWidget {
|
||||
_buildHeaderRow(),
|
||||
const SizedBox(height: 12),
|
||||
|
||||
// Transaction Info
|
||||
_buildTransactionInfo(),
|
||||
// Order Info
|
||||
_buildOrderInfo(),
|
||||
const SizedBox(height: 16),
|
||||
|
||||
// Amount Section
|
||||
@ -99,7 +75,9 @@ class TransactionTile extends StatelessWidget {
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
transaction.receiptNumber ?? 'TXN-${transaction.id}',
|
||||
order.orderNumber.isNotEmpty
|
||||
? order.orderNumber
|
||||
: 'ORD-${order.id}',
|
||||
style: const TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.bold,
|
||||
@ -108,7 +86,7 @@ class TransactionTile extends StatelessWidget {
|
||||
),
|
||||
const SizedBox(height: 2),
|
||||
Text(
|
||||
DateFormat('dd MMM yyyy, HH:mm').format(transaction.date),
|
||||
_formatDate(order.createdAt),
|
||||
style: const TextStyle(
|
||||
fontSize: 12,
|
||||
color: AppColor.textSecondary,
|
||||
@ -126,27 +104,38 @@ class TransactionTile extends StatelessWidget {
|
||||
String statusText;
|
||||
IconData statusIcon;
|
||||
|
||||
switch (transaction.status) {
|
||||
case TransactionStatus.completed:
|
||||
statusColor = AppColor.success;
|
||||
statusText = 'Completed';
|
||||
statusIcon = Icons.check_circle;
|
||||
break;
|
||||
case TransactionStatus.pending:
|
||||
statusColor = AppColor.warning;
|
||||
statusText = 'Pending';
|
||||
statusIcon = Icons.schedule;
|
||||
break;
|
||||
case TransactionStatus.cancelled:
|
||||
statusColor = AppColor.error;
|
||||
statusText = 'Cancelled';
|
||||
statusIcon = Icons.cancel;
|
||||
break;
|
||||
case TransactionStatus.refunded:
|
||||
statusColor = AppColor.info;
|
||||
statusText = 'Refunded';
|
||||
statusIcon = Icons.undo;
|
||||
break;
|
||||
// Check isVoid and isRefund first for display
|
||||
if (order.isVoid) {
|
||||
statusColor = AppColor.error;
|
||||
statusText = 'Void';
|
||||
statusIcon = Icons.block;
|
||||
} else if (order.isRefund) {
|
||||
statusColor = AppColor.info;
|
||||
statusText = 'Refunded';
|
||||
statusIcon = Icons.undo;
|
||||
} else {
|
||||
// Handle status values (only pending and completed)
|
||||
switch (order.status.toLowerCase()) {
|
||||
case 'completed':
|
||||
case 'paid':
|
||||
case 'finished':
|
||||
statusColor = AppColor.success;
|
||||
statusText = 'Completed';
|
||||
statusIcon = Icons.check_circle;
|
||||
break;
|
||||
case 'pending':
|
||||
case 'waiting':
|
||||
case 'processing':
|
||||
statusColor = AppColor.warning;
|
||||
statusText = 'Pending';
|
||||
statusIcon = Icons.schedule;
|
||||
break;
|
||||
default:
|
||||
statusColor = AppColor.textSecondary;
|
||||
statusText = order.status;
|
||||
statusIcon = Icons.info;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return Container(
|
||||
@ -174,7 +163,7 @@ class TransactionTile extends StatelessWidget {
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildTransactionInfo() {
|
||||
Widget _buildOrderInfo() {
|
||||
return Row(
|
||||
children: [
|
||||
Expanded(
|
||||
@ -184,11 +173,11 @@ class TransactionTile extends StatelessWidget {
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Icon(Icons.person_outline, size: 16, color: AppColor.primary),
|
||||
Icon(_getOrderInfoIcon(), size: 16, color: AppColor.primary),
|
||||
const SizedBox(width: 6),
|
||||
Expanded(
|
||||
child: Text(
|
||||
transaction.customerName,
|
||||
_getOrderInfoText(),
|
||||
style: const TextStyle(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w600,
|
||||
@ -209,7 +198,7 @@ class TransactionTile extends StatelessWidget {
|
||||
),
|
||||
const SizedBox(width: 6),
|
||||
Text(
|
||||
'${transaction.itemCount} items',
|
||||
'${order.orderItems.length} items',
|
||||
style: const TextStyle(
|
||||
fontSize: 13,
|
||||
color: AppColor.textSecondary,
|
||||
@ -230,13 +219,13 @@ class TransactionTile extends StatelessWidget {
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Icon(
|
||||
_getPaymentIcon(transaction.paymentMethod),
|
||||
_getOrderTypeIcon(order.orderType),
|
||||
size: 16,
|
||||
color: AppColor.primary,
|
||||
),
|
||||
const SizedBox(width: 6),
|
||||
Text(
|
||||
transaction.paymentMethod,
|
||||
order.orderType.isNotEmpty ? order.orderType : 'Dine In',
|
||||
style: const TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w500,
|
||||
@ -285,13 +274,24 @@ class TransactionTile extends StatelessWidget {
|
||||
),
|
||||
const SizedBox(height: 4),
|
||||
Text(
|
||||
'Rp ${NumberFormat('#,###').format(transaction.totalAmount)}',
|
||||
'Rp ${NumberFormat('#,###').format(order.totalAmount)}',
|
||||
style: const TextStyle(
|
||||
fontSize: 24,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: AppColor.textWhite,
|
||||
),
|
||||
),
|
||||
if (order.remainingAmount > 0) ...[
|
||||
const SizedBox(height: 4),
|
||||
Text(
|
||||
'Remaining: Rp ${NumberFormat('#,###').format(order.remainingAmount)}',
|
||||
style: const TextStyle(
|
||||
fontSize: 12,
|
||||
color: AppColor.textWhite,
|
||||
fontWeight: FontWeight.w400,
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
Container(
|
||||
@ -300,8 +300,8 @@ class TransactionTile extends StatelessWidget {
|
||||
color: AppColor.backgroundLight.withOpacity(0.2),
|
||||
shape: BoxShape.circle,
|
||||
),
|
||||
child: const Icon(
|
||||
Icons.attach_money,
|
||||
child: Icon(
|
||||
_getPaymentStatusIcon(order.paymentStatus),
|
||||
color: AppColor.textWhite,
|
||||
size: 24,
|
||||
),
|
||||
@ -312,19 +312,32 @@ class TransactionTile extends StatelessWidget {
|
||||
}
|
||||
|
||||
Widget _buildFooterActions() {
|
||||
// Don't show anything if order is void or refunded
|
||||
if (order.isVoid || order.isRefund) {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
|
||||
return Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Text(
|
||||
'ID: ${transaction.id}',
|
||||
style: const TextStyle(
|
||||
fontSize: 11,
|
||||
color: AppColor.textLight,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
if (order.payments.isNotEmpty) ...[
|
||||
const SizedBox(height: 2),
|
||||
Text(
|
||||
'Payment: ${_getPaymentMethods()}',
|
||||
style: const TextStyle(
|
||||
fontSize: 11,
|
||||
color: AppColor.textLight,
|
||||
fontWeight: FontWeight.w400,
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
if (transaction.status == TransactionStatus.completed) ...[
|
||||
if (order.status.toLowerCase() == 'completed') ...[
|
||||
_buildActionButton(
|
||||
icon: Icons.print,
|
||||
label: 'Print',
|
||||
@ -377,25 +390,90 @@ class TransactionTile extends StatelessWidget {
|
||||
);
|
||||
}
|
||||
|
||||
IconData _getPaymentIcon(String paymentMethod) {
|
||||
switch (paymentMethod.toLowerCase()) {
|
||||
case 'cash':
|
||||
return Icons.payments;
|
||||
case 'card':
|
||||
case 'credit card':
|
||||
case 'debit card':
|
||||
return Icons.credit_card;
|
||||
case 'qris':
|
||||
case 'qr code':
|
||||
return Icons.qr_code;
|
||||
case 'transfer':
|
||||
case 'bank transfer':
|
||||
return Icons.account_balance;
|
||||
case 'e-wallet':
|
||||
case 'digital wallet':
|
||||
return Icons.account_balance_wallet;
|
||||
IconData _getOrderInfoIcon() {
|
||||
switch (order.orderType.toLowerCase()) {
|
||||
case 'dine in':
|
||||
case 'dine_in':
|
||||
return Icons.table_restaurant_outlined;
|
||||
case 'takeaway':
|
||||
case 'take_away':
|
||||
case 'pickup':
|
||||
return Icons.person_outline;
|
||||
case 'delivery':
|
||||
return Icons.location_on_outlined;
|
||||
default:
|
||||
return Icons.payment;
|
||||
return Icons.receipt_outlined;
|
||||
}
|
||||
}
|
||||
|
||||
String _getOrderInfoText() {
|
||||
switch (order.orderType.toLowerCase()) {
|
||||
case 'dine in':
|
||||
case 'dine_in':
|
||||
return 'Table ${order.tableNumber.isNotEmpty ? order.tableNumber : 'N/A'}';
|
||||
case 'takeaway':
|
||||
case 'take_away':
|
||||
case 'pickup':
|
||||
return 'Pickup Order';
|
||||
case 'delivery':
|
||||
return 'Delivery Order';
|
||||
default:
|
||||
return order.tableNumber.isNotEmpty
|
||||
? 'Table ${order.tableNumber}'
|
||||
: 'Order ${order.orderNumber}';
|
||||
}
|
||||
}
|
||||
|
||||
IconData _getOrderTypeIcon(String orderType) {
|
||||
switch (orderType.toLowerCase()) {
|
||||
case 'dine in':
|
||||
case 'dine_in':
|
||||
return Icons.restaurant;
|
||||
case 'takeaway':
|
||||
case 'take_away':
|
||||
case 'pickup':
|
||||
return Icons.shopping_bag;
|
||||
case 'delivery':
|
||||
return Icons.delivery_dining;
|
||||
default:
|
||||
return Icons.restaurant_menu;
|
||||
}
|
||||
}
|
||||
|
||||
IconData _getPaymentStatusIcon(String paymentStatus) {
|
||||
switch (paymentStatus.toLowerCase()) {
|
||||
case 'paid':
|
||||
case 'completed':
|
||||
return Icons.check_circle;
|
||||
case 'pending':
|
||||
case 'partial':
|
||||
return Icons.schedule;
|
||||
case 'failed':
|
||||
case 'cancelled':
|
||||
return Icons.error;
|
||||
default:
|
||||
return Icons.attach_money;
|
||||
}
|
||||
}
|
||||
|
||||
String _getPaymentMethods() {
|
||||
if (order.payments.isEmpty) return 'N/A';
|
||||
|
||||
// Get unique payment methods from payments
|
||||
final methods = order.payments
|
||||
.map((payment) => payment.paymentMethodName)
|
||||
.toSet()
|
||||
.join(', ');
|
||||
|
||||
return methods.isEmpty ? 'N/A' : methods;
|
||||
}
|
||||
|
||||
String _formatDate(String dateString) {
|
||||
try {
|
||||
final date = DateTime.parse(dateString);
|
||||
return DateFormat('dd MMM yyyy, HH:mm').format(date);
|
||||
} catch (e) {
|
||||
return dateString;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,12 +1,12 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import '../../../../common/theme/theme.dart';
|
||||
import '../../../../../common/theme/theme.dart';
|
||||
|
||||
class TransactionStatusTile extends StatelessWidget {
|
||||
class OrderStatusTile extends StatelessWidget {
|
||||
final String label;
|
||||
final bool isSelected;
|
||||
final void Function(bool)? onSelected;
|
||||
const TransactionStatusTile({
|
||||
const OrderStatusTile({
|
||||
super.key,
|
||||
required this.label,
|
||||
this.isSelected = false,
|
||||
@ -4,15 +4,15 @@ import 'package:flutter_bloc/flutter_bloc.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 '../../../domain/category/category.dart';
|
||||
import '../../../domain/product/product.dart';
|
||||
import '../../../injection.dart';
|
||||
import '../../components/appbar/appbar.dart';
|
||||
import '../../components/button/button.dart';
|
||||
import '../../components/widgets/empty_widget.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 '../../../../domain/category/category.dart';
|
||||
import '../../../../domain/product/product.dart';
|
||||
import '../../../../injection.dart';
|
||||
import '../../../components/appbar/appbar.dart';
|
||||
import '../../../components/button/button.dart';
|
||||
import '../../../components/widgets/empty_widget.dart';
|
||||
import 'widgets/category_delegate.dart';
|
||||
import 'widgets/product_card.dart';
|
||||
import 'widgets/product_tile.dart';
|
||||
@ -1,7 +1,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import '../../../../common/theme/theme.dart';
|
||||
import '../../../../domain/category/category.dart';
|
||||
import '../../../../../common/theme/theme.dart';
|
||||
import '../../../../../domain/category/category.dart';
|
||||
|
||||
class ProductCategoryHeaderDelegate extends SliverPersistentHeaderDelegate {
|
||||
final List<Category> categories;
|
||||
@ -1,9 +1,9 @@
|
||||
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';
|
||||
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});
|
||||
@ -1,10 +1,10 @@
|
||||
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';
|
||||
import '../../../components/spacer/spacer.dart';
|
||||
import '../../../../../common/extension/extension.dart';
|
||||
import '../../../../../common/theme/theme.dart';
|
||||
import '../../../../../domain/product/product.dart';
|
||||
import '../../../../components/image/image.dart';
|
||||
import '../../../../components/spacer/spacer.dart';
|
||||
|
||||
class ProductTile extends StatelessWidget {
|
||||
final Product product;
|
||||
@ -1,296 +0,0 @@
|
||||
import 'package:auto_route/auto_route.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:line_icons/line_icons.dart';
|
||||
|
||||
import '../../../common/theme/theme.dart';
|
||||
import '../../components/appbar/appbar.dart';
|
||||
import '../../components/button/button.dart';
|
||||
import '../../components/spacer/spacer.dart';
|
||||
import 'widgets/status_tile.dart';
|
||||
import 'widgets/transaction_tile.dart';
|
||||
|
||||
@RoutePage()
|
||||
class TransactionPage extends StatefulWidget {
|
||||
const TransactionPage({super.key});
|
||||
|
||||
@override
|
||||
State<TransactionPage> createState() => _TransactionPageState();
|
||||
}
|
||||
|
||||
class _TransactionPageState extends State<TransactionPage>
|
||||
with TickerProviderStateMixin {
|
||||
late AnimationController _fadeController;
|
||||
late AnimationController _slideController;
|
||||
late Animation<double> _fadeAnimation;
|
||||
late Animation<Offset> _slideAnimation;
|
||||
|
||||
// Filter state
|
||||
String selectedFilter = 'All';
|
||||
final List<String> filterOptions = [
|
||||
'All',
|
||||
'Completed',
|
||||
'Pending',
|
||||
'Refunded',
|
||||
];
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
||||
_fadeController = AnimationController(
|
||||
duration: const Duration(milliseconds: 800),
|
||||
vsync: this,
|
||||
);
|
||||
|
||||
_slideController = AnimationController(
|
||||
duration: const Duration(milliseconds: 1000),
|
||||
vsync: this,
|
||||
);
|
||||
|
||||
_fadeAnimation = Tween<double>(begin: 0.0, end: 1.0).animate(
|
||||
CurvedAnimation(parent: _fadeController, curve: Curves.easeInOut),
|
||||
);
|
||||
|
||||
_slideAnimation =
|
||||
Tween<Offset>(begin: const Offset(0, 0.3), end: Offset.zero).animate(
|
||||
CurvedAnimation(parent: _slideController, curve: Curves.elasticOut),
|
||||
);
|
||||
|
||||
_fadeController.forward();
|
||||
_slideController.forward();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_fadeController.dispose();
|
||||
_slideController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
final sampleTransactions = [
|
||||
Transaction(
|
||||
id: 'TXN001',
|
||||
customerName: 'John Doe',
|
||||
date: DateTime.now().subtract(const Duration(hours: 2)),
|
||||
totalAmount: 125000,
|
||||
itemCount: 3,
|
||||
paymentMethod: 'Cash',
|
||||
status: TransactionStatus.completed,
|
||||
receiptNumber: 'RCP-2024-001',
|
||||
),
|
||||
Transaction(
|
||||
id: 'TXN002',
|
||||
customerName: 'Jane Smith',
|
||||
date: DateTime.now().subtract(const Duration(hours: 5)),
|
||||
totalAmount: 87500,
|
||||
itemCount: 2,
|
||||
paymentMethod: 'QRIS',
|
||||
status: TransactionStatus.pending,
|
||||
receiptNumber: 'RCP-2024-002',
|
||||
),
|
||||
Transaction(
|
||||
id: 'TXN003',
|
||||
customerName: 'Bob Johnson',
|
||||
date: DateTime.now().subtract(const Duration(days: 1)),
|
||||
totalAmount: 250000,
|
||||
itemCount: 5,
|
||||
paymentMethod: 'Credit Card',
|
||||
status: TransactionStatus.refunded,
|
||||
receiptNumber: 'RCP-2024-003',
|
||||
),
|
||||
];
|
||||
|
||||
// Filter transactions based on selected status
|
||||
List<Transaction> get filteredTransactions {
|
||||
if (selectedFilter == 'All') {
|
||||
return sampleTransactions;
|
||||
}
|
||||
|
||||
TransactionStatus? filterStatus;
|
||||
switch (selectedFilter) {
|
||||
case 'Completed':
|
||||
filterStatus = TransactionStatus.completed;
|
||||
break;
|
||||
case 'Pending':
|
||||
filterStatus = TransactionStatus.pending;
|
||||
break;
|
||||
case 'Refunded':
|
||||
filterStatus = TransactionStatus.refunded;
|
||||
break;
|
||||
}
|
||||
|
||||
return sampleTransactions
|
||||
.where((transaction) => transaction.status == filterStatus)
|
||||
.toList();
|
||||
}
|
||||
|
||||
// Build filter chip
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
backgroundColor: AppColor.background,
|
||||
body: CustomScrollView(
|
||||
slivers: [
|
||||
// Custom App Bar with Hero Effect
|
||||
SliverAppBar(
|
||||
expandedHeight: 120,
|
||||
floating: true,
|
||||
pinned: true,
|
||||
backgroundColor: AppColor.primary,
|
||||
centerTitle: false,
|
||||
flexibleSpace: CustomAppBar(title: 'Transaction', isBack: false),
|
||||
actions: [
|
||||
ActionIconButton(onTap: () {}, icon: LineIcons.filter),
|
||||
SpaceWidth(8),
|
||||
],
|
||||
),
|
||||
|
||||
// Pinned Filter Section
|
||||
SliverPersistentHeader(
|
||||
pinned: true,
|
||||
delegate: _FilterHeaderDelegate(
|
||||
child: Container(
|
||||
color: AppColor.background,
|
||||
padding: EdgeInsets.fromLTRB(
|
||||
AppValue.padding,
|
||||
10,
|
||||
AppValue.padding,
|
||||
10,
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
SingleChildScrollView(
|
||||
scrollDirection: Axis.horizontal,
|
||||
child: Row(
|
||||
children: filterOptions.map((option) {
|
||||
final index = filterOptions.indexOf(option);
|
||||
return Padding(
|
||||
padding: EdgeInsets.only(
|
||||
right: index < filterOptions.length - 1 ? 8 : 0,
|
||||
),
|
||||
child: TransactionStatusTile(
|
||||
label: option,
|
||||
isSelected: option == selectedFilter,
|
||||
onSelected: (isSelected) {
|
||||
if (isSelected) {
|
||||
setState(() {
|
||||
selectedFilter = option;
|
||||
});
|
||||
}
|
||||
},
|
||||
),
|
||||
);
|
||||
}).toList(),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
// Content
|
||||
SliverPadding(
|
||||
padding: EdgeInsets.all(AppValue.padding),
|
||||
sliver: SliverList(
|
||||
delegate: SliverChildListDelegate([
|
||||
FadeTransition(
|
||||
opacity: _fadeAnimation,
|
||||
child: SlideTransition(
|
||||
position: _slideAnimation,
|
||||
child: Column(
|
||||
children: [
|
||||
// Show filtered transaction count
|
||||
if (selectedFilter != 'All')
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(bottom: 16),
|
||||
child: Row(
|
||||
children: [
|
||||
Text(
|
||||
'${filteredTransactions.length} ${selectedFilter.toLowerCase()} transaction${filteredTransactions.length != 1 ? 's' : ''}',
|
||||
style: TextStyle(
|
||||
color: AppColor.textSecondary,
|
||||
fontSize: 14,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
// Transaction List
|
||||
filteredTransactions.isEmpty
|
||||
? Container(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
vertical: 40,
|
||||
),
|
||||
child: Column(
|
||||
children: [
|
||||
Icon(
|
||||
LineIcons.receipt,
|
||||
size: 64,
|
||||
color: AppColor.textSecondary.withOpacity(
|
||||
0.5,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
Text(
|
||||
'No ${selectedFilter.toLowerCase()} transactions found',
|
||||
style: TextStyle(
|
||||
color: AppColor.textSecondary,
|
||||
fontSize: 16,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
: Column(
|
||||
children: filteredTransactions.map((
|
||||
transaction,
|
||||
) {
|
||||
return TransactionTile(
|
||||
transaction: transaction,
|
||||
onTap: () {},
|
||||
);
|
||||
}).toList(),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
]),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Custom delegate for pinned filter header
|
||||
class _FilterHeaderDelegate extends SliverPersistentHeaderDelegate {
|
||||
final Widget child;
|
||||
|
||||
_FilterHeaderDelegate({required this.child});
|
||||
|
||||
@override
|
||||
double get minExtent => 70; // Minimum height when collapsed
|
||||
|
||||
@override
|
||||
double get maxExtent => 70; // Maximum height when expanded
|
||||
|
||||
@override
|
||||
Widget build(
|
||||
BuildContext context,
|
||||
double shrinkOffset,
|
||||
bool overlapsContent,
|
||||
) {
|
||||
return child;
|
||||
}
|
||||
|
||||
@override
|
||||
bool shouldRebuild(covariant SliverPersistentHeaderDelegate oldDelegate) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -1,97 +0,0 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import '../../../../common/theme/theme.dart';
|
||||
|
||||
class TransactionAppBar extends StatelessWidget {
|
||||
final Animation<double> rotationAnimation;
|
||||
const TransactionAppBar({super.key, required this.rotationAnimation});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return FlexibleSpaceBar(
|
||||
titlePadding: const EdgeInsets.only(left: 20, bottom: 16),
|
||||
title: Text(
|
||||
'Transaksi',
|
||||
style: AppStyle.xl.copyWith(
|
||||
color: AppColor.textWhite,
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
|
||||
background: Container(
|
||||
decoration: const BoxDecoration(
|
||||
gradient: LinearGradient(
|
||||
colors: AppColor.primaryGradient,
|
||||
begin: Alignment.topCenter,
|
||||
end: Alignment.bottomCenter,
|
||||
),
|
||||
),
|
||||
child: Stack(
|
||||
children: [
|
||||
Positioned(
|
||||
right: -20,
|
||||
top: -20,
|
||||
child: AnimatedBuilder(
|
||||
animation: rotationAnimation,
|
||||
builder: (context, child) {
|
||||
return Transform.rotate(
|
||||
angle: rotationAnimation.value,
|
||||
child: Container(
|
||||
width: 100,
|
||||
height: 100,
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
color: AppColor.white.withOpacity(0.1),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
Positioned(
|
||||
left: -30,
|
||||
bottom: -30,
|
||||
child: AnimatedBuilder(
|
||||
animation: rotationAnimation,
|
||||
builder: (context, child) {
|
||||
return Transform.rotate(
|
||||
angle: -rotationAnimation.value * 0.5,
|
||||
child: Container(
|
||||
width: 80,
|
||||
height: 80,
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
color: AppColor.white.withOpacity(0.05),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
Positioned(
|
||||
right: 80,
|
||||
bottom: 30,
|
||||
child: AnimatedBuilder(
|
||||
animation: rotationAnimation,
|
||||
builder: (context, child) {
|
||||
return Transform.rotate(
|
||||
angle: -rotationAnimation.value * 0.2,
|
||||
child: Container(
|
||||
width: 40,
|
||||
height: 40,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
color: AppColor.white.withOpacity(0.08),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -16,7 +16,7 @@ class AppRouter extends RootStackRouter {
|
||||
page: MainRoute.page,
|
||||
children: [
|
||||
AutoRoute(page: HomeRoute.page),
|
||||
AutoRoute(page: TransactionRoute.page),
|
||||
AutoRoute(page: OrderRoute.page),
|
||||
AutoRoute(page: ReportRoute.page),
|
||||
AutoRoute(page: ProfileRoute.page),
|
||||
],
|
||||
@ -51,5 +51,8 @@ class AppRouter extends RootStackRouter {
|
||||
|
||||
// Error
|
||||
AutoRoute(page: ErrorRoute.page),
|
||||
|
||||
// Order
|
||||
AutoRoute(page: OrderDetailRoute.page),
|
||||
];
|
||||
}
|
||||
|
||||
@ -9,6 +9,7 @@
|
||||
// coverage:ignore-file
|
||||
|
||||
// ignore_for_file: no_leading_underscores_for_library_prefixes
|
||||
import 'package:apskel_owner_flutter/domain/order/order.dart' as _i21;
|
||||
import 'package:apskel_owner_flutter/presentation/pages/auth/login/login_page.dart'
|
||||
as _i8;
|
||||
import 'package:apskel_owner_flutter/presentation/pages/customer/customer_page.dart'
|
||||
@ -27,50 +28,52 @@ import 'package:apskel_owner_flutter/presentation/pages/language/language_page.d
|
||||
as _i7;
|
||||
import 'package:apskel_owner_flutter/presentation/pages/main/main_page.dart'
|
||||
as _i9;
|
||||
import 'package:apskel_owner_flutter/presentation/pages/product/product_page.dart'
|
||||
import 'package:apskel_owner_flutter/presentation/pages/order/order_detail/order_detail_page.dart'
|
||||
as _i10;
|
||||
import 'package:apskel_owner_flutter/presentation/pages/profile/profile_page.dart'
|
||||
import 'package:apskel_owner_flutter/presentation/pages/order/order_list/order_page.dart'
|
||||
as _i11;
|
||||
import 'package:apskel_owner_flutter/presentation/pages/purchase/purchase_page.dart'
|
||||
import 'package:apskel_owner_flutter/presentation/pages/product/product_list/product_page.dart'
|
||||
as _i12;
|
||||
import 'package:apskel_owner_flutter/presentation/pages/report/report_page.dart'
|
||||
import 'package:apskel_owner_flutter/presentation/pages/profile/profile_page.dart'
|
||||
as _i13;
|
||||
import 'package:apskel_owner_flutter/presentation/pages/sales/sales_page.dart'
|
||||
import 'package:apskel_owner_flutter/presentation/pages/purchase/purchase_page.dart'
|
||||
as _i14;
|
||||
import 'package:apskel_owner_flutter/presentation/pages/schedule/schedule_page.dart'
|
||||
import 'package:apskel_owner_flutter/presentation/pages/report/report_page.dart'
|
||||
as _i15;
|
||||
import 'package:apskel_owner_flutter/presentation/pages/splash/splash_page.dart'
|
||||
import 'package:apskel_owner_flutter/presentation/pages/sales/sales_page.dart'
|
||||
as _i16;
|
||||
import 'package:apskel_owner_flutter/presentation/pages/transaction/transaction_page.dart'
|
||||
import 'package:apskel_owner_flutter/presentation/pages/schedule/schedule_page.dart'
|
||||
as _i17;
|
||||
import 'package:auto_route/auto_route.dart' as _i18;
|
||||
import 'package:flutter/material.dart' as _i19;
|
||||
import 'package:apskel_owner_flutter/presentation/pages/splash/splash_page.dart'
|
||||
as _i18;
|
||||
import 'package:auto_route/auto_route.dart' as _i19;
|
||||
import 'package:flutter/material.dart' as _i20;
|
||||
|
||||
/// generated route for
|
||||
/// [_i1.CustomerPage]
|
||||
class CustomerRoute extends _i18.PageRouteInfo<void> {
|
||||
const CustomerRoute({List<_i18.PageRouteInfo>? children})
|
||||
class CustomerRoute extends _i19.PageRouteInfo<void> {
|
||||
const CustomerRoute({List<_i19.PageRouteInfo>? children})
|
||||
: super(CustomerRoute.name, initialChildren: children);
|
||||
|
||||
static const String name = 'CustomerRoute';
|
||||
|
||||
static _i18.PageInfo page = _i18.PageInfo(
|
||||
static _i19.PageInfo page = _i19.PageInfo(
|
||||
name,
|
||||
builder: (data) {
|
||||
return _i18.WrappedRoute(child: const _i1.CustomerPage());
|
||||
return _i19.WrappedRoute(child: const _i1.CustomerPage());
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/// generated route for
|
||||
/// [_i2.DailyTasksFormPage]
|
||||
class DailyTasksFormRoute extends _i18.PageRouteInfo<void> {
|
||||
const DailyTasksFormRoute({List<_i18.PageRouteInfo>? children})
|
||||
class DailyTasksFormRoute extends _i19.PageRouteInfo<void> {
|
||||
const DailyTasksFormRoute({List<_i19.PageRouteInfo>? children})
|
||||
: super(DailyTasksFormRoute.name, initialChildren: children);
|
||||
|
||||
static const String name = 'DailyTasksFormRoute';
|
||||
|
||||
static _i18.PageInfo page = _i18.PageInfo(
|
||||
static _i19.PageInfo page = _i19.PageInfo(
|
||||
name,
|
||||
builder: (data) {
|
||||
return const _i2.DailyTasksFormPage();
|
||||
@ -80,16 +83,16 @@ class DailyTasksFormRoute extends _i18.PageRouteInfo<void> {
|
||||
|
||||
/// generated route for
|
||||
/// [_i3.ErrorPage]
|
||||
class ErrorRoute extends _i18.PageRouteInfo<ErrorRouteArgs> {
|
||||
class ErrorRoute extends _i19.PageRouteInfo<ErrorRouteArgs> {
|
||||
ErrorRoute({
|
||||
_i19.Key? key,
|
||||
_i20.Key? key,
|
||||
String? title,
|
||||
String? message,
|
||||
_i19.VoidCallback? onRetry,
|
||||
_i19.VoidCallback? onBack,
|
||||
_i20.VoidCallback? onRetry,
|
||||
_i20.VoidCallback? onBack,
|
||||
String? errorCode,
|
||||
_i19.IconData? errorIcon,
|
||||
List<_i18.PageRouteInfo>? children,
|
||||
_i20.IconData? errorIcon,
|
||||
List<_i19.PageRouteInfo>? children,
|
||||
}) : super(
|
||||
ErrorRoute.name,
|
||||
args: ErrorRouteArgs(
|
||||
@ -106,7 +109,7 @@ class ErrorRoute extends _i18.PageRouteInfo<ErrorRouteArgs> {
|
||||
|
||||
static const String name = 'ErrorRoute';
|
||||
|
||||
static _i18.PageInfo page = _i18.PageInfo(
|
||||
static _i19.PageInfo page = _i19.PageInfo(
|
||||
name,
|
||||
builder: (data) {
|
||||
final args = data.argsAs<ErrorRouteArgs>(
|
||||
@ -136,19 +139,19 @@ class ErrorRouteArgs {
|
||||
this.errorIcon,
|
||||
});
|
||||
|
||||
final _i19.Key? key;
|
||||
final _i20.Key? key;
|
||||
|
||||
final String? title;
|
||||
|
||||
final String? message;
|
||||
|
||||
final _i19.VoidCallback? onRetry;
|
||||
final _i20.VoidCallback? onRetry;
|
||||
|
||||
final _i19.VoidCallback? onBack;
|
||||
final _i20.VoidCallback? onBack;
|
||||
|
||||
final String? errorCode;
|
||||
|
||||
final _i19.IconData? errorIcon;
|
||||
final _i20.IconData? errorIcon;
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
@ -158,29 +161,29 @@ class ErrorRouteArgs {
|
||||
|
||||
/// generated route for
|
||||
/// [_i4.FinancePage]
|
||||
class FinanceRoute extends _i18.PageRouteInfo<void> {
|
||||
const FinanceRoute({List<_i18.PageRouteInfo>? children})
|
||||
class FinanceRoute extends _i19.PageRouteInfo<void> {
|
||||
const FinanceRoute({List<_i19.PageRouteInfo>? children})
|
||||
: super(FinanceRoute.name, initialChildren: children);
|
||||
|
||||
static const String name = 'FinanceRoute';
|
||||
|
||||
static _i18.PageInfo page = _i18.PageInfo(
|
||||
static _i19.PageInfo page = _i19.PageInfo(
|
||||
name,
|
||||
builder: (data) {
|
||||
return _i18.WrappedRoute(child: const _i4.FinancePage());
|
||||
return _i19.WrappedRoute(child: const _i4.FinancePage());
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/// generated route for
|
||||
/// [_i5.HomePage]
|
||||
class HomeRoute extends _i18.PageRouteInfo<void> {
|
||||
const HomeRoute({List<_i18.PageRouteInfo>? children})
|
||||
class HomeRoute extends _i19.PageRouteInfo<void> {
|
||||
const HomeRoute({List<_i19.PageRouteInfo>? children})
|
||||
: super(HomeRoute.name, initialChildren: children);
|
||||
|
||||
static const String name = 'HomeRoute';
|
||||
|
||||
static _i18.PageInfo page = _i18.PageInfo(
|
||||
static _i19.PageInfo page = _i19.PageInfo(
|
||||
name,
|
||||
builder: (data) {
|
||||
return const _i5.HomePage();
|
||||
@ -190,29 +193,29 @@ class HomeRoute extends _i18.PageRouteInfo<void> {
|
||||
|
||||
/// generated route for
|
||||
/// [_i6.InventoryPage]
|
||||
class InventoryRoute extends _i18.PageRouteInfo<void> {
|
||||
const InventoryRoute({List<_i18.PageRouteInfo>? children})
|
||||
class InventoryRoute extends _i19.PageRouteInfo<void> {
|
||||
const InventoryRoute({List<_i19.PageRouteInfo>? children})
|
||||
: super(InventoryRoute.name, initialChildren: children);
|
||||
|
||||
static const String name = 'InventoryRoute';
|
||||
|
||||
static _i18.PageInfo page = _i18.PageInfo(
|
||||
static _i19.PageInfo page = _i19.PageInfo(
|
||||
name,
|
||||
builder: (data) {
|
||||
return _i18.WrappedRoute(child: const _i6.InventoryPage());
|
||||
return _i19.WrappedRoute(child: const _i6.InventoryPage());
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/// generated route for
|
||||
/// [_i7.LanguagePage]
|
||||
class LanguageRoute extends _i18.PageRouteInfo<void> {
|
||||
const LanguageRoute({List<_i18.PageRouteInfo>? children})
|
||||
class LanguageRoute extends _i19.PageRouteInfo<void> {
|
||||
const LanguageRoute({List<_i19.PageRouteInfo>? children})
|
||||
: super(LanguageRoute.name, initialChildren: children);
|
||||
|
||||
static const String name = 'LanguageRoute';
|
||||
|
||||
static _i18.PageInfo page = _i18.PageInfo(
|
||||
static _i19.PageInfo page = _i19.PageInfo(
|
||||
name,
|
||||
builder: (data) {
|
||||
return const _i7.LanguagePage();
|
||||
@ -222,29 +225,29 @@ class LanguageRoute extends _i18.PageRouteInfo<void> {
|
||||
|
||||
/// generated route for
|
||||
/// [_i8.LoginPage]
|
||||
class LoginRoute extends _i18.PageRouteInfo<void> {
|
||||
const LoginRoute({List<_i18.PageRouteInfo>? children})
|
||||
class LoginRoute extends _i19.PageRouteInfo<void> {
|
||||
const LoginRoute({List<_i19.PageRouteInfo>? children})
|
||||
: super(LoginRoute.name, initialChildren: children);
|
||||
|
||||
static const String name = 'LoginRoute';
|
||||
|
||||
static _i18.PageInfo page = _i18.PageInfo(
|
||||
static _i19.PageInfo page = _i19.PageInfo(
|
||||
name,
|
||||
builder: (data) {
|
||||
return _i18.WrappedRoute(child: const _i8.LoginPage());
|
||||
return _i19.WrappedRoute(child: const _i8.LoginPage());
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/// generated route for
|
||||
/// [_i9.MainPage]
|
||||
class MainRoute extends _i18.PageRouteInfo<void> {
|
||||
const MainRoute({List<_i18.PageRouteInfo>? children})
|
||||
class MainRoute extends _i19.PageRouteInfo<void> {
|
||||
const MainRoute({List<_i19.PageRouteInfo>? children})
|
||||
: super(MainRoute.name, initialChildren: children);
|
||||
|
||||
static const String name = 'MainRoute';
|
||||
|
||||
static _i18.PageInfo page = _i18.PageInfo(
|
||||
static _i19.PageInfo page = _i19.PageInfo(
|
||||
name,
|
||||
builder: (data) {
|
||||
return const _i9.MainPage();
|
||||
@ -253,129 +256,166 @@ class MainRoute extends _i18.PageRouteInfo<void> {
|
||||
}
|
||||
|
||||
/// generated route for
|
||||
/// [_i10.ProductPage]
|
||||
class ProductRoute extends _i18.PageRouteInfo<void> {
|
||||
const ProductRoute({List<_i18.PageRouteInfo>? children})
|
||||
/// [_i10.OrderDetailPage]
|
||||
class OrderDetailRoute extends _i19.PageRouteInfo<OrderDetailRouteArgs> {
|
||||
OrderDetailRoute({
|
||||
_i20.Key? key,
|
||||
required _i21.Order order,
|
||||
List<_i19.PageRouteInfo>? children,
|
||||
}) : super(
|
||||
OrderDetailRoute.name,
|
||||
args: OrderDetailRouteArgs(key: key, order: order),
|
||||
initialChildren: children,
|
||||
);
|
||||
|
||||
static const String name = 'OrderDetailRoute';
|
||||
|
||||
static _i19.PageInfo page = _i19.PageInfo(
|
||||
name,
|
||||
builder: (data) {
|
||||
final args = data.argsAs<OrderDetailRouteArgs>();
|
||||
return _i10.OrderDetailPage(key: args.key, order: args.order);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
class OrderDetailRouteArgs {
|
||||
const OrderDetailRouteArgs({this.key, required this.order});
|
||||
|
||||
final _i20.Key? key;
|
||||
|
||||
final _i21.Order order;
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'OrderDetailRouteArgs{key: $key, order: $order}';
|
||||
}
|
||||
}
|
||||
|
||||
/// generated route for
|
||||
/// [_i11.OrderPage]
|
||||
class OrderRoute extends _i19.PageRouteInfo<void> {
|
||||
const OrderRoute({List<_i19.PageRouteInfo>? children})
|
||||
: super(OrderRoute.name, initialChildren: children);
|
||||
|
||||
static const String name = 'OrderRoute';
|
||||
|
||||
static _i19.PageInfo page = _i19.PageInfo(
|
||||
name,
|
||||
builder: (data) {
|
||||
return _i19.WrappedRoute(child: const _i11.OrderPage());
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/// generated route for
|
||||
/// [_i12.ProductPage]
|
||||
class ProductRoute extends _i19.PageRouteInfo<void> {
|
||||
const ProductRoute({List<_i19.PageRouteInfo>? children})
|
||||
: super(ProductRoute.name, initialChildren: children);
|
||||
|
||||
static const String name = 'ProductRoute';
|
||||
|
||||
static _i18.PageInfo page = _i18.PageInfo(
|
||||
static _i19.PageInfo page = _i19.PageInfo(
|
||||
name,
|
||||
builder: (data) {
|
||||
return _i18.WrappedRoute(child: const _i10.ProductPage());
|
||||
return _i19.WrappedRoute(child: const _i12.ProductPage());
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/// generated route for
|
||||
/// [_i11.ProfilePage]
|
||||
class ProfileRoute extends _i18.PageRouteInfo<void> {
|
||||
const ProfileRoute({List<_i18.PageRouteInfo>? children})
|
||||
/// [_i13.ProfilePage]
|
||||
class ProfileRoute extends _i19.PageRouteInfo<void> {
|
||||
const ProfileRoute({List<_i19.PageRouteInfo>? children})
|
||||
: super(ProfileRoute.name, initialChildren: children);
|
||||
|
||||
static const String name = 'ProfileRoute';
|
||||
|
||||
static _i18.PageInfo page = _i18.PageInfo(
|
||||
static _i19.PageInfo page = _i19.PageInfo(
|
||||
name,
|
||||
builder: (data) {
|
||||
return _i18.WrappedRoute(child: const _i11.ProfilePage());
|
||||
return _i19.WrappedRoute(child: const _i13.ProfilePage());
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/// generated route for
|
||||
/// [_i12.PurchasePage]
|
||||
class PurchaseRoute extends _i18.PageRouteInfo<void> {
|
||||
const PurchaseRoute({List<_i18.PageRouteInfo>? children})
|
||||
/// [_i14.PurchasePage]
|
||||
class PurchaseRoute extends _i19.PageRouteInfo<void> {
|
||||
const PurchaseRoute({List<_i19.PageRouteInfo>? children})
|
||||
: super(PurchaseRoute.name, initialChildren: children);
|
||||
|
||||
static const String name = 'PurchaseRoute';
|
||||
|
||||
static _i18.PageInfo page = _i18.PageInfo(
|
||||
static _i19.PageInfo page = _i19.PageInfo(
|
||||
name,
|
||||
builder: (data) {
|
||||
return const _i12.PurchasePage();
|
||||
return const _i14.PurchasePage();
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/// generated route for
|
||||
/// [_i13.ReportPage]
|
||||
class ReportRoute extends _i18.PageRouteInfo<void> {
|
||||
const ReportRoute({List<_i18.PageRouteInfo>? children})
|
||||
/// [_i15.ReportPage]
|
||||
class ReportRoute extends _i19.PageRouteInfo<void> {
|
||||
const ReportRoute({List<_i19.PageRouteInfo>? children})
|
||||
: super(ReportRoute.name, initialChildren: children);
|
||||
|
||||
static const String name = 'ReportRoute';
|
||||
|
||||
static _i18.PageInfo page = _i18.PageInfo(
|
||||
static _i19.PageInfo page = _i19.PageInfo(
|
||||
name,
|
||||
builder: (data) {
|
||||
return _i18.WrappedRoute(child: const _i13.ReportPage());
|
||||
return _i19.WrappedRoute(child: const _i15.ReportPage());
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/// generated route for
|
||||
/// [_i14.SalesPage]
|
||||
class SalesRoute extends _i18.PageRouteInfo<void> {
|
||||
const SalesRoute({List<_i18.PageRouteInfo>? children})
|
||||
/// [_i16.SalesPage]
|
||||
class SalesRoute extends _i19.PageRouteInfo<void> {
|
||||
const SalesRoute({List<_i19.PageRouteInfo>? children})
|
||||
: super(SalesRoute.name, initialChildren: children);
|
||||
|
||||
static const String name = 'SalesRoute';
|
||||
|
||||
static _i18.PageInfo page = _i18.PageInfo(
|
||||
static _i19.PageInfo page = _i19.PageInfo(
|
||||
name,
|
||||
builder: (data) {
|
||||
return _i18.WrappedRoute(child: const _i14.SalesPage());
|
||||
return _i19.WrappedRoute(child: const _i16.SalesPage());
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/// generated route for
|
||||
/// [_i15.SchedulePage]
|
||||
class ScheduleRoute extends _i18.PageRouteInfo<void> {
|
||||
const ScheduleRoute({List<_i18.PageRouteInfo>? children})
|
||||
/// [_i17.SchedulePage]
|
||||
class ScheduleRoute extends _i19.PageRouteInfo<void> {
|
||||
const ScheduleRoute({List<_i19.PageRouteInfo>? children})
|
||||
: super(ScheduleRoute.name, initialChildren: children);
|
||||
|
||||
static const String name = 'ScheduleRoute';
|
||||
|
||||
static _i18.PageInfo page = _i18.PageInfo(
|
||||
static _i19.PageInfo page = _i19.PageInfo(
|
||||
name,
|
||||
builder: (data) {
|
||||
return const _i15.SchedulePage();
|
||||
return const _i17.SchedulePage();
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/// generated route for
|
||||
/// [_i16.SplashPage]
|
||||
class SplashRoute extends _i18.PageRouteInfo<void> {
|
||||
const SplashRoute({List<_i18.PageRouteInfo>? children})
|
||||
/// [_i18.SplashPage]
|
||||
class SplashRoute extends _i19.PageRouteInfo<void> {
|
||||
const SplashRoute({List<_i19.PageRouteInfo>? children})
|
||||
: super(SplashRoute.name, initialChildren: children);
|
||||
|
||||
static const String name = 'SplashRoute';
|
||||
|
||||
static _i18.PageInfo page = _i18.PageInfo(
|
||||
static _i19.PageInfo page = _i19.PageInfo(
|
||||
name,
|
||||
builder: (data) {
|
||||
return const _i16.SplashPage();
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/// generated route for
|
||||
/// [_i17.TransactionPage]
|
||||
class TransactionRoute extends _i18.PageRouteInfo<void> {
|
||||
const TransactionRoute({List<_i18.PageRouteInfo>? children})
|
||||
: super(TransactionRoute.name, initialChildren: children);
|
||||
|
||||
static const String name = 'TransactionRoute';
|
||||
|
||||
static _i18.PageInfo page = _i18.PageInfo(
|
||||
name,
|
||||
builder: (data) {
|
||||
return const _i17.TransactionPage();
|
||||
return const _i18.SplashPage();
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user