Compare commits

...

7 Commits

Author SHA1 Message Date
efrilm
bfd4604897 feat: update download report 2025-08-19 13:09:00 +07:00
efrilm
60f43f6df7 feat: download report page 2025-08-19 13:01:29 +07:00
efrilm
811ac4b202 feat: comming page 2025-08-19 12:48:06 +07:00
efrilm
b731704a3d feat: home bloc 2025-08-19 12:23:53 +07:00
efrilm
9b51bf2bee feat: order shimmer 2025-08-19 11:44:50 +07:00
efrilm
5b91b5978f feat: order range date filter 2025-08-19 11:42:26 +07:00
efrilm
590bb3329c feat: outlet information page 2025-08-19 11:08:33 +07:00
46 changed files with 4895 additions and 954 deletions

View File

@ -0,0 +1,38 @@
import 'package:dartz/dartz.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:injectable/injectable.dart';
import '../../domain/analytic/analytic.dart';
import '../../domain/analytic/repositories/i_analytic_repository.dart';
part 'home_event.dart';
part 'home_state.dart';
part 'home_bloc.freezed.dart';
@injectable
class HomeBloc extends Bloc<HomeEvent, HomeState> {
final IAnalyticRepository _analyticRepository;
HomeBloc(this._analyticRepository) : super(HomeState.initial()) {
on<HomeEvent>(_onHomeEvent);
}
Future<void> _onHomeEvent(HomeEvent event, Emitter<HomeState> emit) {
return event.map(
fetchedDashboard: (e) async {
emit(state.copyWith(isFetching: true, failureOptionDashboard: none()));
final result = await _analyticRepository.getDashboard(
dateFrom: DateTime.now(),
dateTo: DateTime.now(),
);
var data = result.fold(
(f) => state.copyWith(failureOptionDashboard: optionOf(f)),
(dashboard) => state.copyWith(dashboard: dashboard),
);
emit(data.copyWith(isFetching: false));
},
);
}
}

View File

@ -0,0 +1,370 @@
// 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 'home_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 _$HomeEvent {
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function() fetchedDashboard,
}) => throw _privateConstructorUsedError;
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>({
TResult? Function()? fetchedDashboard,
}) => throw _privateConstructorUsedError;
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({
TResult Function()? fetchedDashboard,
required TResult orElse(),
}) => throw _privateConstructorUsedError;
@optionalTypeArgs
TResult map<TResult extends Object?>({
required TResult Function(_FetchedDashboard value) fetchedDashboard,
}) => throw _privateConstructorUsedError;
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>({
TResult? Function(_FetchedDashboard value)? fetchedDashboard,
}) => throw _privateConstructorUsedError;
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>({
TResult Function(_FetchedDashboard value)? fetchedDashboard,
required TResult orElse(),
}) => throw _privateConstructorUsedError;
}
/// @nodoc
abstract class $HomeEventCopyWith<$Res> {
factory $HomeEventCopyWith(HomeEvent value, $Res Function(HomeEvent) then) =
_$HomeEventCopyWithImpl<$Res, HomeEvent>;
}
/// @nodoc
class _$HomeEventCopyWithImpl<$Res, $Val extends HomeEvent>
implements $HomeEventCopyWith<$Res> {
_$HomeEventCopyWithImpl(this._value, this._then);
// ignore: unused_field
final $Val _value;
// ignore: unused_field
final $Res Function($Val) _then;
/// Create a copy of HomeEvent
/// with the given fields replaced by the non-null parameter values.
}
/// @nodoc
abstract class _$$FetchedDashboardImplCopyWith<$Res> {
factory _$$FetchedDashboardImplCopyWith(
_$FetchedDashboardImpl value,
$Res Function(_$FetchedDashboardImpl) then,
) = __$$FetchedDashboardImplCopyWithImpl<$Res>;
}
/// @nodoc
class __$$FetchedDashboardImplCopyWithImpl<$Res>
extends _$HomeEventCopyWithImpl<$Res, _$FetchedDashboardImpl>
implements _$$FetchedDashboardImplCopyWith<$Res> {
__$$FetchedDashboardImplCopyWithImpl(
_$FetchedDashboardImpl _value,
$Res Function(_$FetchedDashboardImpl) _then,
) : super(_value, _then);
/// Create a copy of HomeEvent
/// with the given fields replaced by the non-null parameter values.
}
/// @nodoc
class _$FetchedDashboardImpl implements _FetchedDashboard {
const _$FetchedDashboardImpl();
@override
String toString() {
return 'HomeEvent.fetchedDashboard()';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType && other is _$FetchedDashboardImpl);
}
@override
int get hashCode => runtimeType.hashCode;
@override
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function() fetchedDashboard,
}) {
return fetchedDashboard();
}
@override
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>({
TResult? Function()? fetchedDashboard,
}) {
return fetchedDashboard?.call();
}
@override
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({
TResult Function()? fetchedDashboard,
required TResult orElse(),
}) {
if (fetchedDashboard != null) {
return fetchedDashboard();
}
return orElse();
}
@override
@optionalTypeArgs
TResult map<TResult extends Object?>({
required TResult Function(_FetchedDashboard value) fetchedDashboard,
}) {
return fetchedDashboard(this);
}
@override
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>({
TResult? Function(_FetchedDashboard value)? fetchedDashboard,
}) {
return fetchedDashboard?.call(this);
}
@override
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>({
TResult Function(_FetchedDashboard value)? fetchedDashboard,
required TResult orElse(),
}) {
if (fetchedDashboard != null) {
return fetchedDashboard(this);
}
return orElse();
}
}
abstract class _FetchedDashboard implements HomeEvent {
const factory _FetchedDashboard() = _$FetchedDashboardImpl;
}
/// @nodoc
mixin _$HomeState {
DashboardAnalytic get dashboard => throw _privateConstructorUsedError;
Option<AnalyticFailure> get failureOptionDashboard =>
throw _privateConstructorUsedError;
bool get isFetching => throw _privateConstructorUsedError;
/// Create a copy of HomeState
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
$HomeStateCopyWith<HomeState> get copyWith =>
throw _privateConstructorUsedError;
}
/// @nodoc
abstract class $HomeStateCopyWith<$Res> {
factory $HomeStateCopyWith(HomeState value, $Res Function(HomeState) then) =
_$HomeStateCopyWithImpl<$Res, HomeState>;
@useResult
$Res call({
DashboardAnalytic dashboard,
Option<AnalyticFailure> failureOptionDashboard,
bool isFetching,
});
$DashboardAnalyticCopyWith<$Res> get dashboard;
}
/// @nodoc
class _$HomeStateCopyWithImpl<$Res, $Val extends HomeState>
implements $HomeStateCopyWith<$Res> {
_$HomeStateCopyWithImpl(this._value, this._then);
// ignore: unused_field
final $Val _value;
// ignore: unused_field
final $Res Function($Val) _then;
/// Create a copy of HomeState
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({
Object? dashboard = null,
Object? failureOptionDashboard = null,
Object? isFetching = null,
}) {
return _then(
_value.copyWith(
dashboard: null == dashboard
? _value.dashboard
: dashboard // ignore: cast_nullable_to_non_nullable
as DashboardAnalytic,
failureOptionDashboard: null == failureOptionDashboard
? _value.failureOptionDashboard
: failureOptionDashboard // ignore: cast_nullable_to_non_nullable
as Option<AnalyticFailure>,
isFetching: null == isFetching
? _value.isFetching
: isFetching // ignore: cast_nullable_to_non_nullable
as bool,
)
as $Val,
);
}
/// Create a copy of HomeState
/// with the given fields replaced by the non-null parameter values.
@override
@pragma('vm:prefer-inline')
$DashboardAnalyticCopyWith<$Res> get dashboard {
return $DashboardAnalyticCopyWith<$Res>(_value.dashboard, (value) {
return _then(_value.copyWith(dashboard: value) as $Val);
});
}
}
/// @nodoc
abstract class _$$HomeStateImplCopyWith<$Res>
implements $HomeStateCopyWith<$Res> {
factory _$$HomeStateImplCopyWith(
_$HomeStateImpl value,
$Res Function(_$HomeStateImpl) then,
) = __$$HomeStateImplCopyWithImpl<$Res>;
@override
@useResult
$Res call({
DashboardAnalytic dashboard,
Option<AnalyticFailure> failureOptionDashboard,
bool isFetching,
});
@override
$DashboardAnalyticCopyWith<$Res> get dashboard;
}
/// @nodoc
class __$$HomeStateImplCopyWithImpl<$Res>
extends _$HomeStateCopyWithImpl<$Res, _$HomeStateImpl>
implements _$$HomeStateImplCopyWith<$Res> {
__$$HomeStateImplCopyWithImpl(
_$HomeStateImpl _value,
$Res Function(_$HomeStateImpl) _then,
) : super(_value, _then);
/// Create a copy of HomeState
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({
Object? dashboard = null,
Object? failureOptionDashboard = null,
Object? isFetching = null,
}) {
return _then(
_$HomeStateImpl(
dashboard: null == dashboard
? _value.dashboard
: dashboard // ignore: cast_nullable_to_non_nullable
as DashboardAnalytic,
failureOptionDashboard: null == failureOptionDashboard
? _value.failureOptionDashboard
: failureOptionDashboard // ignore: cast_nullable_to_non_nullable
as Option<AnalyticFailure>,
isFetching: null == isFetching
? _value.isFetching
: isFetching // ignore: cast_nullable_to_non_nullable
as bool,
),
);
}
}
/// @nodoc
class _$HomeStateImpl implements _HomeState {
const _$HomeStateImpl({
required this.dashboard,
required this.failureOptionDashboard,
this.isFetching = false,
});
@override
final DashboardAnalytic dashboard;
@override
final Option<AnalyticFailure> failureOptionDashboard;
@override
@JsonKey()
final bool isFetching;
@override
String toString() {
return 'HomeState(dashboard: $dashboard, failureOptionDashboard: $failureOptionDashboard, isFetching: $isFetching)';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType &&
other is _$HomeStateImpl &&
(identical(other.dashboard, dashboard) ||
other.dashboard == dashboard) &&
(identical(other.failureOptionDashboard, failureOptionDashboard) ||
other.failureOptionDashboard == failureOptionDashboard) &&
(identical(other.isFetching, isFetching) ||
other.isFetching == isFetching));
}
@override
int get hashCode =>
Object.hash(runtimeType, dashboard, failureOptionDashboard, isFetching);
/// Create a copy of HomeState
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@override
@pragma('vm:prefer-inline')
_$$HomeStateImplCopyWith<_$HomeStateImpl> get copyWith =>
__$$HomeStateImplCopyWithImpl<_$HomeStateImpl>(this, _$identity);
}
abstract class _HomeState implements HomeState {
const factory _HomeState({
required final DashboardAnalytic dashboard,
required final Option<AnalyticFailure> failureOptionDashboard,
final bool isFetching,
}) = _$HomeStateImpl;
@override
DashboardAnalytic get dashboard;
@override
Option<AnalyticFailure> get failureOptionDashboard;
@override
bool get isFetching;
/// Create a copy of HomeState
/// with the given fields replaced by the non-null parameter values.
@override
@JsonKey(includeFromJson: false, includeToJson: false)
_$$HomeStateImplCopyWith<_$HomeStateImpl> get copyWith =>
throw _privateConstructorUsedError;
}

View File

@ -0,0 +1,6 @@
part of 'home_bloc.dart';
@freezed
class HomeEvent with _$HomeEvent {
const factory HomeEvent.fetchedDashboard() = _FetchedDashboard;
}

View File

@ -0,0 +1,15 @@
part of 'home_bloc.dart';
@freezed
class HomeState with _$HomeState {
const factory HomeState({
required DashboardAnalytic dashboard,
required Option<AnalyticFailure> failureOptionDashboard,
@Default(false) bool isFetching,
}) = _HomeState;
factory HomeState.initial() => HomeState(
dashboard: DashboardAnalytic.empty(),
failureOptionDashboard: none(),
);
}

View File

@ -21,6 +21,9 @@ class OrderLoaderBloc extends Bloc<OrderLoaderEvent, OrderLoaderState> {
Emitter<OrderLoaderState> emit, Emitter<OrderLoaderState> emit,
) { ) {
return event.map( return event.map(
rangeDateChanged: (e) async {
emit(state.copyWith(dateFrom: e.dateFrom, dateTo: e.dateTo));
},
statusChanged: (e) async { statusChanged: (e) async {
emit(state.copyWith(status: e.status)); emit(state.copyWith(status: e.status));
}, },
@ -63,9 +66,11 @@ class OrderLoaderBloc extends Bloc<OrderLoaderEvent, OrderLoaderState> {
} }
final failureOrOrder = await _repository.get( final failureOrOrder = await _repository.get(
status: state.status, status: state.status == 'all' ? null : state.status,
page: state.page, page: state.page,
search: state.search, search: state.search,
dateFrom: state.dateFrom,
dateTo: state.dateTo,
); );
state = failureOrOrder.fold( state = failureOrOrder.fold(

View File

@ -19,18 +19,22 @@ final _privateConstructorUsedError = UnsupportedError(
mixin _$OrderLoaderEvent { mixin _$OrderLoaderEvent {
@optionalTypeArgs @optionalTypeArgs
TResult when<TResult extends Object?>({ TResult when<TResult extends Object?>({
required TResult Function(DateTime dateFrom, DateTime dateTo)
rangeDateChanged,
required TResult Function(String status) statusChanged, required TResult Function(String status) statusChanged,
required TResult Function(String search) searchChanged, required TResult Function(String search) searchChanged,
required TResult Function(bool isRefresh) fetched, required TResult Function(bool isRefresh) fetched,
}) => throw _privateConstructorUsedError; }) => throw _privateConstructorUsedError;
@optionalTypeArgs @optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>({ TResult? whenOrNull<TResult extends Object?>({
TResult? Function(DateTime dateFrom, DateTime dateTo)? rangeDateChanged,
TResult? Function(String status)? statusChanged, TResult? Function(String status)? statusChanged,
TResult? Function(String search)? searchChanged, TResult? Function(String search)? searchChanged,
TResult? Function(bool isRefresh)? fetched, TResult? Function(bool isRefresh)? fetched,
}) => throw _privateConstructorUsedError; }) => throw _privateConstructorUsedError;
@optionalTypeArgs @optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({ TResult maybeWhen<TResult extends Object?>({
TResult Function(DateTime dateFrom, DateTime dateTo)? rangeDateChanged,
TResult Function(String status)? statusChanged, TResult Function(String status)? statusChanged,
TResult Function(String search)? searchChanged, TResult Function(String search)? searchChanged,
TResult Function(bool isRefresh)? fetched, TResult Function(bool isRefresh)? fetched,
@ -38,18 +42,21 @@ mixin _$OrderLoaderEvent {
}) => throw _privateConstructorUsedError; }) => throw _privateConstructorUsedError;
@optionalTypeArgs @optionalTypeArgs
TResult map<TResult extends Object?>({ TResult map<TResult extends Object?>({
required TResult Function(_RangeDateChanged value) rangeDateChanged,
required TResult Function(_StatusChanged value) statusChanged, required TResult Function(_StatusChanged value) statusChanged,
required TResult Function(_SearchChanged value) searchChanged, required TResult Function(_SearchChanged value) searchChanged,
required TResult Function(_Fetched value) fetched, required TResult Function(_Fetched value) fetched,
}) => throw _privateConstructorUsedError; }) => throw _privateConstructorUsedError;
@optionalTypeArgs @optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>({ TResult? mapOrNull<TResult extends Object?>({
TResult? Function(_RangeDateChanged value)? rangeDateChanged,
TResult? Function(_StatusChanged value)? statusChanged, TResult? Function(_StatusChanged value)? statusChanged,
TResult? Function(_SearchChanged value)? searchChanged, TResult? Function(_SearchChanged value)? searchChanged,
TResult? Function(_Fetched value)? fetched, TResult? Function(_Fetched value)? fetched,
}) => throw _privateConstructorUsedError; }) => throw _privateConstructorUsedError;
@optionalTypeArgs @optionalTypeArgs
TResult maybeMap<TResult extends Object?>({ TResult maybeMap<TResult extends Object?>({
TResult Function(_RangeDateChanged value)? rangeDateChanged,
TResult Function(_StatusChanged value)? statusChanged, TResult Function(_StatusChanged value)? statusChanged,
TResult Function(_SearchChanged value)? searchChanged, TResult Function(_SearchChanged value)? searchChanged,
TResult Function(_Fetched value)? fetched, TResult Function(_Fetched value)? fetched,
@ -79,6 +86,176 @@ class _$OrderLoaderEventCopyWithImpl<$Res, $Val extends OrderLoaderEvent>
/// with the given fields replaced by the non-null parameter values. /// with the given fields replaced by the non-null parameter values.
} }
/// @nodoc
abstract class _$$RangeDateChangedImplCopyWith<$Res> {
factory _$$RangeDateChangedImplCopyWith(
_$RangeDateChangedImpl value,
$Res Function(_$RangeDateChangedImpl) then,
) = __$$RangeDateChangedImplCopyWithImpl<$Res>;
@useResult
$Res call({DateTime dateFrom, DateTime dateTo});
}
/// @nodoc
class __$$RangeDateChangedImplCopyWithImpl<$Res>
extends _$OrderLoaderEventCopyWithImpl<$Res, _$RangeDateChangedImpl>
implements _$$RangeDateChangedImplCopyWith<$Res> {
__$$RangeDateChangedImplCopyWithImpl(
_$RangeDateChangedImpl _value,
$Res Function(_$RangeDateChangedImpl) _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? dateFrom = null, Object? dateTo = null}) {
return _then(
_$RangeDateChangedImpl(
null == dateFrom
? _value.dateFrom
: dateFrom // ignore: cast_nullable_to_non_nullable
as DateTime,
null == dateTo
? _value.dateTo
: dateTo // ignore: cast_nullable_to_non_nullable
as DateTime,
),
);
}
}
/// @nodoc
class _$RangeDateChangedImpl implements _RangeDateChanged {
const _$RangeDateChangedImpl(this.dateFrom, this.dateTo);
@override
final DateTime dateFrom;
@override
final DateTime dateTo;
@override
String toString() {
return 'OrderLoaderEvent.rangeDateChanged(dateFrom: $dateFrom, dateTo: $dateTo)';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType &&
other is _$RangeDateChangedImpl &&
(identical(other.dateFrom, dateFrom) ||
other.dateFrom == dateFrom) &&
(identical(other.dateTo, dateTo) || other.dateTo == dateTo));
}
@override
int get hashCode => Object.hash(runtimeType, dateFrom, dateTo);
/// 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')
_$$RangeDateChangedImplCopyWith<_$RangeDateChangedImpl> get copyWith =>
__$$RangeDateChangedImplCopyWithImpl<_$RangeDateChangedImpl>(
this,
_$identity,
);
@override
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function(DateTime dateFrom, DateTime dateTo)
rangeDateChanged,
required TResult Function(String status) statusChanged,
required TResult Function(String search) searchChanged,
required TResult Function(bool isRefresh) fetched,
}) {
return rangeDateChanged(dateFrom, dateTo);
}
@override
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>({
TResult? Function(DateTime dateFrom, DateTime dateTo)? rangeDateChanged,
TResult? Function(String status)? statusChanged,
TResult? Function(String search)? searchChanged,
TResult? Function(bool isRefresh)? fetched,
}) {
return rangeDateChanged?.call(dateFrom, dateTo);
}
@override
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({
TResult Function(DateTime dateFrom, DateTime dateTo)? rangeDateChanged,
TResult Function(String status)? statusChanged,
TResult Function(String search)? searchChanged,
TResult Function(bool isRefresh)? fetched,
required TResult orElse(),
}) {
if (rangeDateChanged != null) {
return rangeDateChanged(dateFrom, dateTo);
}
return orElse();
}
@override
@optionalTypeArgs
TResult map<TResult extends Object?>({
required TResult Function(_RangeDateChanged value) rangeDateChanged,
required TResult Function(_StatusChanged value) statusChanged,
required TResult Function(_SearchChanged value) searchChanged,
required TResult Function(_Fetched value) fetched,
}) {
return rangeDateChanged(this);
}
@override
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>({
TResult? Function(_RangeDateChanged value)? rangeDateChanged,
TResult? Function(_StatusChanged value)? statusChanged,
TResult? Function(_SearchChanged value)? searchChanged,
TResult? Function(_Fetched value)? fetched,
}) {
return rangeDateChanged?.call(this);
}
@override
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>({
TResult Function(_RangeDateChanged value)? rangeDateChanged,
TResult Function(_StatusChanged value)? statusChanged,
TResult Function(_SearchChanged value)? searchChanged,
TResult Function(_Fetched value)? fetched,
required TResult orElse(),
}) {
if (rangeDateChanged != null) {
return rangeDateChanged(this);
}
return orElse();
}
}
abstract class _RangeDateChanged implements OrderLoaderEvent {
const factory _RangeDateChanged(
final DateTime dateFrom,
final DateTime dateTo,
) = _$RangeDateChangedImpl;
DateTime get dateFrom;
DateTime get dateTo;
/// Create a copy of OrderLoaderEvent
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
_$$RangeDateChangedImplCopyWith<_$RangeDateChangedImpl> get copyWith =>
throw _privateConstructorUsedError;
}
/// @nodoc /// @nodoc
abstract class _$$StatusChangedImplCopyWith<$Res> { abstract class _$$StatusChangedImplCopyWith<$Res> {
factory _$$StatusChangedImplCopyWith( factory _$$StatusChangedImplCopyWith(
@ -149,6 +326,8 @@ class _$StatusChangedImpl implements _StatusChanged {
@override @override
@optionalTypeArgs @optionalTypeArgs
TResult when<TResult extends Object?>({ TResult when<TResult extends Object?>({
required TResult Function(DateTime dateFrom, DateTime dateTo)
rangeDateChanged,
required TResult Function(String status) statusChanged, required TResult Function(String status) statusChanged,
required TResult Function(String search) searchChanged, required TResult Function(String search) searchChanged,
required TResult Function(bool isRefresh) fetched, required TResult Function(bool isRefresh) fetched,
@ -159,6 +338,7 @@ class _$StatusChangedImpl implements _StatusChanged {
@override @override
@optionalTypeArgs @optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>({ TResult? whenOrNull<TResult extends Object?>({
TResult? Function(DateTime dateFrom, DateTime dateTo)? rangeDateChanged,
TResult? Function(String status)? statusChanged, TResult? Function(String status)? statusChanged,
TResult? Function(String search)? searchChanged, TResult? Function(String search)? searchChanged,
TResult? Function(bool isRefresh)? fetched, TResult? Function(bool isRefresh)? fetched,
@ -169,6 +349,7 @@ class _$StatusChangedImpl implements _StatusChanged {
@override @override
@optionalTypeArgs @optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({ TResult maybeWhen<TResult extends Object?>({
TResult Function(DateTime dateFrom, DateTime dateTo)? rangeDateChanged,
TResult Function(String status)? statusChanged, TResult Function(String status)? statusChanged,
TResult Function(String search)? searchChanged, TResult Function(String search)? searchChanged,
TResult Function(bool isRefresh)? fetched, TResult Function(bool isRefresh)? fetched,
@ -183,6 +364,7 @@ class _$StatusChangedImpl implements _StatusChanged {
@override @override
@optionalTypeArgs @optionalTypeArgs
TResult map<TResult extends Object?>({ TResult map<TResult extends Object?>({
required TResult Function(_RangeDateChanged value) rangeDateChanged,
required TResult Function(_StatusChanged value) statusChanged, required TResult Function(_StatusChanged value) statusChanged,
required TResult Function(_SearchChanged value) searchChanged, required TResult Function(_SearchChanged value) searchChanged,
required TResult Function(_Fetched value) fetched, required TResult Function(_Fetched value) fetched,
@ -193,6 +375,7 @@ class _$StatusChangedImpl implements _StatusChanged {
@override @override
@optionalTypeArgs @optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>({ TResult? mapOrNull<TResult extends Object?>({
TResult? Function(_RangeDateChanged value)? rangeDateChanged,
TResult? Function(_StatusChanged value)? statusChanged, TResult? Function(_StatusChanged value)? statusChanged,
TResult? Function(_SearchChanged value)? searchChanged, TResult? Function(_SearchChanged value)? searchChanged,
TResult? Function(_Fetched value)? fetched, TResult? Function(_Fetched value)? fetched,
@ -203,6 +386,7 @@ class _$StatusChangedImpl implements _StatusChanged {
@override @override
@optionalTypeArgs @optionalTypeArgs
TResult maybeMap<TResult extends Object?>({ TResult maybeMap<TResult extends Object?>({
TResult Function(_RangeDateChanged value)? rangeDateChanged,
TResult Function(_StatusChanged value)? statusChanged, TResult Function(_StatusChanged value)? statusChanged,
TResult Function(_SearchChanged value)? searchChanged, TResult Function(_SearchChanged value)? searchChanged,
TResult Function(_Fetched value)? fetched, TResult Function(_Fetched value)? fetched,
@ -297,6 +481,8 @@ class _$SearchChangedImpl implements _SearchChanged {
@override @override
@optionalTypeArgs @optionalTypeArgs
TResult when<TResult extends Object?>({ TResult when<TResult extends Object?>({
required TResult Function(DateTime dateFrom, DateTime dateTo)
rangeDateChanged,
required TResult Function(String status) statusChanged, required TResult Function(String status) statusChanged,
required TResult Function(String search) searchChanged, required TResult Function(String search) searchChanged,
required TResult Function(bool isRefresh) fetched, required TResult Function(bool isRefresh) fetched,
@ -307,6 +493,7 @@ class _$SearchChangedImpl implements _SearchChanged {
@override @override
@optionalTypeArgs @optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>({ TResult? whenOrNull<TResult extends Object?>({
TResult? Function(DateTime dateFrom, DateTime dateTo)? rangeDateChanged,
TResult? Function(String status)? statusChanged, TResult? Function(String status)? statusChanged,
TResult? Function(String search)? searchChanged, TResult? Function(String search)? searchChanged,
TResult? Function(bool isRefresh)? fetched, TResult? Function(bool isRefresh)? fetched,
@ -317,6 +504,7 @@ class _$SearchChangedImpl implements _SearchChanged {
@override @override
@optionalTypeArgs @optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({ TResult maybeWhen<TResult extends Object?>({
TResult Function(DateTime dateFrom, DateTime dateTo)? rangeDateChanged,
TResult Function(String status)? statusChanged, TResult Function(String status)? statusChanged,
TResult Function(String search)? searchChanged, TResult Function(String search)? searchChanged,
TResult Function(bool isRefresh)? fetched, TResult Function(bool isRefresh)? fetched,
@ -331,6 +519,7 @@ class _$SearchChangedImpl implements _SearchChanged {
@override @override
@optionalTypeArgs @optionalTypeArgs
TResult map<TResult extends Object?>({ TResult map<TResult extends Object?>({
required TResult Function(_RangeDateChanged value) rangeDateChanged,
required TResult Function(_StatusChanged value) statusChanged, required TResult Function(_StatusChanged value) statusChanged,
required TResult Function(_SearchChanged value) searchChanged, required TResult Function(_SearchChanged value) searchChanged,
required TResult Function(_Fetched value) fetched, required TResult Function(_Fetched value) fetched,
@ -341,6 +530,7 @@ class _$SearchChangedImpl implements _SearchChanged {
@override @override
@optionalTypeArgs @optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>({ TResult? mapOrNull<TResult extends Object?>({
TResult? Function(_RangeDateChanged value)? rangeDateChanged,
TResult? Function(_StatusChanged value)? statusChanged, TResult? Function(_StatusChanged value)? statusChanged,
TResult? Function(_SearchChanged value)? searchChanged, TResult? Function(_SearchChanged value)? searchChanged,
TResult? Function(_Fetched value)? fetched, TResult? Function(_Fetched value)? fetched,
@ -351,6 +541,7 @@ class _$SearchChangedImpl implements _SearchChanged {
@override @override
@optionalTypeArgs @optionalTypeArgs
TResult maybeMap<TResult extends Object?>({ TResult maybeMap<TResult extends Object?>({
TResult Function(_RangeDateChanged value)? rangeDateChanged,
TResult Function(_StatusChanged value)? statusChanged, TResult Function(_StatusChanged value)? statusChanged,
TResult Function(_SearchChanged value)? searchChanged, TResult Function(_SearchChanged value)? searchChanged,
TResult Function(_Fetched value)? fetched, TResult Function(_Fetched value)? fetched,
@ -447,6 +638,8 @@ class _$FetchedImpl implements _Fetched {
@override @override
@optionalTypeArgs @optionalTypeArgs
TResult when<TResult extends Object?>({ TResult when<TResult extends Object?>({
required TResult Function(DateTime dateFrom, DateTime dateTo)
rangeDateChanged,
required TResult Function(String status) statusChanged, required TResult Function(String status) statusChanged,
required TResult Function(String search) searchChanged, required TResult Function(String search) searchChanged,
required TResult Function(bool isRefresh) fetched, required TResult Function(bool isRefresh) fetched,
@ -457,6 +650,7 @@ class _$FetchedImpl implements _Fetched {
@override @override
@optionalTypeArgs @optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>({ TResult? whenOrNull<TResult extends Object?>({
TResult? Function(DateTime dateFrom, DateTime dateTo)? rangeDateChanged,
TResult? Function(String status)? statusChanged, TResult? Function(String status)? statusChanged,
TResult? Function(String search)? searchChanged, TResult? Function(String search)? searchChanged,
TResult? Function(bool isRefresh)? fetched, TResult? Function(bool isRefresh)? fetched,
@ -467,6 +661,7 @@ class _$FetchedImpl implements _Fetched {
@override @override
@optionalTypeArgs @optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({ TResult maybeWhen<TResult extends Object?>({
TResult Function(DateTime dateFrom, DateTime dateTo)? rangeDateChanged,
TResult Function(String status)? statusChanged, TResult Function(String status)? statusChanged,
TResult Function(String search)? searchChanged, TResult Function(String search)? searchChanged,
TResult Function(bool isRefresh)? fetched, TResult Function(bool isRefresh)? fetched,
@ -481,6 +676,7 @@ class _$FetchedImpl implements _Fetched {
@override @override
@optionalTypeArgs @optionalTypeArgs
TResult map<TResult extends Object?>({ TResult map<TResult extends Object?>({
required TResult Function(_RangeDateChanged value) rangeDateChanged,
required TResult Function(_StatusChanged value) statusChanged, required TResult Function(_StatusChanged value) statusChanged,
required TResult Function(_SearchChanged value) searchChanged, required TResult Function(_SearchChanged value) searchChanged,
required TResult Function(_Fetched value) fetched, required TResult Function(_Fetched value) fetched,
@ -491,6 +687,7 @@ class _$FetchedImpl implements _Fetched {
@override @override
@optionalTypeArgs @optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>({ TResult? mapOrNull<TResult extends Object?>({
TResult? Function(_RangeDateChanged value)? rangeDateChanged,
TResult? Function(_StatusChanged value)? statusChanged, TResult? Function(_StatusChanged value)? statusChanged,
TResult? Function(_SearchChanged value)? searchChanged, TResult? Function(_SearchChanged value)? searchChanged,
TResult? Function(_Fetched value)? fetched, TResult? Function(_Fetched value)? fetched,
@ -501,6 +698,7 @@ class _$FetchedImpl implements _Fetched {
@override @override
@optionalTypeArgs @optionalTypeArgs
TResult maybeMap<TResult extends Object?>({ TResult maybeMap<TResult extends Object?>({
TResult Function(_RangeDateChanged value)? rangeDateChanged,
TResult Function(_StatusChanged value)? statusChanged, TResult Function(_StatusChanged value)? statusChanged,
TResult Function(_SearchChanged value)? searchChanged, TResult Function(_SearchChanged value)? searchChanged,
TResult Function(_Fetched value)? fetched, TResult Function(_Fetched value)? fetched,
@ -530,11 +728,13 @@ mixin _$OrderLoaderState {
List<Order> get orders => throw _privateConstructorUsedError; List<Order> get orders => throw _privateConstructorUsedError;
Option<OrderFailure> get failureOptionOrder => Option<OrderFailure> get failureOptionOrder =>
throw _privateConstructorUsedError; throw _privateConstructorUsedError;
String? get status => throw _privateConstructorUsedError; String get status => throw _privateConstructorUsedError;
String? get search => throw _privateConstructorUsedError; String? get search => throw _privateConstructorUsedError;
bool get isFetching => throw _privateConstructorUsedError; bool get isFetching => throw _privateConstructorUsedError;
bool get hasReachedMax => throw _privateConstructorUsedError; bool get hasReachedMax => throw _privateConstructorUsedError;
int get page => throw _privateConstructorUsedError; int get page => throw _privateConstructorUsedError;
DateTime get dateFrom => throw _privateConstructorUsedError;
DateTime get dateTo => throw _privateConstructorUsedError;
/// Create a copy of OrderLoaderState /// Create a copy of OrderLoaderState
/// with the given fields replaced by the non-null parameter values. /// with the given fields replaced by the non-null parameter values.
@ -553,11 +753,13 @@ abstract class $OrderLoaderStateCopyWith<$Res> {
$Res call({ $Res call({
List<Order> orders, List<Order> orders,
Option<OrderFailure> failureOptionOrder, Option<OrderFailure> failureOptionOrder,
String? status, String status,
String? search, String? search,
bool isFetching, bool isFetching,
bool hasReachedMax, bool hasReachedMax,
int page, int page,
DateTime dateFrom,
DateTime dateTo,
}); });
} }
@ -578,11 +780,13 @@ class _$OrderLoaderStateCopyWithImpl<$Res, $Val extends OrderLoaderState>
$Res call({ $Res call({
Object? orders = null, Object? orders = null,
Object? failureOptionOrder = null, Object? failureOptionOrder = null,
Object? status = freezed, Object? status = null,
Object? search = freezed, Object? search = freezed,
Object? isFetching = null, Object? isFetching = null,
Object? hasReachedMax = null, Object? hasReachedMax = null,
Object? page = null, Object? page = null,
Object? dateFrom = null,
Object? dateTo = null,
}) { }) {
return _then( return _then(
_value.copyWith( _value.copyWith(
@ -594,10 +798,10 @@ class _$OrderLoaderStateCopyWithImpl<$Res, $Val extends OrderLoaderState>
? _value.failureOptionOrder ? _value.failureOptionOrder
: failureOptionOrder // ignore: cast_nullable_to_non_nullable : failureOptionOrder // ignore: cast_nullable_to_non_nullable
as Option<OrderFailure>, as Option<OrderFailure>,
status: freezed == status status: null == status
? _value.status ? _value.status
: status // ignore: cast_nullable_to_non_nullable : status // ignore: cast_nullable_to_non_nullable
as String?, as String,
search: freezed == search search: freezed == search
? _value.search ? _value.search
: search // ignore: cast_nullable_to_non_nullable : search // ignore: cast_nullable_to_non_nullable
@ -614,6 +818,14 @@ class _$OrderLoaderStateCopyWithImpl<$Res, $Val extends OrderLoaderState>
? _value.page ? _value.page
: page // ignore: cast_nullable_to_non_nullable : page // ignore: cast_nullable_to_non_nullable
as int, as int,
dateFrom: null == dateFrom
? _value.dateFrom
: dateFrom // ignore: cast_nullable_to_non_nullable
as DateTime,
dateTo: null == dateTo
? _value.dateTo
: dateTo // ignore: cast_nullable_to_non_nullable
as DateTime,
) )
as $Val, as $Val,
); );
@ -632,11 +844,13 @@ abstract class _$$OrderLoaderStateImplCopyWith<$Res>
$Res call({ $Res call({
List<Order> orders, List<Order> orders,
Option<OrderFailure> failureOptionOrder, Option<OrderFailure> failureOptionOrder,
String? status, String status,
String? search, String? search,
bool isFetching, bool isFetching,
bool hasReachedMax, bool hasReachedMax,
int page, int page,
DateTime dateFrom,
DateTime dateTo,
}); });
} }
@ -656,11 +870,13 @@ class __$$OrderLoaderStateImplCopyWithImpl<$Res>
$Res call({ $Res call({
Object? orders = null, Object? orders = null,
Object? failureOptionOrder = null, Object? failureOptionOrder = null,
Object? status = freezed, Object? status = null,
Object? search = freezed, Object? search = freezed,
Object? isFetching = null, Object? isFetching = null,
Object? hasReachedMax = null, Object? hasReachedMax = null,
Object? page = null, Object? page = null,
Object? dateFrom = null,
Object? dateTo = null,
}) { }) {
return _then( return _then(
_$OrderLoaderStateImpl( _$OrderLoaderStateImpl(
@ -672,10 +888,10 @@ class __$$OrderLoaderStateImplCopyWithImpl<$Res>
? _value.failureOptionOrder ? _value.failureOptionOrder
: failureOptionOrder // ignore: cast_nullable_to_non_nullable : failureOptionOrder // ignore: cast_nullable_to_non_nullable
as Option<OrderFailure>, as Option<OrderFailure>,
status: freezed == status status: null == status
? _value.status ? _value.status
: status // ignore: cast_nullable_to_non_nullable : status // ignore: cast_nullable_to_non_nullable
as String?, as String,
search: freezed == search search: freezed == search
? _value.search ? _value.search
: search // ignore: cast_nullable_to_non_nullable : search // ignore: cast_nullable_to_non_nullable
@ -692,6 +908,14 @@ class __$$OrderLoaderStateImplCopyWithImpl<$Res>
? _value.page ? _value.page
: page // ignore: cast_nullable_to_non_nullable : page // ignore: cast_nullable_to_non_nullable
as int, as int,
dateFrom: null == dateFrom
? _value.dateFrom
: dateFrom // ignore: cast_nullable_to_non_nullable
as DateTime,
dateTo: null == dateTo
? _value.dateTo
: dateTo // ignore: cast_nullable_to_non_nullable
as DateTime,
), ),
); );
} }
@ -703,11 +927,13 @@ class _$OrderLoaderStateImpl implements _OrderLoaderState {
const _$OrderLoaderStateImpl({ const _$OrderLoaderStateImpl({
required final List<Order> orders, required final List<Order> orders,
required this.failureOptionOrder, required this.failureOptionOrder,
this.status, required this.status,
this.search, this.search,
this.isFetching = false, this.isFetching = false,
this.hasReachedMax = false, this.hasReachedMax = false,
this.page = 1, this.page = 1,
required this.dateFrom,
required this.dateTo,
}) : _orders = orders; }) : _orders = orders;
final List<Order> _orders; final List<Order> _orders;
@ -721,7 +947,7 @@ class _$OrderLoaderStateImpl implements _OrderLoaderState {
@override @override
final Option<OrderFailure> failureOptionOrder; final Option<OrderFailure> failureOptionOrder;
@override @override
final String? status; final String status;
@override @override
final String? search; final String? search;
@override @override
@ -733,10 +959,14 @@ class _$OrderLoaderStateImpl implements _OrderLoaderState {
@override @override
@JsonKey() @JsonKey()
final int page; final int page;
@override
final DateTime dateFrom;
@override
final DateTime dateTo;
@override @override
String toString() { String toString() {
return 'OrderLoaderState(orders: $orders, failureOptionOrder: $failureOptionOrder, status: $status, search: $search, isFetching: $isFetching, hasReachedMax: $hasReachedMax, page: $page)'; return 'OrderLoaderState(orders: $orders, failureOptionOrder: $failureOptionOrder, status: $status, search: $search, isFetching: $isFetching, hasReachedMax: $hasReachedMax, page: $page, dateFrom: $dateFrom, dateTo: $dateTo)';
} }
@override @override
@ -753,7 +983,10 @@ class _$OrderLoaderStateImpl implements _OrderLoaderState {
other.isFetching == isFetching) && other.isFetching == isFetching) &&
(identical(other.hasReachedMax, hasReachedMax) || (identical(other.hasReachedMax, hasReachedMax) ||
other.hasReachedMax == hasReachedMax) && other.hasReachedMax == hasReachedMax) &&
(identical(other.page, page) || other.page == page)); (identical(other.page, page) || other.page == page) &&
(identical(other.dateFrom, dateFrom) ||
other.dateFrom == dateFrom) &&
(identical(other.dateTo, dateTo) || other.dateTo == dateTo));
} }
@override @override
@ -766,6 +999,8 @@ class _$OrderLoaderStateImpl implements _OrderLoaderState {
isFetching, isFetching,
hasReachedMax, hasReachedMax,
page, page,
dateFrom,
dateTo,
); );
/// Create a copy of OrderLoaderState /// Create a copy of OrderLoaderState
@ -784,11 +1019,13 @@ abstract class _OrderLoaderState implements OrderLoaderState {
const factory _OrderLoaderState({ const factory _OrderLoaderState({
required final List<Order> orders, required final List<Order> orders,
required final Option<OrderFailure> failureOptionOrder, required final Option<OrderFailure> failureOptionOrder,
final String? status, required final String status,
final String? search, final String? search,
final bool isFetching, final bool isFetching,
final bool hasReachedMax, final bool hasReachedMax,
final int page, final int page,
required final DateTime dateFrom,
required final DateTime dateTo,
}) = _$OrderLoaderStateImpl; }) = _$OrderLoaderStateImpl;
@override @override
@ -796,7 +1033,7 @@ abstract class _OrderLoaderState implements OrderLoaderState {
@override @override
Option<OrderFailure> get failureOptionOrder; Option<OrderFailure> get failureOptionOrder;
@override @override
String? get status; String get status;
@override @override
String? get search; String? get search;
@override @override
@ -805,6 +1042,10 @@ abstract class _OrderLoaderState implements OrderLoaderState {
bool get hasReachedMax; bool get hasReachedMax;
@override @override
int get page; int get page;
@override
DateTime get dateFrom;
@override
DateTime get dateTo;
/// Create a copy of OrderLoaderState /// Create a copy of OrderLoaderState
/// with the given fields replaced by the non-null parameter values. /// with the given fields replaced by the non-null parameter values.

View File

@ -2,6 +2,10 @@ part of 'order_loader_bloc.dart';
@freezed @freezed
class OrderLoaderEvent with _$OrderLoaderEvent { class OrderLoaderEvent with _$OrderLoaderEvent {
const factory OrderLoaderEvent.rangeDateChanged(
DateTime dateFrom,
DateTime dateTo,
) = _RangeDateChanged;
const factory OrderLoaderEvent.statusChanged(String status) = _StatusChanged; const factory OrderLoaderEvent.statusChanged(String status) = _StatusChanged;
const factory OrderLoaderEvent.searchChanged(String search) = _SearchChanged; const factory OrderLoaderEvent.searchChanged(String search) = _SearchChanged;
const factory OrderLoaderEvent.fetched({@Default(false) bool isRefresh}) = const factory OrderLoaderEvent.fetched({@Default(false) bool isRefresh}) =

View File

@ -5,13 +5,20 @@ class OrderLoaderState with _$OrderLoaderState {
const factory OrderLoaderState({ const factory OrderLoaderState({
required List<Order> orders, required List<Order> orders,
required Option<OrderFailure> failureOptionOrder, required Option<OrderFailure> failureOptionOrder,
String? status, required String status,
String? search, String? search,
@Default(false) bool isFetching, @Default(false) bool isFetching,
@Default(false) bool hasReachedMax, @Default(false) bool hasReachedMax,
@Default(1) int page, @Default(1) int page,
required DateTime dateFrom,
required DateTime dateTo,
}) = _OrderLoaderState; }) = _OrderLoaderState;
factory OrderLoaderState.initial() => factory OrderLoaderState.initial() => OrderLoaderState(
OrderLoaderState(orders: [], failureOptionOrder: none()); orders: [],
failureOptionOrder: none(),
dateFrom: DateTime.now().subtract(const Duration(days: 30)),
dateTo: DateTime.now(),
status: 'all',
);
} }

View File

@ -0,0 +1,40 @@
import 'package:dartz/dartz.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:injectable/injectable.dart';
import '../../../domain/outlet/outlet.dart';
part 'current_outlet_loader_event.dart';
part 'current_outlet_loader_state.dart';
part 'current_outlet_loader_bloc.freezed.dart';
@injectable
class CurrentOutletLoaderBloc
extends Bloc<CurrentOutletLoaderEvent, CurrentOutletLoaderState> {
final IOutletRepository _repository;
CurrentOutletLoaderBloc(this._repository)
: super(CurrentOutletLoaderState.initial()) {
on<CurrentOutletLoaderEvent>(_onCurrentOutletLoaderEvent);
}
Future<void> _onCurrentOutletLoaderEvent(
CurrentOutletLoaderEvent event,
Emitter<CurrentOutletLoaderState> emit,
) {
return event.map(
fetched: (e) async {
emit(state.copyWith(isFetching: true, failureOptionOutlet: none()));
final result = await _repository.currentOutlet();
var data = result.fold(
(f) => state.copyWith(failureOptionOutlet: optionOf(f)),
(currentOutlet) => state.copyWith(outlet: currentOutlet),
);
emit(data.copyWith(isFetching: false));
},
);
}
}

View File

@ -0,0 +1,382 @@
// 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 'current_outlet_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 _$CurrentOutletLoaderEvent {
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function() fetched,
}) => throw _privateConstructorUsedError;
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>({
TResult? Function()? fetched,
}) => throw _privateConstructorUsedError;
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({
TResult Function()? fetched,
required TResult orElse(),
}) => throw _privateConstructorUsedError;
@optionalTypeArgs
TResult map<TResult extends Object?>({
required TResult Function(_Fetched value) fetched,
}) => throw _privateConstructorUsedError;
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>({
TResult? Function(_Fetched value)? fetched,
}) => throw _privateConstructorUsedError;
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>({
TResult Function(_Fetched value)? fetched,
required TResult orElse(),
}) => throw _privateConstructorUsedError;
}
/// @nodoc
abstract class $CurrentOutletLoaderEventCopyWith<$Res> {
factory $CurrentOutletLoaderEventCopyWith(
CurrentOutletLoaderEvent value,
$Res Function(CurrentOutletLoaderEvent) then,
) = _$CurrentOutletLoaderEventCopyWithImpl<$Res, CurrentOutletLoaderEvent>;
}
/// @nodoc
class _$CurrentOutletLoaderEventCopyWithImpl<
$Res,
$Val extends CurrentOutletLoaderEvent
>
implements $CurrentOutletLoaderEventCopyWith<$Res> {
_$CurrentOutletLoaderEventCopyWithImpl(this._value, this._then);
// ignore: unused_field
final $Val _value;
// ignore: unused_field
final $Res Function($Val) _then;
/// Create a copy of CurrentOutletLoaderEvent
/// with the given fields replaced by the non-null parameter values.
}
/// @nodoc
abstract class _$$FetchedImplCopyWith<$Res> {
factory _$$FetchedImplCopyWith(
_$FetchedImpl value,
$Res Function(_$FetchedImpl) then,
) = __$$FetchedImplCopyWithImpl<$Res>;
}
/// @nodoc
class __$$FetchedImplCopyWithImpl<$Res>
extends _$CurrentOutletLoaderEventCopyWithImpl<$Res, _$FetchedImpl>
implements _$$FetchedImplCopyWith<$Res> {
__$$FetchedImplCopyWithImpl(
_$FetchedImpl _value,
$Res Function(_$FetchedImpl) _then,
) : super(_value, _then);
/// Create a copy of CurrentOutletLoaderEvent
/// with the given fields replaced by the non-null parameter values.
}
/// @nodoc
class _$FetchedImpl implements _Fetched {
const _$FetchedImpl();
@override
String toString() {
return 'CurrentOutletLoaderEvent.fetched()';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType && other is _$FetchedImpl);
}
@override
int get hashCode => runtimeType.hashCode;
@override
@optionalTypeArgs
TResult when<TResult extends Object?>({required TResult Function() fetched}) {
return fetched();
}
@override
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>({TResult? Function()? fetched}) {
return fetched?.call();
}
@override
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({
TResult Function()? fetched,
required TResult orElse(),
}) {
if (fetched != null) {
return fetched();
}
return orElse();
}
@override
@optionalTypeArgs
TResult map<TResult extends Object?>({
required TResult Function(_Fetched value) fetched,
}) {
return fetched(this);
}
@override
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>({
TResult? Function(_Fetched value)? fetched,
}) {
return fetched?.call(this);
}
@override
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>({
TResult Function(_Fetched value)? fetched,
required TResult orElse(),
}) {
if (fetched != null) {
return fetched(this);
}
return orElse();
}
}
abstract class _Fetched implements CurrentOutletLoaderEvent {
const factory _Fetched() = _$FetchedImpl;
}
/// @nodoc
mixin _$CurrentOutletLoaderState {
Outlet get outlet => throw _privateConstructorUsedError;
Option<OutletFailure> get failureOptionOutlet =>
throw _privateConstructorUsedError;
bool get isFetching => throw _privateConstructorUsedError;
/// Create a copy of CurrentOutletLoaderState
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
$CurrentOutletLoaderStateCopyWith<CurrentOutletLoaderState> get copyWith =>
throw _privateConstructorUsedError;
}
/// @nodoc
abstract class $CurrentOutletLoaderStateCopyWith<$Res> {
factory $CurrentOutletLoaderStateCopyWith(
CurrentOutletLoaderState value,
$Res Function(CurrentOutletLoaderState) then,
) = _$CurrentOutletLoaderStateCopyWithImpl<$Res, CurrentOutletLoaderState>;
@useResult
$Res call({
Outlet outlet,
Option<OutletFailure> failureOptionOutlet,
bool isFetching,
});
$OutletCopyWith<$Res> get outlet;
}
/// @nodoc
class _$CurrentOutletLoaderStateCopyWithImpl<
$Res,
$Val extends CurrentOutletLoaderState
>
implements $CurrentOutletLoaderStateCopyWith<$Res> {
_$CurrentOutletLoaderStateCopyWithImpl(this._value, this._then);
// ignore: unused_field
final $Val _value;
// ignore: unused_field
final $Res Function($Val) _then;
/// Create a copy of CurrentOutletLoaderState
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({
Object? outlet = null,
Object? failureOptionOutlet = null,
Object? isFetching = null,
}) {
return _then(
_value.copyWith(
outlet: null == outlet
? _value.outlet
: outlet // ignore: cast_nullable_to_non_nullable
as Outlet,
failureOptionOutlet: null == failureOptionOutlet
? _value.failureOptionOutlet
: failureOptionOutlet // ignore: cast_nullable_to_non_nullable
as Option<OutletFailure>,
isFetching: null == isFetching
? _value.isFetching
: isFetching // ignore: cast_nullable_to_non_nullable
as bool,
)
as $Val,
);
}
/// Create a copy of CurrentOutletLoaderState
/// with the given fields replaced by the non-null parameter values.
@override
@pragma('vm:prefer-inline')
$OutletCopyWith<$Res> get outlet {
return $OutletCopyWith<$Res>(_value.outlet, (value) {
return _then(_value.copyWith(outlet: value) as $Val);
});
}
}
/// @nodoc
abstract class _$$CurrentOutletLoaderStateImplCopyWith<$Res>
implements $CurrentOutletLoaderStateCopyWith<$Res> {
factory _$$CurrentOutletLoaderStateImplCopyWith(
_$CurrentOutletLoaderStateImpl value,
$Res Function(_$CurrentOutletLoaderStateImpl) then,
) = __$$CurrentOutletLoaderStateImplCopyWithImpl<$Res>;
@override
@useResult
$Res call({
Outlet outlet,
Option<OutletFailure> failureOptionOutlet,
bool isFetching,
});
@override
$OutletCopyWith<$Res> get outlet;
}
/// @nodoc
class __$$CurrentOutletLoaderStateImplCopyWithImpl<$Res>
extends
_$CurrentOutletLoaderStateCopyWithImpl<
$Res,
_$CurrentOutletLoaderStateImpl
>
implements _$$CurrentOutletLoaderStateImplCopyWith<$Res> {
__$$CurrentOutletLoaderStateImplCopyWithImpl(
_$CurrentOutletLoaderStateImpl _value,
$Res Function(_$CurrentOutletLoaderStateImpl) _then,
) : super(_value, _then);
/// Create a copy of CurrentOutletLoaderState
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({
Object? outlet = null,
Object? failureOptionOutlet = null,
Object? isFetching = null,
}) {
return _then(
_$CurrentOutletLoaderStateImpl(
outlet: null == outlet
? _value.outlet
: outlet // ignore: cast_nullable_to_non_nullable
as Outlet,
failureOptionOutlet: null == failureOptionOutlet
? _value.failureOptionOutlet
: failureOptionOutlet // ignore: cast_nullable_to_non_nullable
as Option<OutletFailure>,
isFetching: null == isFetching
? _value.isFetching
: isFetching // ignore: cast_nullable_to_non_nullable
as bool,
),
);
}
}
/// @nodoc
class _$CurrentOutletLoaderStateImpl implements _CurrentOutletLoaderState {
const _$CurrentOutletLoaderStateImpl({
required this.outlet,
required this.failureOptionOutlet,
this.isFetching = false,
});
@override
final Outlet outlet;
@override
final Option<OutletFailure> failureOptionOutlet;
@override
@JsonKey()
final bool isFetching;
@override
String toString() {
return 'CurrentOutletLoaderState(outlet: $outlet, failureOptionOutlet: $failureOptionOutlet, isFetching: $isFetching)';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType &&
other is _$CurrentOutletLoaderStateImpl &&
(identical(other.outlet, outlet) || other.outlet == outlet) &&
(identical(other.failureOptionOutlet, failureOptionOutlet) ||
other.failureOptionOutlet == failureOptionOutlet) &&
(identical(other.isFetching, isFetching) ||
other.isFetching == isFetching));
}
@override
int get hashCode =>
Object.hash(runtimeType, outlet, failureOptionOutlet, isFetching);
/// Create a copy of CurrentOutletLoaderState
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@override
@pragma('vm:prefer-inline')
_$$CurrentOutletLoaderStateImplCopyWith<_$CurrentOutletLoaderStateImpl>
get copyWith =>
__$$CurrentOutletLoaderStateImplCopyWithImpl<
_$CurrentOutletLoaderStateImpl
>(this, _$identity);
}
abstract class _CurrentOutletLoaderState implements CurrentOutletLoaderState {
const factory _CurrentOutletLoaderState({
required final Outlet outlet,
required final Option<OutletFailure> failureOptionOutlet,
final bool isFetching,
}) = _$CurrentOutletLoaderStateImpl;
@override
Outlet get outlet;
@override
Option<OutletFailure> get failureOptionOutlet;
@override
bool get isFetching;
/// Create a copy of CurrentOutletLoaderState
/// with the given fields replaced by the non-null parameter values.
@override
@JsonKey(includeFromJson: false, includeToJson: false)
_$$CurrentOutletLoaderStateImplCopyWith<_$CurrentOutletLoaderStateImpl>
get copyWith => throw _privateConstructorUsedError;
}

View File

@ -0,0 +1,6 @@
part of 'current_outlet_loader_bloc.dart';
@freezed
class CurrentOutletLoaderEvent with _$CurrentOutletLoaderEvent {
const factory CurrentOutletLoaderEvent.fetched() = _Fetched;
}

View File

@ -0,0 +1,15 @@
part of 'current_outlet_loader_bloc.dart';
@freezed
class CurrentOutletLoaderState with _$CurrentOutletLoaderState {
const factory CurrentOutletLoaderState({
required Outlet outlet,
required Option<OutletFailure> failureOptionOutlet,
@Default(false) bool isFetching,
}) = _CurrentOutletLoaderState;
factory CurrentOutletLoaderState.initial() => CurrentOutletLoaderState(
outlet: Outlet.empty(),
failureOptionOutlet: none(),
);
}

View File

@ -27,4 +27,7 @@ class ApiPath {
// Order // Order
static const String order = '/api/v1/orders'; static const String order = '/api/v1/orders';
// Outlet
static const String outlet = '/api/v1/outlets';
} }

View File

@ -6,5 +6,7 @@ abstract class IOrderRepository {
int limit = 10, int limit = 10,
String? status, String? status,
String? search, String? search,
required DateTime dateFrom,
required DateTime dateTo,
}); });
} }

View File

@ -0,0 +1,32 @@
part of '../outlet.dart';
@freezed
class Outlet with _$Outlet {
const factory Outlet({
required String id,
required String organizationId,
required String name,
required String address,
required String phoneNumber,
required String businessType,
required String currency,
required int taxRate,
required bool isActive,
required DateTime createdAt,
required DateTime updatedAt,
}) = _Outlet;
factory Outlet.empty() => Outlet(
id: '',
organizationId: '',
name: '',
address: '',
phoneNumber: '',
businessType: '',
currency: '',
taxRate: 0,
isActive: false,
createdAt: DateTime(1970),
updatedAt: DateTime(1970),
);
}

View File

@ -0,0 +1,10 @@
part of '../outlet.dart';
@freezed
sealed class OutletFailure with _$OutletFailure {
const factory OutletFailure.serverError(ApiFailure failure) = _ServerError;
const factory OutletFailure.unexpectedError() = _UnexpectedError;
const factory OutletFailure.empty() = _Empty;
const factory OutletFailure.dynamicErrorMessage(String erroMessage) =
_DynamicErrorMessage;
}

View File

@ -0,0 +1,10 @@
import 'package:dartz/dartz.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
import '../../common/api/api_failure.dart';
part 'outlet.freezed.dart';
part 'entities/outlet_entity.dart';
part 'failures/outlet_failure.dart';
part 'repositories/i_outlet_repository.dart';

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,5 @@
part of '../outlet.dart';
abstract class IOutletRepository {
Future<Either<OutletFailure, Outlet>> currentOutlet();
}

View File

@ -5,6 +5,7 @@ import 'package:injectable/injectable.dart';
import '../../../common/api/api_client.dart'; import '../../../common/api/api_client.dart';
import '../../../common/api/api_failure.dart'; import '../../../common/api/api_failure.dart';
import '../../../common/extension/extension.dart';
import '../../../common/function/app_function.dart'; import '../../../common/function/app_function.dart';
import '../../../common/url/api_path.dart'; import '../../../common/url/api_path.dart';
import '../../../domain/order/order.dart'; import '../../../domain/order/order.dart';
@ -22,9 +23,16 @@ class OrderRemoteDataProvider {
int limit = 10, int limit = 10,
String? status, String? status,
String? search, String? search,
required DateTime dateFrom,
required DateTime dateTo,
}) async { }) async {
try { try {
Map<String, dynamic> params = {'page': page, 'limit': limit}; Map<String, dynamic> params = {
'page': page,
'limit': limit,
'date_from': dateFrom.toServerDate,
'date_to': dateTo.toServerDate,
};
if (status != null && status.isNotEmpty) { if (status != null && status.isNotEmpty) {
params['status'] = status; params['status'] = status;

View File

@ -19,6 +19,8 @@ class OrderRepository implements IOrderRepository {
int limit = 20, int limit = 20,
String? status, String? status,
String? search, String? search,
required DateTime dateFrom,
required DateTime dateTo,
}) async { }) async {
try { try {
final result = await _dataProvider.fetch( final result = await _dataProvider.fetch(
@ -26,6 +28,8 @@ class OrderRepository implements IOrderRepository {
limit: limit, limit: limit,
status: status, status: status,
search: search, search: search,
dateFrom: dateFrom,
dateTo: dateTo,
); );
if (result.hasError) { if (result.hasError) {

View File

@ -0,0 +1,39 @@
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/outlet/outlet.dart';
import '../outlet_dtos.dart';
@injectable
class OutletRemoteDataProvider {
final ApiClient _apiClient;
final String _logName = 'OutletRemoteDataProvider';
OutletRemoteDataProvider(this._apiClient);
Future<DC<OutletFailure, OutletDto>> fetchById({required outletId}) async {
try {
final response = await _apiClient.get(
'${ApiPath.outlet}/detail/$outletId',
headers: getAuthorizationHeader(),
);
if (response.data['data'] == null) {
return DC.error(OutletFailure.empty());
}
final dto = OutletDto.fromJson(response.data['data']);
return DC.data(dto);
} on ApiFailure catch (e, s) {
log('fetchOutletByIdError', name: _logName, error: e, stackTrace: s);
return DC.error(OutletFailure.serverError(e));
}
}
}

View File

@ -0,0 +1,44 @@
part of '../outlet_dtos.dart';
@freezed
class OutletDto with _$OutletDto {
const OutletDto._();
const factory OutletDto({
@JsonKey(name: 'id') String? id,
@JsonKey(name: 'organization_id') String? organizationId,
@JsonKey(name: 'name') String? name,
@JsonKey(name: 'address') String? address,
@JsonKey(name: 'phone_number') String? phoneNumber,
@JsonKey(name: 'business_type') String? businessType,
@JsonKey(name: 'currency') String? currency,
@JsonKey(name: 'tax_rate') int? taxRate,
@JsonKey(name: 'is_active') bool? isActive,
@JsonKey(name: 'created_at') String? createdAt,
@JsonKey(name: 'updated_at') String? updatedAt,
}) = _OutletDto;
factory OutletDto.fromJson(Map<String, dynamic> json) =>
_$OutletDtoFromJson(json);
/// Mapper ke domain
Outlet toDomain() {
return Outlet(
id: id ?? '',
organizationId: organizationId ?? '',
name: name ?? '',
address: address ?? '',
phoneNumber: phoneNumber ?? '',
businessType: businessType ?? '',
currency: currency ?? '',
taxRate: taxRate ?? 0,
isActive: isActive ?? false,
createdAt: createdAt != null
? DateTime.tryParse(createdAt!) ?? DateTime(1970)
: DateTime(1970),
updatedAt: updatedAt != null
? DateTime.tryParse(updatedAt!) ?? DateTime(1970)
: DateTime(1970),
);
}
}

View File

@ -0,0 +1,8 @@
import 'package:freezed_annotation/freezed_annotation.dart';
import '../../domain/outlet/outlet.dart';
part 'outlet_dtos.freezed.dart';
part 'outlet_dtos.g.dart';
part 'dto/outlet_dto.dart';

View File

@ -0,0 +1,431 @@
// 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 'outlet_dtos.dart';
// **************************************************************************
// FreezedGenerator
// **************************************************************************
T _$identity<T>(T value) => value;
final _privateConstructorUsedError = UnsupportedError(
'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models',
);
OutletDto _$OutletDtoFromJson(Map<String, dynamic> json) {
return _OutletDto.fromJson(json);
}
/// @nodoc
mixin _$OutletDto {
@JsonKey(name: 'id')
String? get id => throw _privateConstructorUsedError;
@JsonKey(name: 'organization_id')
String? get organizationId => throw _privateConstructorUsedError;
@JsonKey(name: 'name')
String? get name => throw _privateConstructorUsedError;
@JsonKey(name: 'address')
String? get address => throw _privateConstructorUsedError;
@JsonKey(name: 'phone_number')
String? get phoneNumber => throw _privateConstructorUsedError;
@JsonKey(name: 'business_type')
String? get businessType => throw _privateConstructorUsedError;
@JsonKey(name: 'currency')
String? get currency => throw _privateConstructorUsedError;
@JsonKey(name: 'tax_rate')
int? get taxRate => throw _privateConstructorUsedError;
@JsonKey(name: 'is_active')
bool? get isActive => throw _privateConstructorUsedError;
@JsonKey(name: 'created_at')
String? get createdAt => throw _privateConstructorUsedError;
@JsonKey(name: 'updated_at')
String? get updatedAt => throw _privateConstructorUsedError;
/// Serializes this OutletDto to a JSON map.
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
/// Create a copy of OutletDto
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
$OutletDtoCopyWith<OutletDto> get copyWith =>
throw _privateConstructorUsedError;
}
/// @nodoc
abstract class $OutletDtoCopyWith<$Res> {
factory $OutletDtoCopyWith(OutletDto value, $Res Function(OutletDto) then) =
_$OutletDtoCopyWithImpl<$Res, OutletDto>;
@useResult
$Res call({
@JsonKey(name: 'id') String? id,
@JsonKey(name: 'organization_id') String? organizationId,
@JsonKey(name: 'name') String? name,
@JsonKey(name: 'address') String? address,
@JsonKey(name: 'phone_number') String? phoneNumber,
@JsonKey(name: 'business_type') String? businessType,
@JsonKey(name: 'currency') String? currency,
@JsonKey(name: 'tax_rate') int? taxRate,
@JsonKey(name: 'is_active') bool? isActive,
@JsonKey(name: 'created_at') String? createdAt,
@JsonKey(name: 'updated_at') String? updatedAt,
});
}
/// @nodoc
class _$OutletDtoCopyWithImpl<$Res, $Val extends OutletDto>
implements $OutletDtoCopyWith<$Res> {
_$OutletDtoCopyWithImpl(this._value, this._then);
// ignore: unused_field
final $Val _value;
// ignore: unused_field
final $Res Function($Val) _then;
/// Create a copy of OutletDto
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({
Object? id = freezed,
Object? organizationId = freezed,
Object? name = freezed,
Object? address = freezed,
Object? phoneNumber = freezed,
Object? businessType = freezed,
Object? currency = freezed,
Object? taxRate = freezed,
Object? isActive = freezed,
Object? createdAt = freezed,
Object? updatedAt = freezed,
}) {
return _then(
_value.copyWith(
id: freezed == id
? _value.id
: id // ignore: cast_nullable_to_non_nullable
as String?,
organizationId: freezed == organizationId
? _value.organizationId
: organizationId // ignore: cast_nullable_to_non_nullable
as String?,
name: freezed == name
? _value.name
: name // ignore: cast_nullable_to_non_nullable
as String?,
address: freezed == address
? _value.address
: address // ignore: cast_nullable_to_non_nullable
as String?,
phoneNumber: freezed == phoneNumber
? _value.phoneNumber
: phoneNumber // ignore: cast_nullable_to_non_nullable
as String?,
businessType: freezed == businessType
? _value.businessType
: businessType // ignore: cast_nullable_to_non_nullable
as String?,
currency: freezed == currency
? _value.currency
: currency // ignore: cast_nullable_to_non_nullable
as String?,
taxRate: freezed == taxRate
? _value.taxRate
: taxRate // ignore: cast_nullable_to_non_nullable
as int?,
isActive: freezed == isActive
? _value.isActive
: isActive // ignore: cast_nullable_to_non_nullable
as bool?,
createdAt: freezed == createdAt
? _value.createdAt
: createdAt // ignore: cast_nullable_to_non_nullable
as String?,
updatedAt: freezed == updatedAt
? _value.updatedAt
: updatedAt // ignore: cast_nullable_to_non_nullable
as String?,
)
as $Val,
);
}
}
/// @nodoc
abstract class _$$OutletDtoImplCopyWith<$Res>
implements $OutletDtoCopyWith<$Res> {
factory _$$OutletDtoImplCopyWith(
_$OutletDtoImpl value,
$Res Function(_$OutletDtoImpl) then,
) = __$$OutletDtoImplCopyWithImpl<$Res>;
@override
@useResult
$Res call({
@JsonKey(name: 'id') String? id,
@JsonKey(name: 'organization_id') String? organizationId,
@JsonKey(name: 'name') String? name,
@JsonKey(name: 'address') String? address,
@JsonKey(name: 'phone_number') String? phoneNumber,
@JsonKey(name: 'business_type') String? businessType,
@JsonKey(name: 'currency') String? currency,
@JsonKey(name: 'tax_rate') int? taxRate,
@JsonKey(name: 'is_active') bool? isActive,
@JsonKey(name: 'created_at') String? createdAt,
@JsonKey(name: 'updated_at') String? updatedAt,
});
}
/// @nodoc
class __$$OutletDtoImplCopyWithImpl<$Res>
extends _$OutletDtoCopyWithImpl<$Res, _$OutletDtoImpl>
implements _$$OutletDtoImplCopyWith<$Res> {
__$$OutletDtoImplCopyWithImpl(
_$OutletDtoImpl _value,
$Res Function(_$OutletDtoImpl) _then,
) : super(_value, _then);
/// Create a copy of OutletDto
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({
Object? id = freezed,
Object? organizationId = freezed,
Object? name = freezed,
Object? address = freezed,
Object? phoneNumber = freezed,
Object? businessType = freezed,
Object? currency = freezed,
Object? taxRate = freezed,
Object? isActive = freezed,
Object? createdAt = freezed,
Object? updatedAt = freezed,
}) {
return _then(
_$OutletDtoImpl(
id: freezed == id
? _value.id
: id // ignore: cast_nullable_to_non_nullable
as String?,
organizationId: freezed == organizationId
? _value.organizationId
: organizationId // ignore: cast_nullable_to_non_nullable
as String?,
name: freezed == name
? _value.name
: name // ignore: cast_nullable_to_non_nullable
as String?,
address: freezed == address
? _value.address
: address // ignore: cast_nullable_to_non_nullable
as String?,
phoneNumber: freezed == phoneNumber
? _value.phoneNumber
: phoneNumber // ignore: cast_nullable_to_non_nullable
as String?,
businessType: freezed == businessType
? _value.businessType
: businessType // ignore: cast_nullable_to_non_nullable
as String?,
currency: freezed == currency
? _value.currency
: currency // ignore: cast_nullable_to_non_nullable
as String?,
taxRate: freezed == taxRate
? _value.taxRate
: taxRate // ignore: cast_nullable_to_non_nullable
as int?,
isActive: freezed == isActive
? _value.isActive
: isActive // ignore: cast_nullable_to_non_nullable
as bool?,
createdAt: freezed == createdAt
? _value.createdAt
: createdAt // ignore: cast_nullable_to_non_nullable
as String?,
updatedAt: freezed == updatedAt
? _value.updatedAt
: updatedAt // ignore: cast_nullable_to_non_nullable
as String?,
),
);
}
}
/// @nodoc
@JsonSerializable()
class _$OutletDtoImpl extends _OutletDto {
const _$OutletDtoImpl({
@JsonKey(name: 'id') this.id,
@JsonKey(name: 'organization_id') this.organizationId,
@JsonKey(name: 'name') this.name,
@JsonKey(name: 'address') this.address,
@JsonKey(name: 'phone_number') this.phoneNumber,
@JsonKey(name: 'business_type') this.businessType,
@JsonKey(name: 'currency') this.currency,
@JsonKey(name: 'tax_rate') this.taxRate,
@JsonKey(name: 'is_active') this.isActive,
@JsonKey(name: 'created_at') this.createdAt,
@JsonKey(name: 'updated_at') this.updatedAt,
}) : super._();
factory _$OutletDtoImpl.fromJson(Map<String, dynamic> json) =>
_$$OutletDtoImplFromJson(json);
@override
@JsonKey(name: 'id')
final String? id;
@override
@JsonKey(name: 'organization_id')
final String? organizationId;
@override
@JsonKey(name: 'name')
final String? name;
@override
@JsonKey(name: 'address')
final String? address;
@override
@JsonKey(name: 'phone_number')
final String? phoneNumber;
@override
@JsonKey(name: 'business_type')
final String? businessType;
@override
@JsonKey(name: 'currency')
final String? currency;
@override
@JsonKey(name: 'tax_rate')
final int? taxRate;
@override
@JsonKey(name: 'is_active')
final bool? isActive;
@override
@JsonKey(name: 'created_at')
final String? createdAt;
@override
@JsonKey(name: 'updated_at')
final String? updatedAt;
@override
String toString() {
return 'OutletDto(id: $id, organizationId: $organizationId, name: $name, address: $address, phoneNumber: $phoneNumber, businessType: $businessType, currency: $currency, taxRate: $taxRate, isActive: $isActive, createdAt: $createdAt, updatedAt: $updatedAt)';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType &&
other is _$OutletDtoImpl &&
(identical(other.id, id) || other.id == id) &&
(identical(other.organizationId, organizationId) ||
other.organizationId == organizationId) &&
(identical(other.name, name) || other.name == name) &&
(identical(other.address, address) || other.address == address) &&
(identical(other.phoneNumber, phoneNumber) ||
other.phoneNumber == phoneNumber) &&
(identical(other.businessType, businessType) ||
other.businessType == businessType) &&
(identical(other.currency, currency) ||
other.currency == currency) &&
(identical(other.taxRate, taxRate) || other.taxRate == taxRate) &&
(identical(other.isActive, isActive) ||
other.isActive == isActive) &&
(identical(other.createdAt, createdAt) ||
other.createdAt == createdAt) &&
(identical(other.updatedAt, updatedAt) ||
other.updatedAt == updatedAt));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(
runtimeType,
id,
organizationId,
name,
address,
phoneNumber,
businessType,
currency,
taxRate,
isActive,
createdAt,
updatedAt,
);
/// Create a copy of OutletDto
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@override
@pragma('vm:prefer-inline')
_$$OutletDtoImplCopyWith<_$OutletDtoImpl> get copyWith =>
__$$OutletDtoImplCopyWithImpl<_$OutletDtoImpl>(this, _$identity);
@override
Map<String, dynamic> toJson() {
return _$$OutletDtoImplToJson(this);
}
}
abstract class _OutletDto extends OutletDto {
const factory _OutletDto({
@JsonKey(name: 'id') final String? id,
@JsonKey(name: 'organization_id') final String? organizationId,
@JsonKey(name: 'name') final String? name,
@JsonKey(name: 'address') final String? address,
@JsonKey(name: 'phone_number') final String? phoneNumber,
@JsonKey(name: 'business_type') final String? businessType,
@JsonKey(name: 'currency') final String? currency,
@JsonKey(name: 'tax_rate') final int? taxRate,
@JsonKey(name: 'is_active') final bool? isActive,
@JsonKey(name: 'created_at') final String? createdAt,
@JsonKey(name: 'updated_at') final String? updatedAt,
}) = _$OutletDtoImpl;
const _OutletDto._() : super._();
factory _OutletDto.fromJson(Map<String, dynamic> json) =
_$OutletDtoImpl.fromJson;
@override
@JsonKey(name: 'id')
String? get id;
@override
@JsonKey(name: 'organization_id')
String? get organizationId;
@override
@JsonKey(name: 'name')
String? get name;
@override
@JsonKey(name: 'address')
String? get address;
@override
@JsonKey(name: 'phone_number')
String? get phoneNumber;
@override
@JsonKey(name: 'business_type')
String? get businessType;
@override
@JsonKey(name: 'currency')
String? get currency;
@override
@JsonKey(name: 'tax_rate')
int? get taxRate;
@override
@JsonKey(name: 'is_active')
bool? get isActive;
@override
@JsonKey(name: 'created_at')
String? get createdAt;
@override
@JsonKey(name: 'updated_at')
String? get updatedAt;
/// Create a copy of OutletDto
/// with the given fields replaced by the non-null parameter values.
@override
@JsonKey(includeFromJson: false, includeToJson: false)
_$$OutletDtoImplCopyWith<_$OutletDtoImpl> get copyWith =>
throw _privateConstructorUsedError;
}

View File

@ -0,0 +1,37 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'outlet_dtos.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
_$OutletDtoImpl _$$OutletDtoImplFromJson(Map<String, dynamic> json) =>
_$OutletDtoImpl(
id: json['id'] as String?,
organizationId: json['organization_id'] as String?,
name: json['name'] as String?,
address: json['address'] as String?,
phoneNumber: json['phone_number'] as String?,
businessType: json['business_type'] as String?,
currency: json['currency'] as String?,
taxRate: (json['tax_rate'] as num?)?.toInt(),
isActive: json['is_active'] as bool?,
createdAt: json['created_at'] as String?,
updatedAt: json['updated_at'] as String?,
);
Map<String, dynamic> _$$OutletDtoImplToJson(_$OutletDtoImpl instance) =>
<String, dynamic>{
'id': instance.id,
'organization_id': instance.organizationId,
'name': instance.name,
'address': instance.address,
'phone_number': instance.phoneNumber,
'business_type': instance.businessType,
'currency': instance.currency,
'tax_rate': instance.taxRate,
'is_active': instance.isActive,
'created_at': instance.createdAt,
'updated_at': instance.updatedAt,
};

View File

@ -0,0 +1,36 @@
import 'dart:developer';
import 'package:dartz/dartz.dart';
import 'package:injectable/injectable.dart';
import '../../../domain/outlet/outlet.dart';
import '../../auth/datasources/local_data_provider.dart';
import '../datasource/remote_data_provider.dart';
@Injectable(as: IOutletRepository)
class OutletRepository implements IOutletRepository {
final OutletRemoteDataProvider _dataProvider;
final AuthLocalDataProvider _authLocalDataProvider;
final String _logName = 'OutletRepository';
OutletRepository(this._dataProvider, this._authLocalDataProvider);
@override
Future<Either<OutletFailure, Outlet>> currentOutlet() async {
try {
final authData = await _authLocalDataProvider.currentUser();
final result = await _dataProvider.fetchById(outletId: authData.outletId);
if (result.hasError) {
return left(result.error!);
}
final auth = result.data!.toDomain();
return right(auth);
} catch (e, s) {
log('currentOutletError', name: _logName, error: e, stackTrace: s);
return left(const OutletFailure.unexpectedError());
}
}
}

View File

@ -32,10 +32,13 @@ import 'package:apskel_owner_flutter/application/category/category_loader/catego
as _i183; as _i183;
import 'package:apskel_owner_flutter/application/customer/customer_loader/customer_loader_bloc.dart' import 'package:apskel_owner_flutter/application/customer/customer_loader/customer_loader_bloc.dart'
as _i972; as _i972;
import 'package:apskel_owner_flutter/application/home/home_bloc.dart' as _i473;
import 'package:apskel_owner_flutter/application/language/language_bloc.dart' import 'package:apskel_owner_flutter/application/language/language_bloc.dart'
as _i455; as _i455;
import 'package:apskel_owner_flutter/application/order/order_loader/order_loader_bloc.dart' import 'package:apskel_owner_flutter/application/order/order_loader/order_loader_bloc.dart'
as _i1058; as _i1058;
import 'package:apskel_owner_flutter/application/outlet/current_outlet_loader/current_outlet_loader_bloc.dart'
as _i337;
import 'package:apskel_owner_flutter/application/product/product_loader/product_loader_bloc.dart' import 'package:apskel_owner_flutter/application/product/product_loader/product_loader_bloc.dart'
as _i458; as _i458;
import 'package:apskel_owner_flutter/common/api/api_client.dart' as _i115; import 'package:apskel_owner_flutter/common/api/api_client.dart' as _i115;
@ -53,6 +56,7 @@ 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/category/category.dart' as _i1020;
import 'package:apskel_owner_flutter/domain/customer/customer.dart' as _i48; 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/order/order.dart' as _i219;
import 'package:apskel_owner_flutter/domain/outlet/outlet.dart' as _i197;
import 'package:apskel_owner_flutter/domain/product/product.dart' as _i419; import 'package:apskel_owner_flutter/domain/product/product.dart' as _i419;
import 'package:apskel_owner_flutter/env.dart' as _i6; import 'package:apskel_owner_flutter/env.dart' as _i6;
import 'package:apskel_owner_flutter/infrastructure/analytic/datasource/remote_data_provider.dart' import 'package:apskel_owner_flutter/infrastructure/analytic/datasource/remote_data_provider.dart'
@ -77,6 +81,10 @@ import 'package:apskel_owner_flutter/infrastructure/order/datasource/remote_data
as _i130; as _i130;
import 'package:apskel_owner_flutter/infrastructure/order/repositories/order_repository.dart' import 'package:apskel_owner_flutter/infrastructure/order/repositories/order_repository.dart'
as _i641; as _i641;
import 'package:apskel_owner_flutter/infrastructure/outlet/datasource/remote_data_provider.dart'
as _i27;
import 'package:apskel_owner_flutter/infrastructure/outlet/repositories/outlet_repository.dart'
as _i13;
import 'package:apskel_owner_flutter/infrastructure/product/datasources/remote_data_provider.dart' import 'package:apskel_owner_flutter/infrastructure/product/datasources/remote_data_provider.dart'
as _i823; as _i823;
import 'package:apskel_owner_flutter/infrastructure/product/repositories/product_repository.dart' import 'package:apskel_owner_flutter/infrastructure/product/repositories/product_repository.dart'
@ -148,6 +156,9 @@ extension GetItInjectableX on _i174.GetIt {
gh.factory<_i1006.CustomerRemoteDataProvider>( gh.factory<_i1006.CustomerRemoteDataProvider>(
() => _i1006.CustomerRemoteDataProvider(gh<_i115.ApiClient>()), () => _i1006.CustomerRemoteDataProvider(gh<_i115.ApiClient>()),
); );
gh.factory<_i27.OutletRemoteDataProvider>(
() => _i27.OutletRemoteDataProvider(gh<_i115.ApiClient>()),
);
gh.factory<_i48.ICustomerRepository>( gh.factory<_i48.ICustomerRepository>(
() => _i550.CustomerRepository(gh<_i1006.CustomerRemoteDataProvider>()), () => _i550.CustomerRepository(gh<_i1006.CustomerRemoteDataProvider>()),
); );
@ -175,6 +186,12 @@ extension GetItInjectableX on _i174.GetIt {
gh.factory<_i1020.ICategoryRepository>( gh.factory<_i1020.ICategoryRepository>(
() => _i869.CategoryRepository(gh<_i333.CategoryRemoteDataProvider>()), () => _i869.CategoryRepository(gh<_i333.CategoryRemoteDataProvider>()),
); );
gh.factory<_i197.IOutletRepository>(
() => _i13.OutletRepository(
gh<_i27.OutletRemoteDataProvider>(),
gh<_i991.AuthLocalDataProvider>(),
),
);
gh.factory<_i458.ProductLoaderBloc>( gh.factory<_i458.ProductLoaderBloc>(
() => _i458.ProductLoaderBloc(gh<_i419.IProductRepository>()), () => _i458.ProductLoaderBloc(gh<_i419.IProductRepository>()),
); );
@ -184,6 +201,12 @@ extension GetItInjectableX on _i174.GetIt {
gh.factory<_i889.SalesLoaderBloc>( gh.factory<_i889.SalesLoaderBloc>(
() => _i889.SalesLoaderBloc(gh<_i477.IAnalyticRepository>()), () => _i889.SalesLoaderBloc(gh<_i477.IAnalyticRepository>()),
); );
gh.factory<_i473.HomeBloc>(
() => _i473.HomeBloc(gh<_i477.IAnalyticRepository>()),
);
gh.factory<_i337.CurrentOutletLoaderBloc>(
() => _i337.CurrentOutletLoaderBloc(gh<_i197.IOutletRepository>()),
);
gh.factory<_i221.ProductAnalyticLoaderBloc>( gh.factory<_i221.ProductAnalyticLoaderBloc>(
() => _i221.ProductAnalyticLoaderBloc(gh<_i477.IAnalyticRepository>()), () => _i221.ProductAnalyticLoaderBloc(gh<_i477.IAnalyticRepository>()),
); );

View File

@ -0,0 +1,186 @@
import 'package:flutter/material.dart';
import 'package:auto_route/auto_route.dart';
import '../../../common/theme/theme.dart';
@RoutePage()
class ComingSoonPage extends StatefulWidget {
const ComingSoonPage({super.key});
@override
State<ComingSoonPage> createState() => _ComingSoonPageState();
}
class _ComingSoonPageState extends State<ComingSoonPage>
with TickerProviderStateMixin {
late AnimationController _fadeController;
late AnimationController _slideController;
late AnimationController _pulseController;
late Animation<double> _fadeAnimation;
late Animation<Offset> _slideAnimation;
late Animation<double> _pulseAnimation;
@override
void initState() {
super.initState();
// Initialize animation controllers
_fadeController = AnimationController(
duration: const Duration(milliseconds: 1500),
vsync: this,
);
_slideController = AnimationController(
duration: const Duration(milliseconds: 1200),
vsync: this,
);
_pulseController = AnimationController(
duration: const Duration(milliseconds: 2000),
vsync: this,
);
// Initialize animations
_fadeAnimation = Tween<double>(begin: 0.0, end: 1.0).animate(
CurvedAnimation(parent: _fadeController, curve: Curves.easeInOut),
);
_slideAnimation =
Tween<Offset>(begin: const Offset(0, 0.5), end: Offset.zero).animate(
CurvedAnimation(parent: _slideController, curve: Curves.easeOutCubic),
);
_pulseAnimation = Tween<double>(begin: 1.0, end: 1.1).animate(
CurvedAnimation(parent: _pulseController, curve: Curves.easeInOut),
);
// Start animations
_startAnimations();
}
void _startAnimations() {
_fadeController.forward();
_slideController.forward();
_pulseController.repeat(reverse: true);
}
@override
void dispose() {
_fadeController.dispose();
_slideController.dispose();
_pulseController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
width: double.infinity,
height: double.infinity,
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: [
AppColor.primary,
AppColor.primaryLight,
AppColor.primaryDark,
],
stops: const [0.0, 0.5, 1.0],
),
),
child: SafeArea(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 24.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
// Animated Logo/Icon
FadeTransition(
opacity: _fadeAnimation,
child: SlideTransition(
position: _slideAnimation,
child: _buildAnimatedLogo(),
),
),
const SizedBox(height: 40),
// Coming Soon Text
FadeTransition(
opacity: _fadeAnimation,
child: SlideTransition(
position: _slideAnimation,
child: Text(
'Coming Soon',
style: AppStyle.h1.copyWith(
color: AppColor.textWhite,
fontWeight: FontWeight.bold,
fontSize: 42,
letterSpacing: 2.0,
),
textAlign: TextAlign.center,
),
),
),
const SizedBox(height: 16),
// Subtitle
FadeTransition(
opacity: _fadeAnimation,
child: SlideTransition(
position: _slideAnimation,
child: Text(
'Something amazing is brewing!\nStay tuned for the big reveal.',
style: AppStyle.lg.copyWith(
color: AppColor.textWhite.withOpacity(0.9),
height: 1.5,
),
textAlign: TextAlign.center,
),
),
),
],
),
),
),
),
);
}
Widget _buildAnimatedLogo() {
return AnimatedBuilder(
animation: _pulseAnimation,
builder: (context, child) {
return Transform.scale(
scale: _pulseAnimation.value,
child: Container(
width: 120,
height: 120,
decoration: BoxDecoration(
shape: BoxShape.circle,
gradient: LinearGradient(
colors: [AppColor.secondary, AppColor.secondaryLight],
),
boxShadow: [
BoxShadow(
color: AppColor.secondary.withOpacity(0.3),
blurRadius: 30,
spreadRadius: 5,
),
],
),
child: Icon(
Icons.rocket_launch,
size: 60,
color: AppColor.textWhite,
),
),
);
},
);
}
}

View File

@ -0,0 +1,464 @@
import 'package:flutter/material.dart';
import 'package:auto_route/auto_route.dart';
import '../../../common/theme/theme.dart';
import '../../components/appbar/appbar.dart';
import '../../components/field/date_range_picker_field.dart';
@RoutePage()
class DownloadReportPage extends StatefulWidget {
const DownloadReportPage({super.key});
@override
State<DownloadReportPage> createState() => _DownloadReportPageState();
}
class _DownloadReportPageState extends State<DownloadReportPage>
with TickerProviderStateMixin {
late AnimationController _fadeController;
late AnimationController _slideController;
late AnimationController _scaleController;
late Animation<double> _fadeAnimation;
// Date range variables for each report type
DateTime? _transactionStartDate;
DateTime? _transactionEndDate;
DateTime? _inventoryStartDate;
DateTime? _inventoryEndDate;
DateTime? _salesStartDate;
DateTime? _salesEndDate;
DateTime? _customerStartDate;
DateTime? _customerEndDate;
@override
void initState() {
super.initState();
// Initialize animation controllers
_fadeController = AnimationController(
duration: const Duration(milliseconds: 800),
vsync: this,
);
_slideController = AnimationController(
duration: const Duration(milliseconds: 1000),
vsync: this,
);
_scaleController = AnimationController(
duration: const Duration(milliseconds: 600),
vsync: this,
);
// Initialize animations
_fadeAnimation = Tween<double>(begin: 0.0, end: 1.0).animate(
CurvedAnimation(parent: _fadeController, curve: Curves.easeInOut),
);
// Start animations
_fadeController.forward();
_slideController.forward();
_scaleController.forward();
}
@override
void dispose() {
_fadeController.dispose();
_slideController.dispose();
_scaleController.dispose();
super.dispose();
}
void _downloadReport(
String reportType,
DateTime? startDate,
DateTime? endDate,
) {
if (startDate == null || endDate == null) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('Please select both start and end dates'),
backgroundColor: AppColor.error,
),
);
return;
}
// Implement download logic here
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
'Downloading $reportType from ${_formatDate(startDate)} to ${_formatDate(endDate)}',
),
backgroundColor: AppColor.success,
),
);
}
String _formatDate(DateTime date) {
return '${date.day}/${date.month}/${date.year}';
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: AppColor.background,
body: CustomScrollView(
slivers: [
// SliverAppBar with gradient
SliverAppBar(
expandedHeight: 120,
floating: false,
pinned: true,
elevation: 0,
backgroundColor: AppColor.primary,
flexibleSpace: CustomAppBar(title: 'Download Report'),
),
// Content
SliverToBoxAdapter(
child: Padding(
padding: const EdgeInsets.all(20),
child: Column(
children: [
// Report Options
FadeTransition(
opacity: _fadeAnimation,
child: Column(
children: [
// Transaction Report Card
_ReportOptionCard(
title: 'Transaction Report',
subtitle:
'Export all transaction data with detailed analytics',
icon: Icons.receipt_long_outlined,
gradient: const [
AppColor.primary,
AppColor.primaryLight,
],
startDate: _transactionStartDate,
endDate: _transactionEndDate,
onDateRangeChanged: (start, end) {
setState(() {
_transactionStartDate = start;
_transactionEndDate = end;
});
},
onDownload: () => _downloadReport(
'Transaction Report',
_transactionStartDate,
_transactionEndDate,
),
delay: 200,
),
const SizedBox(height: 20),
// Inventory Report Card
_ReportOptionCard(
title: 'Inventory Report',
subtitle:
'Export inventory and stock data with trends',
icon: Icons.inventory_2_outlined,
gradient: const [
AppColor.secondary,
AppColor.secondaryLight,
],
startDate: _inventoryStartDate,
endDate: _inventoryEndDate,
onDateRangeChanged: (start, end) {
setState(() {
_inventoryStartDate = start;
_inventoryEndDate = end;
});
},
onDownload: () => _downloadReport(
'Inventory Report',
_inventoryStartDate,
_inventoryEndDate,
),
delay: 400,
),
const SizedBox(height: 20),
// Sales Report Card
_ReportOptionCard(
title: 'Sales Report',
subtitle: 'Export sales performance and revenue data',
icon: Icons.trending_up_outlined,
gradient: const [AppColor.info, Color(0xFF64B5F6)],
startDate: _salesStartDate,
endDate: _salesEndDate,
onDateRangeChanged: (start, end) {
setState(() {
_salesStartDate = start;
_salesEndDate = end;
});
},
onDownload: () => _downloadReport(
'Sales Report',
_salesStartDate,
_salesEndDate,
),
delay: 600,
),
const SizedBox(height: 20),
// Customer Report Card
_ReportOptionCard(
title: 'Customer Report',
subtitle:
'Export customer data and behavior analytics',
icon: Icons.people_outline,
gradient: const [AppColor.warning, Color(0xFFFFB74D)],
startDate: _customerStartDate,
endDate: _customerEndDate,
onDateRangeChanged: (start, end) {
setState(() {
_customerStartDate = start;
_customerEndDate = end;
});
},
onDownload: () => _downloadReport(
'Customer Report',
_customerStartDate,
_customerEndDate,
),
delay: 800,
),
],
),
),
const SizedBox(height: 40),
],
),
),
),
],
),
);
}
}
class _ReportOptionCard extends StatefulWidget {
final String title;
final String subtitle;
final IconData icon;
final List<Color> gradient;
final DateTime? startDate;
final DateTime? endDate;
final Function(DateTime? startDate, DateTime? endDate) onDateRangeChanged;
final VoidCallback onDownload;
final int delay;
const _ReportOptionCard({
required this.title,
required this.subtitle,
required this.icon,
required this.gradient,
required this.startDate,
required this.endDate,
required this.onDateRangeChanged,
required this.onDownload,
required this.delay,
});
@override
State<_ReportOptionCard> createState() => _ReportOptionCardState();
}
class _ReportOptionCardState extends State<_ReportOptionCard>
with SingleTickerProviderStateMixin {
late AnimationController _animationController;
late Animation<double> _slideAnimation;
bool _isExpanded = false;
@override
void initState() {
super.initState();
_animationController = AnimationController(
duration: const Duration(milliseconds: 300),
vsync: this,
);
_slideAnimation = CurvedAnimation(
parent: _animationController,
curve: Curves.easeInOutCubic,
);
}
@override
void dispose() {
_animationController.dispose();
super.dispose();
}
void _toggleExpanded() {
setState(() {
_isExpanded = !_isExpanded;
if (_isExpanded) {
_animationController.forward();
} else {
_animationController.reverse();
}
});
}
@override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: widget.gradient,
),
borderRadius: BorderRadius.circular(20),
boxShadow: [
BoxShadow(
color: widget.gradient.first.withOpacity(0.3),
blurRadius: 15,
offset: const Offset(0, 8),
),
],
),
child: Column(
children: [
// Header Section
GestureDetector(
onTap: _toggleExpanded,
child: Container(
padding: const EdgeInsets.all(20),
child: Row(
children: [
Container(
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: AppColor.white.withOpacity(0.2),
borderRadius: BorderRadius.circular(16),
),
child: Icon(widget.icon, color: AppColor.white, size: 32),
),
const SizedBox(width: 20),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
widget.title,
style: AppStyle.lg.copyWith(
color: AppColor.white,
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 4),
Text(
widget.subtitle,
style: AppStyle.sm.copyWith(
color: AppColor.white.withOpacity(0.8),
),
),
],
),
),
AnimatedRotation(
turns: _isExpanded ? 0.25 : 0,
duration: const Duration(milliseconds: 300),
child: Icon(
Icons.arrow_forward_ios,
color: AppColor.white.withOpacity(0.8),
size: 20,
),
),
],
),
),
),
// Expandable Content
SizeTransition(
sizeFactor: _slideAnimation,
child: Container(
padding: const EdgeInsets.fromLTRB(20, 0, 20, 20),
child: Column(
children: [
Container(
padding: const EdgeInsets.all(20),
decoration: BoxDecoration(
color: AppColor.white.withOpacity(0.1),
borderRadius: BorderRadius.circular(16),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Select Date Range',
style: AppStyle.md.copyWith(
color: AppColor.white,
fontWeight: FontWeight.w600,
),
),
const SizedBox(height: 16),
// Date Range Picker Field Style
DateRangePickerField(
placeholder: 'Select date range',
startDate: widget.startDate,
endDate: widget.endDate,
onChanged: widget.onDateRangeChanged,
),
const SizedBox(height: 20),
// Download Button
SizedBox(
width: double.infinity,
child: ElevatedButton(
onPressed:
widget.startDate != null &&
widget.endDate != null
? widget.onDownload
: null,
style: ElevatedButton.styleFrom(
backgroundColor: AppColor.white,
foregroundColor: widget.gradient.first,
padding: const EdgeInsets.symmetric(vertical: 16),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
),
elevation: 0,
),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(
Icons.download_rounded,
color: widget.gradient.first,
),
const SizedBox(width: 8),
Text(
'Download Report',
style: AppStyle.md.copyWith(
color: widget.gradient.first,
fontWeight: FontWeight.bold,
),
),
],
),
),
),
],
),
),
],
),
),
),
],
),
);
}
}

View File

@ -1,22 +1,31 @@
import 'package:auto_route/auto_route.dart'; import 'package:auto_route/auto_route.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:line_icons/line_icons.dart'; import 'package:line_icons/line_icons.dart';
import '../../../application/home/home_bloc.dart';
import '../../../common/constant/app_constant.dart';
import '../../../common/theme/theme.dart'; import '../../../common/theme/theme.dart';
import '../../../injection.dart';
import '../../components/button/button.dart'; import '../../components/button/button.dart';
import '../../components/spacer/spacer.dart'; import '../../components/spacer/spacer.dart';
import 'widgets/activity.dart';
import 'widgets/feature.dart'; import 'widgets/feature.dart';
import 'widgets/header.dart'; import 'widgets/header.dart';
import 'widgets/performance.dart';
import 'widgets/stats.dart'; import 'widgets/stats.dart';
import 'widgets/top_product.dart';
@RoutePage() @RoutePage()
class HomePage extends StatefulWidget { class HomePage extends StatefulWidget implements AutoRouteWrapper {
const HomePage({super.key}); const HomePage({super.key});
@override @override
State<HomePage> createState() => _HomePageState(); State<HomePage> createState() => _HomePageState();
@override
Widget wrappedRoute(BuildContext context) => BlocProvider(
create: (context) => getIt<HomeBloc>()..add(HomeEvent.fetchedDashboard()),
child: this,
);
} }
class _HomePageState extends State<HomePage> with TickerProviderStateMixin { class _HomePageState extends State<HomePage> with TickerProviderStateMixin {
@ -58,8 +67,12 @@ class _HomePageState extends State<HomePage> with TickerProviderStateMixin {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
backgroundColor: AppColor.background, backgroundColor: AppColor.background,
body: CustomScrollView( body: BlocBuilder<HomeBloc, HomeState>(
physics: const BouncingScrollPhysics(parent: ClampingScrollPhysics()), builder: (context, state) {
return CustomScrollView(
physics: const BouncingScrollPhysics(
parent: ClampingScrollPhysics(),
),
slivers: [ slivers: [
// SliverAppBar with HomeHeader as background // SliverAppBar with HomeHeader as background
SliverAppBar( SliverAppBar(
@ -92,7 +105,7 @@ class _HomePageState extends State<HomePage> with TickerProviderStateMixin {
children: [ children: [
Expanded( Expanded(
child: Text( child: Text(
'AppSkel POS Owner', AppConstant.appName,
style: AppStyle.xl.copyWith( style: AppStyle.xl.copyWith(
fontWeight: FontWeight.w700, fontWeight: FontWeight.w700,
fontSize: 18, fontSize: 18,
@ -101,7 +114,10 @@ class _HomePageState extends State<HomePage> with TickerProviderStateMixin {
), ),
), ),
), ),
ActionIconButton(onTap: () {}, icon: LineIcons.bell), ActionIconButton(
onTap: () {},
icon: LineIcons.bell,
),
], ],
), ),
), ),
@ -120,7 +136,10 @@ class _HomePageState extends State<HomePage> with TickerProviderStateMixin {
), ),
child: Opacity( child: Opacity(
opacity: _headerAnimationController.value, opacity: _headerAnimationController.value,
child: HomeHeader(), child: HomeHeader(
totalRevenue:
state.dashboard.overview.totalSales,
),
), ),
); );
}, },
@ -146,9 +165,10 @@ class _HomePageState extends State<HomePage> with TickerProviderStateMixin {
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
HomeFeature(), HomeFeature(),
HomeStats(), HomeStats(overview: state.dashboard.overview),
HomeActivity(), HomeTopProduct(
HomePerformance(), products: state.dashboard.topProducts,
),
const SpaceHeight(40), const SpaceHeight(40),
], ],
), ),
@ -158,6 +178,8 @@ class _HomePageState extends State<HomePage> with TickerProviderStateMixin {
), ),
), ),
], ],
);
},
), ),
); );
} }

View File

@ -1,95 +0,0 @@
import 'package:flutter/material.dart';
import '../../../../common/theme/theme.dart';
import '../../../components/spacer/spacer.dart';
import 'activity_tile.dart';
class HomeActivity extends StatelessWidget {
const HomeActivity({super.key});
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.symmetric(
vertical: 24,
horizontal: AppValue.padding,
).copyWith(bottom: 0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
const Text(
'Aktivitas Terkini',
style: TextStyle(
fontSize: 22,
fontWeight: FontWeight.w700,
color: AppColor.textPrimary,
letterSpacing: -0.5,
),
),
TextButton.icon(
onPressed: () {},
icon: const Icon(Icons.arrow_forward_rounded, size: 16),
label: const Text('Lihat Semua'),
style: TextButton.styleFrom(
foregroundColor: AppColor.primary,
textStyle: const TextStyle(
fontWeight: FontWeight.w600,
fontSize: 14,
),
),
),
],
),
const SpaceHeight(16),
Container(
decoration: BoxDecoration(
color: AppColor.white,
borderRadius: BorderRadius.circular(16),
border: Border.all(color: AppColor.border.withOpacity(0.5)),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.04),
blurRadius: 20,
offset: const Offset(0, 8),
),
],
),
child: Column(
children: [
HomeActivityTile(
title: 'Transaksi Berhasil',
subtitle: 'Kasir-01 • Rp 125.000',
time: '2 menit lalu',
icon: Icons.check_circle_rounded,
color: AppColor.success,
isHighlighted: true,
),
const Divider(height: 1, color: AppColor.border),
HomeActivityTile(
title: 'Stok Menipis',
subtitle: 'Kopi Arabica • 5 unit tersisa',
time: '15 menit lalu',
icon: Icons.warning_amber_rounded,
color: AppColor.warning,
isHighlighted: false,
),
const Divider(height: 1, color: AppColor.border),
HomeActivityTile(
title: 'Login Kasir',
subtitle: 'Sari masuk shift pagi',
time: '1 Jam lalu',
icon: Icons.login_rounded,
color: AppColor.info,
isHighlighted: false,
),
],
),
),
],
),
);
}
}

View File

@ -1,103 +0,0 @@
import 'package:flutter/material.dart';
import '../../../../common/theme/theme.dart';
import '../../../components/spacer/spacer.dart';
class HomeActivityTile extends StatelessWidget {
final String title;
final String subtitle;
final String time;
final IconData icon;
final Color color;
final bool isHighlighted;
const HomeActivityTile({
super.key,
required this.title,
required this.subtitle,
required this.time,
required this.icon,
required this.color,
required this.isHighlighted,
});
@override
Widget build(BuildContext context) {
return Container(
padding: const EdgeInsets.all(20),
decoration: BoxDecoration(
color: isHighlighted ? color.withOpacity(0.02) : Colors.transparent,
borderRadius: isHighlighted ? BorderRadius.circular(16) : null,
),
child: Row(
children: [
Container(
padding: const EdgeInsets.all(12),
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [color.withOpacity(0.1), color.withOpacity(0.05)],
begin: Alignment.topLeft,
end: Alignment.bottomRight,
),
borderRadius: BorderRadius.circular(12),
border: Border.all(color: color.withOpacity(0.2), width: 1),
),
child: Icon(icon, color: color, size: 20),
),
const SpaceWidth(16),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
Text(
title,
style: AppStyle.md.copyWith(
fontWeight: FontWeight.w600,
color: AppColor.textPrimary,
letterSpacing: -0.2,
),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
const SpaceHeight(4),
Text(
subtitle,
style: AppStyle.sm.copyWith(
color: AppColor.textSecondary,
fontWeight: FontWeight.w500,
),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
],
),
),
Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Text(
time,
style: AppStyle.xs.copyWith(
fontSize: 11,
color: AppColor.textLight,
fontWeight: FontWeight.w500,
),
),
if (isHighlighted) ...[
const SpaceHeight(4),
Container(
width: 6,
height: 6,
decoration: BoxDecoration(
color: color,
shape: BoxShape.circle,
),
),
],
],
),
],
),
);
}
}

View File

@ -11,7 +11,8 @@ import '../../../../domain/auth/auth.dart';
import '../../../components/spacer/spacer.dart'; import '../../../components/spacer/spacer.dart';
class HomeHeader extends StatefulWidget { class HomeHeader extends StatefulWidget {
const HomeHeader({super.key}); final int totalRevenue;
const HomeHeader({super.key, required this.totalRevenue});
@override @override
State<HomeHeader> createState() => _HomeHeaderState(); State<HomeHeader> createState() => _HomeHeaderState();
@ -467,7 +468,7 @@ class _HomeHeaderState extends State<HomeHeader> with TickerProviderStateMixin {
), ),
const SizedBox(width: 6), const SizedBox(width: 6),
Text( Text(
'${context.lang.sales_today} +25%', '${context.lang.sales_today} ${widget.totalRevenue.currencyFormatRp}',
style: AppStyle.sm.copyWith( style: AppStyle.sm.copyWith(
color: AppColor.white, color: AppColor.white,
fontWeight: FontWeight.w600, fontWeight: FontWeight.w600,

View File

@ -1,281 +0,0 @@
import 'package:flutter/material.dart';
import '../../../../common/theme/theme.dart';
import '../../../components/spacer/spacer.dart';
class HomePerformance extends StatelessWidget {
const HomePerformance({super.key});
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.symmetric(
vertical: 24,
horizontal: AppValue.padding,
).copyWith(bottom: 0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'Performa Minggu Ini',
style: AppStyle.h6.copyWith(
fontWeight: FontWeight.w700,
color: AppColor.textPrimary,
letterSpacing: -0.5,
),
),
Container(
padding: const EdgeInsets.symmetric(
horizontal: 12,
vertical: 6,
),
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [
AppColor.success.withOpacity(0.1),
AppColor.success.withOpacity(0.05),
],
),
borderRadius: BorderRadius.circular(20),
border: Border.all(
color: AppColor.success.withOpacity(0.2),
width: 1,
),
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Icon(
Icons.arrow_upward_rounded,
color: AppColor.success,
size: 14,
),
const SpaceWidth(4),
Text(
'89%',
style: AppStyle.sm.copyWith(
color: AppColor.success,
fontSize: 12,
fontWeight: FontWeight.w700,
),
),
],
),
),
],
),
const SpaceHeight(20),
Container(
padding: const EdgeInsets.all(24),
decoration: BoxDecoration(
color: AppColor.white,
borderRadius: BorderRadius.circular(16),
border: Border.all(color: AppColor.border.withOpacity(0.5)),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.04),
blurRadius: 20,
offset: const Offset(0, 8),
),
],
),
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
_buildPerformanceBar(
'Sen',
0.8,
AppColor.primary,
'Rp 2.1M',
),
_buildPerformanceBar(
'Sel',
0.6,
AppColor.primary,
'Rp 1.8M',
),
_buildPerformanceBar(
'Rab',
0.9,
AppColor.success,
'Rp 2.4M',
),
_buildPerformanceBar(
'Kam',
0.7,
AppColor.primary,
'Rp 1.9M',
),
_buildPerformanceBar(
'Jum',
1.0,
AppColor.success,
'Rp 2.5M',
),
_buildPerformanceBar(
'Sab',
0.85,
AppColor.success,
'Rp 2.2M',
),
_buildPerformanceBar(
'Min',
0.4,
AppColor.textLight,
'Rp 1.2M',
),
],
),
const SpaceHeight(24),
Container(
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [
AppColor.primary.withOpacity(0.05),
AppColor.primary.withOpacity(0.02),
],
),
borderRadius: BorderRadius.circular(12),
border: Border.all(
color: AppColor.primary.withOpacity(0.1),
width: 1,
),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Target Minggu Ini',
style: TextStyle(
fontSize: 12,
color: AppColor.textSecondary,
fontWeight: FontWeight.w500,
),
),
const SpaceHeight(4),
Text(
'Rp 15.000.000',
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w700,
color: AppColor.textPrimary,
),
),
],
),
Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Text(
'Tercapai',
style: TextStyle(
fontSize: 12,
color: AppColor.textSecondary,
fontWeight: FontWeight.w500,
),
),
const SpaceHeight(4),
Row(
children: [
Text(
'89%',
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w700,
color: AppColor.success,
),
),
const SpaceWidth(4),
Icon(
Icons.trending_up_rounded,
color: AppColor.success,
size: 16,
),
],
),
],
),
],
),
),
],
),
),
],
),
);
}
Widget _buildPerformanceBar(
String day,
double percentage,
Color color,
String amount,
) {
return Column(
mainAxisSize: MainAxisSize.min,
children: [
// Amount label
Text(
amount,
style: AppStyle.xs.copyWith(
fontSize: 10,
fontWeight: FontWeight.w600,
color: AppColor.textSecondary,
),
),
const SpaceHeight(8),
// Performance bar
Container(
height: 80,
width: 12,
decoration: BoxDecoration(
color: AppColor.border.withOpacity(0.3),
borderRadius: BorderRadius.circular(6),
),
child: Align(
alignment: Alignment.bottomCenter,
child: AnimatedContainer(
duration: Duration(milliseconds: 800 + (day.hashCode % 400)),
curve: Curves.easeOutCubic,
height: 80 * percentage,
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [color, color.withOpacity(0.7)],
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
),
borderRadius: BorderRadius.circular(6),
boxShadow: [
BoxShadow(
color: color.withOpacity(0.3),
blurRadius: 4,
offset: const Offset(0, 2),
),
],
),
),
),
),
const SpaceHeight(12),
// Day label
Text(
day,
style: AppStyle.xs.copyWith(
color: AppColor.textSecondary,
fontWeight: FontWeight.w600,
),
),
],
);
}
}

View File

@ -1,11 +1,15 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:line_icons/line_icons.dart';
import '../../../../common/theme/theme.dart'; import '../../../../common/theme/theme.dart';
import '../../../../domain/analytic/analytic.dart';
import '../../../components/spacer/spacer.dart'; import '../../../components/spacer/spacer.dart';
import 'stats_tile.dart'; import 'stats_tile.dart';
import 'title.dart';
class HomeStats extends StatelessWidget { class HomeStats extends StatelessWidget {
const HomeStats({super.key}); final DashboardOverview overview;
const HomeStats({super.key, required this.overview});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -17,74 +21,30 @@ class HomeStats extends StatelessWidget {
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Row( HomeTitle(title: 'Ringkasan Hari Ini'),
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'Ringkasan Hari Ini',
style: AppStyle.h6.copyWith(
fontWeight: FontWeight.w700,
color: AppColor.textPrimary,
letterSpacing: -0.5,
),
),
Container(
padding: const EdgeInsets.symmetric(
horizontal: 12,
vertical: 6,
),
decoration: BoxDecoration(
color: AppColor.success.withOpacity(0.1),
borderRadius: BorderRadius.circular(20),
border: Border.all(
color: AppColor.success.withOpacity(0.2),
width: 1,
),
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Icon(
Icons.trending_up_rounded,
color: AppColor.success,
size: 14,
),
const SpaceWidth(4),
Text(
'Live',
style: AppStyle.sm.copyWith(
color: AppColor.success,
fontWeight: FontWeight.w600,
),
),
],
),
),
],
),
const SpaceHeight(20), const SpaceHeight(20),
Row( Row(
children: [ children: [
Expanded( Expanded(
child: HomeStatsTile( child: HomeStatsTile(
title: 'Total Penjualan', title: 'Pesanan',
value: 'Rp 2.450.000', value: overview.totalOrders.toString(),
icon: Icons.trending_up_rounded, icon: Icons.receipt_long_rounded,
color: AppColor.success, color: AppColor.info,
change: '+12%', subtitle: 'Hari ini',
subtitle: 'dari kemarin',
), ),
), ),
const SpaceWidth(16), const SpaceWidth(16),
Expanded( Expanded(
child: HomeStatsTile( child: HomeStatsTile(
title: 'Transaksi', title: 'Pelanggan Baru',
value: '85', value: overview.totalCustomers.toString(),
icon: Icons.receipt_long_rounded, icon: Icons.person_add_outlined,
color: AppColor.info, color: AppColor.primary,
change: '+8%', subtitle: overview.totalCustomers < 1
subtitle: 'lebih tinggi', ? 'Hari ini'
: 'bertambah',
), ),
), ),
], ],
@ -94,23 +54,21 @@ class HomeStats extends StatelessWidget {
children: [ children: [
Expanded( Expanded(
child: HomeStatsTile( child: HomeStatsTile(
title: 'Profit Bersih', title: 'Refund',
value: 'Rp 735.000', value: overview.refundedOrders.toString(),
icon: Icons.account_balance_wallet_rounded, icon: LineIcons.alternateExchange,
color: AppColor.warning, color: AppColor.warning,
change: '+15%', subtitle: 'Hari ini',
subtitle: 'margin sehat',
), ),
), ),
const SpaceWidth(16), const SpaceWidth(16),
Expanded( Expanded(
child: HomeStatsTile( child: HomeStatsTile(
title: 'Pelanggan Baru', title: 'Void',
value: '42', value: overview.voidedOrders.toString(),
icon: Icons.person_add_rounded, icon: Icons.cancel_rounded,
color: AppColor.primary, color: AppColor.error,
change: '+3%', subtitle: 'Hari ini',
subtitle: 'bertambah',
), ),
), ),
], ],

View File

@ -8,7 +8,6 @@ class HomeStatsTile extends StatelessWidget {
final String value; final String value;
final IconData icon; final IconData icon;
final Color color; final Color color;
final String change;
final String subtitle; final String subtitle;
const HomeStatsTile({ const HomeStatsTile({
super.key, super.key,
@ -16,7 +15,6 @@ class HomeStatsTile extends StatelessWidget {
required this.value, required this.value,
required this.icon, required this.icon,
required this.color, required this.color,
required this.change,
required this.subtitle, required this.subtitle,
}); });
@ -56,20 +54,6 @@ class HomeStatsTile extends StatelessWidget {
), ),
child: Icon(icon, color: color, size: 20), child: Icon(icon, color: color, size: 20),
), ),
Container(
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
decoration: BoxDecoration(
color: AppColor.success.withOpacity(0.1),
borderRadius: BorderRadius.circular(12),
),
child: Text(
change,
style: AppStyle.xs.copyWith(
color: AppColor.success,
fontWeight: FontWeight.w700,
),
),
),
], ],
), ),
const SpaceHeight(16), const SpaceHeight(16),

View File

@ -0,0 +1,25 @@
import 'package:flutter/material.dart';
import '../../../../common/theme/theme.dart';
class HomeTitle extends StatelessWidget {
final String title;
const HomeTitle({super.key, required this.title});
@override
Widget build(BuildContext context) {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
title,
style: AppStyle.h6.copyWith(
fontWeight: FontWeight.w700,
color: AppColor.textPrimary,
letterSpacing: -0.5,
),
),
],
);
}
}

View File

@ -0,0 +1,39 @@
import 'package:flutter/material.dart';
import '../../../../common/theme/theme.dart';
import '../../../../domain/analytic/analytic.dart';
import '../../../components/spacer/spacer.dart';
import 'title.dart';
import 'top_product_tile.dart';
class HomeTopProduct extends StatelessWidget {
final List<DashboardTopProduct> products;
const HomeTopProduct({super.key, required this.products});
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.symmetric(
vertical: 24,
horizontal: AppValue.padding,
).copyWith(bottom: 0),
child: Column(
children: [
HomeTitle(title: 'Product Terlaris Hari Ini'),
SpaceHeight(20),
ListView.builder(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
itemCount: products.length,
itemBuilder: (context, index) {
return HomeTopProductTile(
product: products[index],
ranking: index + 1,
);
},
),
],
),
);
}
}

View File

@ -0,0 +1,287 @@
import 'package:flutter/material.dart';
import '../../../../common/extension/extension.dart';
import '../../../../common/theme/theme.dart';
import '../../../../domain/analytic/analytic.dart';
class HomeTopProductTile extends StatelessWidget {
final DashboardTopProduct product;
final int ranking;
final VoidCallback? onTap;
const HomeTopProductTile({
super.key,
required this.product,
required this.ranking,
this.onTap,
});
@override
Widget build(BuildContext context) {
return Container(
margin: const EdgeInsets.only(bottom: 12),
child: Material(
elevation: 2,
borderRadius: BorderRadius.circular(16),
shadowColor: AppColor.primary.withOpacity(0.1),
child: InkWell(
onTap: onTap,
borderRadius: BorderRadius.circular(16),
child: Container(
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(16),
gradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: [AppColor.white, AppColor.backgroundLight],
),
border: Border.all(color: AppColor.borderLight, width: 1),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// Header Row - Ranking dan Revenue
Row(
children: [
_buildRankingBadge(),
const Spacer(),
_buildRevenueDisplay(),
],
),
const SizedBox(height: 12),
// Product Name
Text(
product.productName,
style: AppStyle.lg.copyWith(
fontWeight: FontWeight.w600,
color: AppColor.textPrimary,
),
maxLines: 2,
overflow: TextOverflow.ellipsis,
),
const SizedBox(height: 8),
// Category
_buildCategoryChip(),
const SizedBox(height: 12),
// Metrics dalam Grid 2x2
_buildMetricsGrid(),
],
),
),
),
),
);
}
Widget _buildRankingBadge() {
Color badgeColor;
IconData icon;
switch (ranking) {
case 1:
badgeColor = const Color(0xFFFFD700); // Gold
icon = Icons.emoji_events;
break;
case 2:
badgeColor = const Color(0xFFC0C0C0); // Silver
icon = Icons.emoji_events;
break;
case 3:
badgeColor = const Color(0xFFCD7F32); // Bronze
icon = Icons.emoji_events;
break;
default:
badgeColor = AppColor.primary;
icon = Icons.star;
}
return Container(
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
decoration: BoxDecoration(
color: badgeColor.withOpacity(0.1),
borderRadius: BorderRadius.circular(20),
border: Border.all(color: badgeColor.withOpacity(0.3), width: 1.5),
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Icon(icon, color: badgeColor, size: 16),
const SizedBox(width: 6),
Text(
'Rank #$ranking',
style: AppStyle.sm.copyWith(
color: badgeColor,
fontWeight: FontWeight.bold,
),
),
],
),
);
}
Widget _buildCategoryChip() {
return Container(
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 6),
decoration: BoxDecoration(
color: AppColor.secondary.withOpacity(0.1),
borderRadius: BorderRadius.circular(20),
border: Border.all(
color: AppColor.secondary.withOpacity(0.3),
width: 1,
),
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Icon(Icons.category_outlined, size: 14, color: AppColor.secondary),
const SizedBox(width: 6),
Flexible(
child: Text(
product.categoryName,
style: AppStyle.sm.copyWith(
color: AppColor.secondary,
fontWeight: FontWeight.w500,
),
overflow: TextOverflow.ellipsis,
),
),
],
),
);
}
Widget _buildMetricsGrid() {
return Row(
children: [
Expanded(
child: Column(
children: [
_buildMetricCard(
icon: Icons.shopping_cart_outlined,
label: 'Quantity Sold',
value: product.quantitySold.toString(),
color: AppColor.info,
),
const SizedBox(height: 8),
_buildMetricCard(
icon: Icons.attach_money,
label: 'Average Price',
value: product.averagePrice.round().currencyFormatRp,
color: AppColor.success,
),
],
),
),
const SizedBox(width: 8),
Expanded(
child: Column(
children: [
_buildMetricCard(
icon: Icons.receipt_outlined,
label: 'Total Orders',
value: product.orderCount.toString(),
color: AppColor.warning,
),
const SizedBox(height: 8),
_buildMetricCard(
icon: Icons.trending_up,
label: 'Performance',
value: 'Top $ranking',
color: AppColor.primary,
),
],
),
),
],
);
}
Widget _buildMetricCard({
required IconData icon,
required String label,
required String value,
required Color color,
}) {
return Container(
width: double.infinity,
padding: const EdgeInsets.all(12),
decoration: BoxDecoration(
color: color.withOpacity(0.05),
borderRadius: BorderRadius.circular(12),
border: Border.all(color: color.withOpacity(0.2), width: 1),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Icon(icon, size: 16, color: color),
const SizedBox(width: 6),
Expanded(
child: Text(
label,
style: AppStyle.xs.copyWith(
color: AppColor.textSecondary,
fontWeight: FontWeight.w500,
),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
),
],
),
const SizedBox(height: 6),
Text(
value,
style: AppStyle.md.copyWith(
color: color,
fontWeight: FontWeight.bold,
),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
],
),
);
}
Widget _buildRevenueDisplay() {
return Container(
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
decoration: BoxDecoration(
gradient: LinearGradient(
colors: AppColor.primaryGradient,
begin: Alignment.topLeft,
end: Alignment.bottomRight,
),
borderRadius: BorderRadius.circular(20),
boxShadow: [
BoxShadow(
color: AppColor.primary.withOpacity(0.3),
blurRadius: 4,
offset: const Offset(0, 2),
),
],
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Text(
product.revenue.currencyFormatRp,
style: AppStyle.md.copyWith(
color: AppColor.white,
fontWeight: FontWeight.bold,
),
),
],
),
);
}
}

View File

@ -1,7 +1,10 @@
import 'dart:developer';
import 'package:auto_route/auto_route.dart'; import 'package:auto_route/auto_route.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:line_icons/line_icons.dart'; import 'package:line_icons/line_icons.dart';
import 'package:shimmer/shimmer.dart';
import '../../../../application/order/order_loader/order_loader_bloc.dart'; import '../../../../application/order/order_loader/order_loader_bloc.dart';
import '../../../../common/theme/theme.dart'; import '../../../../common/theme/theme.dart';
@ -11,7 +14,7 @@ import '../../../components/button/button.dart';
import '../../../components/spacer/spacer.dart'; import '../../../components/spacer/spacer.dart';
import '../../../components/widgets/empty_widget.dart'; import '../../../components/widgets/empty_widget.dart';
import '../../../router/app_router.gr.dart'; import '../../../router/app_router.gr.dart';
import 'widgets/status_tile.dart'; import 'widgets/filter_header_delegate.dart';
import 'widgets/order_tile.dart'; import 'widgets/order_tile.dart';
@RoutePage() @RoutePage()
@ -38,7 +41,6 @@ class _OrderPageState extends State<OrderPage> with TickerProviderStateMixin {
final ScrollController _scrollController = ScrollController(); final ScrollController _scrollController = ScrollController();
// Filter state // Filter state
String selectedFilter = 'All';
final List<String> filterOptions = ['All', 'Completed', 'Pending']; final List<String> filterOptions = ['All', 'Completed', 'Pending'];
@override @override
@ -75,17 +77,129 @@ class _OrderPageState extends State<OrderPage> with TickerProviderStateMixin {
super.dispose(); super.dispose();
} }
Widget _buildShimmerOrderCard() {
return Shimmer.fromColors(
baseColor: Colors.grey[300]!,
highlightColor: Colors.grey[100]!,
child: Container(
margin: const EdgeInsets.only(bottom: 12),
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(12),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.05),
blurRadius: 10,
offset: const Offset(0, 2),
),
],
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Container(
width: 120,
height: 16,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(4),
),
),
Container(
width: 60,
height: 20,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(10),
),
),
],
),
const SizedBox(height: 8),
Container(
width: double.infinity,
height: 14,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(4),
),
),
const SizedBox(height: 6),
Container(
width: 200,
height: 14,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(4),
),
),
const SizedBox(height: 12),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Container(
width: 80,
height: 14,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(4),
),
),
Container(
width: 100,
height: 16,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(4),
),
),
],
),
],
),
),
);
}
Widget _buildShimmerList() {
return ListView.builder(
itemCount: 5, // Show 5 shimmer cards
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
padding: EdgeInsets.zero,
itemBuilder: (context, index) => _buildShimmerOrderCard(),
);
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
backgroundColor: AppColor.background, backgroundColor: AppColor.background,
body: BlocListener<OrderLoaderBloc, OrderLoaderState>( body: MultiBlocListener(
listeners: [
BlocListener<OrderLoaderBloc, OrderLoaderState>(
listenWhen: (p, c) => p.status != c.status, listenWhen: (p, c) => p.status != c.status,
listener: (context, state) { listener: (context, state) {
context.read<OrderLoaderBloc>().add( context.read<OrderLoaderBloc>().add(
OrderLoaderEvent.fetched(isRefresh: true), OrderLoaderEvent.fetched(isRefresh: true),
); );
}, },
),
BlocListener<OrderLoaderBloc, OrderLoaderState>(
listenWhen: (previous, current) =>
previous.dateFrom != current.dateFrom ||
previous.dateTo != current.dateTo,
listener: (context, state) {
context.read<OrderLoaderBloc>().add(
OrderLoaderEvent.fetched(isRefresh: true),
);
},
),
],
child: BlocBuilder<OrderLoaderBloc, OrderLoaderState>( child: BlocBuilder<OrderLoaderBloc, OrderLoaderState>(
builder: (context, state) { builder: (context, state) {
return NotificationListener<ScrollNotification>( return NotificationListener<ScrollNotification>(
@ -120,60 +234,36 @@ class _OrderPageState extends State<OrderPage> with TickerProviderStateMixin {
// Pinned Filter Section // Pinned Filter Section
SliverPersistentHeader( SliverPersistentHeader(
pinned: true, pinned: true,
delegate: _FilterHeaderDelegate( delegate: FilterHeaderDelegate(
child: Container( backgroundColor: AppColor.background,
color: AppColor.background,
padding: EdgeInsets.fromLTRB( padding: EdgeInsets.fromLTRB(
AppValue.padding, AppValue.padding,
10, 10,
AppValue.padding, AppValue.padding,
10, 10,
), ),
child: Column( startDate: state.dateFrom,
crossAxisAlignment: CrossAxisAlignment.start, endDate: state.dateTo,
children: [ filterOptions: filterOptions,
SingleChildScrollView( selectedFilter: state.status,
scrollDirection: Axis.horizontal, onDateChanged: (startDate, endDate) {
child: Row( if (startDate != null && endDate != null) {
children: filterOptions.map((option) { log('Date changed');
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( context.read<OrderLoaderBloc>().add(
OrderLoaderEvent.statusChanged( OrderLoaderEvent.rangeDateChanged(
'', startDate,
endDate,
), ),
); );
} else {
context.read<OrderLoaderBloc>().add(
OrderLoaderEvent.statusChanged(
option.toLowerCase(),
),
);
}
} }
}, },
), onFilterChanged: (filter) {
final status = filter.toLowerCase();
context.read<OrderLoaderBloc>().add(
OrderLoaderEvent.statusChanged(status),
); );
}).toList(), },
),
),
],
),
),
), ),
), ),
@ -189,13 +279,13 @@ class _OrderPageState extends State<OrderPage> with TickerProviderStateMixin {
child: Column( child: Column(
children: [ children: [
// Show filtered transaction count // Show filtered transaction count
if (selectedFilter != 'All') if (state.status != 'all' && !state.isFetching)
Padding( Padding(
padding: const EdgeInsets.only(bottom: 16), padding: const EdgeInsets.only(bottom: 16),
child: Row( child: Row(
children: [ children: [
Text( Text(
'${state.orders.length} ${selectedFilter.toLowerCase()} order${state.orders.length != 1 ? 's' : ''}', '${state.orders.length} ${state.status.toLowerCase()} order${state.orders.length != 1 ? 's' : ''}',
style: TextStyle( style: TextStyle(
color: AppColor.textSecondary, color: AppColor.textSecondary,
fontSize: 14, fontSize: 14,
@ -205,14 +295,17 @@ class _OrderPageState extends State<OrderPage> with TickerProviderStateMixin {
), ),
), ),
// Transaction List // Order List with Shimmer Loading
state.orders.isEmpty if (state.isFetching)
? EmptyWidget( _buildShimmerList()
else if (state.orders.isEmpty)
EmptyWidget(
title: 'Order', title: 'Order',
message: message:
'No ${selectedFilter.toLowerCase()} orders found', 'No ${state.status.toLowerCase()} orders found',
) )
: ListView.builder( else
ListView.builder(
itemCount: state.orders.length, itemCount: state.orders.length,
shrinkWrap: true, shrinkWrap: true,
physics: physics:
@ -245,30 +338,3 @@ class _OrderPageState extends State<OrderPage> with TickerProviderStateMixin {
); );
} }
} }
// 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;
}
}

View File

@ -0,0 +1,99 @@
import 'package:flutter/material.dart';
import '../../../../components/field/date_range_picker_field.dart';
import 'status_tile.dart';
class FilterHeaderDelegate extends SliverPersistentHeaderDelegate {
final Color backgroundColor;
final EdgeInsets padding;
final DateTime? startDate;
final DateTime? endDate;
final List<String> filterOptions;
final String selectedFilter;
final Function(DateTime?, DateTime?) onDateChanged;
final Function(String) onFilterChanged;
FilterHeaderDelegate({
required this.backgroundColor,
required this.padding,
required this.startDate,
required this.endDate,
required this.filterOptions,
required this.selectedFilter,
required this.onDateChanged,
required this.onFilterChanged,
});
@override
double get minExtent => 130;
@override
double get maxExtent => 130;
@override
Widget build(
BuildContext context,
double shrinkOffset,
bool overlapsContent,
) {
print('FilterHeaderDelegate build called'); // Debug log
return Container(
color: backgroundColor,
padding: padding,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.only(bottom: 8.0),
child: DateRangePickerField(
maxDate: DateTime.now(),
startDate: startDate,
endDate: endDate,
onChanged: (start, end) {
print(
'onChanged called in FilterHeaderDelegate: $start - $end',
); // Debug log
onDateChanged(start, end);
},
),
),
Expanded(
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
children: filterOptions.asMap().entries.map((entry) {
final index = entry.key;
final option = entry.value;
return Padding(
padding: EdgeInsets.only(
right: index < filterOptions.length - 1 ? 8 : 0,
),
child: OrderStatusTile(
label: option,
isSelected: option == selectedFilter,
onSelected: (isSelected) {
if (isSelected) {
onFilterChanged(option);
}
},
),
);
}).toList(),
),
),
),
],
),
);
}
@override
bool shouldRebuild(covariant FilterHeaderDelegate oldDelegate) {
return oldDelegate.startDate != startDate ||
oldDelegate.endDate != endDate ||
oldDelegate.selectedFilter != selectedFilter ||
oldDelegate.filterOptions.length != filterOptions.length ||
oldDelegate.backgroundColor != backgroundColor;
}
}

View File

@ -0,0 +1,403 @@
import 'package:flutter/material.dart';
import 'package:auto_route/auto_route.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import '../../../application/outlet/current_outlet_loader/current_outlet_loader_bloc.dart';
import '../../../common/theme/theme.dart';
import '../../../domain/outlet/outlet.dart';
import '../../../injection.dart';
import '../../components/appbar/appbar.dart';
// Outlet Information Page
@RoutePage()
class OutletInformationPage extends StatefulWidget implements AutoRouteWrapper {
const OutletInformationPage({super.key});
@override
State<OutletInformationPage> createState() => _OutletInformationPageState();
@override
Widget wrappedRoute(BuildContext context) => BlocProvider(
create: (_) =>
getIt<CurrentOutletLoaderBloc>()
..add(CurrentOutletLoaderEvent.fetched()),
child: this,
);
}
class _OutletInformationPageState extends State<OutletInformationPage>
with TickerProviderStateMixin {
late ScrollController _scrollController;
late AnimationController _fadeController;
late AnimationController _slideController;
late Animation<double> _fadeAnimation;
late Animation<Offset> _slideAnimation;
@override
void initState() {
super.initState();
_scrollController = ScrollController();
_fadeController = AnimationController(
duration: const Duration(milliseconds: 800),
vsync: this,
);
_slideController = AnimationController(
duration: const Duration(milliseconds: 600),
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.easeOutBack),
);
// Start animations
_fadeController.forward();
_slideController.forward();
}
@override
void dispose() {
_scrollController.dispose();
_fadeController.dispose();
_slideController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: AppColor.background,
body: CustomScrollView(
controller: _scrollController,
slivers: [
SliverAppBar(
expandedHeight: 120.0,
floating: false,
pinned: true,
flexibleSpace: CustomAppBar(title: 'Outlet Information'),
),
SliverToBoxAdapter(
child: FadeTransition(
opacity: _fadeAnimation,
child: SlideTransition(
position: _slideAnimation,
child: _buildContent(),
),
),
),
],
),
);
}
Widget _buildContent() {
return BlocBuilder<CurrentOutletLoaderBloc, CurrentOutletLoaderState>(
builder: (context, state) {
return Padding(
padding: const EdgeInsets.all(20.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_buildHeaderCard(state.outlet),
const SizedBox(height: 20),
_buildInfoSection(state.outlet),
const SizedBox(height: 20),
_buildContactSection(state.outlet),
const SizedBox(height: 20),
_buildBusinessSection(state.outlet),
const SizedBox(height: 20),
_buildStatusSection(state.outlet),
const SizedBox(height: 20),
_buildTimestampSection(state.outlet),
],
),
);
},
);
}
Widget _buildHeaderCard(Outlet outlet) {
return TweenAnimationBuilder<double>(
duration: const Duration(milliseconds: 800),
tween: Tween(begin: 0.0, end: 1.0),
builder: (context, value, child) {
return Transform.scale(
scale: 0.8 + (0.2 * value),
child: Container(
padding: const EdgeInsets.all(24),
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: AppColor.primaryGradient,
),
borderRadius: BorderRadius.circular(20),
boxShadow: [
BoxShadow(
color: AppColor.primary.withOpacity(0.3),
blurRadius: 20,
offset: const Offset(0, 10),
),
],
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Container(
padding: const EdgeInsets.all(12),
decoration: BoxDecoration(
color: AppColor.white.withOpacity(0.2),
borderRadius: BorderRadius.circular(12),
),
child: Icon(Icons.store, color: AppColor.white, size: 24),
),
const SizedBox(width: 16),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
outlet.name,
style: AppStyle.h5.copyWith(
color: AppColor.white,
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 4),
Text(
outlet.businessType,
style: AppStyle.md.copyWith(
color: AppColor.white.withOpacity(0.9),
),
),
],
),
),
],
),
],
),
),
);
},
);
}
Widget _buildInfoSection(Outlet outlet) {
return _buildAnimatedCard(
delay: 200,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_buildSectionTitle('General Information', Icons.info_outline),
const SizedBox(height: 16),
_buildInfoRow('Outlet ID', outlet.id, Icons.fingerprint),
_buildInfoRow(
'Organization ID',
outlet.organizationId,
Icons.business,
),
_buildInfoRow('Address', outlet.address, Icons.location_on),
],
),
);
}
Widget _buildContactSection(Outlet outlet) {
return _buildAnimatedCard(
delay: 400,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_buildSectionTitle('Contact Information', Icons.contact_phone),
const SizedBox(height: 16),
_buildInfoRow('Phone Number', outlet.phoneNumber, Icons.phone),
],
),
);
}
Widget _buildBusinessSection(Outlet outlet) {
return _buildAnimatedCard(
delay: 600,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_buildSectionTitle('Business Settings', Icons.settings_applications),
const SizedBox(height: 16),
_buildInfoRow('Currency', outlet.currency, Icons.monetization_on),
_buildInfoRow('Tax Rate', '${outlet.taxRate}%', Icons.percent),
],
),
);
}
Widget _buildStatusSection(Outlet outlet) {
return _buildAnimatedCard(
delay: 800,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_buildSectionTitle('Status', Icons.toggle_on),
const SizedBox(height: 16),
Container(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
decoration: BoxDecoration(
color: outlet.isActive
? AppColor.success.withOpacity(0.1)
: AppColor.error.withOpacity(0.1),
borderRadius: BorderRadius.circular(12),
border: Border.all(
color: outlet.isActive
? AppColor.success.withOpacity(0.3)
: AppColor.error.withOpacity(0.3),
),
),
child: Row(
children: [
Container(
width: 8,
height: 8,
decoration: BoxDecoration(
color: outlet.isActive ? AppColor.success : AppColor.error,
shape: BoxShape.circle,
),
),
const SizedBox(width: 12),
Text(
outlet.isActive ? 'Active' : 'Inactive',
style: AppStyle.md.copyWith(
color: outlet.isActive ? AppColor.success : AppColor.error,
fontWeight: FontWeight.w600,
),
),
],
),
),
],
),
);
}
Widget _buildTimestampSection(Outlet outlet) {
return _buildAnimatedCard(
delay: 1000,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_buildSectionTitle('Timestamps', Icons.schedule),
const SizedBox(height: 16),
_buildInfoRow(
'Created At',
_formatDateTime(outlet.createdAt),
Icons.add_circle_outline,
),
_buildInfoRow(
'Updated At',
_formatDateTime(outlet.updatedAt),
Icons.update,
),
],
),
);
}
Widget _buildAnimatedCard({required Widget child, required int delay}) {
return TweenAnimationBuilder<double>(
duration: Duration(milliseconds: 600 + delay),
tween: Tween(begin: 0.0, end: 1.0),
builder: (context, value, _) {
return Transform.translate(
offset: Offset(0, 30 * (1 - value)),
child: Opacity(
opacity: value,
child: Container(
padding: const EdgeInsets.all(20),
decoration: BoxDecoration(
color: AppColor.white,
borderRadius: BorderRadius.circular(16),
boxShadow: [
BoxShadow(
color: AppColor.black.withOpacity(0.05),
blurRadius: 10,
offset: const Offset(0, 5),
),
],
),
child: child,
),
),
);
},
);
}
Widget _buildSectionTitle(String title, IconData icon) {
return Row(
children: [
Container(
padding: const EdgeInsets.all(8),
decoration: BoxDecoration(
color: AppColor.primary.withOpacity(0.1),
borderRadius: BorderRadius.circular(8),
),
child: Icon(icon, color: AppColor.primary, size: 20),
),
const SizedBox(width: 12),
Text(
title,
style: AppStyle.lg.copyWith(
fontWeight: FontWeight.bold,
color: AppColor.textPrimary,
),
),
],
);
}
Widget _buildInfoRow(String label, String value, IconData icon) {
return Padding(
padding: const EdgeInsets.only(bottom: 16),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Icon(icon, color: AppColor.textSecondary, size: 20),
const SizedBox(width: 12),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
label,
style: AppStyle.sm.copyWith(
color: AppColor.textSecondary,
fontWeight: FontWeight.w500,
),
),
const SizedBox(height: 4),
Text(
value,
style: AppStyle.md.copyWith(
color: AppColor.textPrimary,
fontWeight: FontWeight.w600,
),
),
],
),
),
],
),
);
}
String _formatDateTime(DateTime dateTime) {
return '${dateTime.day}/${dateTime.month}/${dateTime.year} ${dateTime.hour.toString().padLeft(2, '0')}:${dateTime.minute.toString().padLeft(2, '0')}';
}
}

View File

@ -43,9 +43,7 @@ class ProfileBusinessSetting extends StatelessWidget {
icon: Icons.business_outlined, icon: Icons.business_outlined,
title: 'Outlet Information', title: 'Outlet Information',
subtitle: 'Manage your Outlet details', subtitle: 'Manage your Outlet details',
onTap: () { onTap: () => context.router.push(OutletInformationRoute()),
// Navigate to business info
},
), ),
ProfileDivider(), ProfileDivider(),
@ -54,20 +52,7 @@ class ProfileBusinessSetting extends StatelessWidget {
icon: Icons.people_outline, icon: Icons.people_outline,
title: 'Staff Management', title: 'Staff Management',
subtitle: 'Manage employees and permissions', subtitle: 'Manage employees and permissions',
onTap: () { onTap: () => context.router.push(ComingSoonRoute()),
// Navigate to staff management
},
),
ProfileDivider(),
ProfileTile(
icon: Icons.payment_outlined,
title: 'Payment Methods',
subtitle: 'Configure payment options',
onTap: () {
// Navigate to payment settings
},
), ),
ProfileDivider(), ProfileDivider(),
@ -78,6 +63,14 @@ class ProfileBusinessSetting extends StatelessWidget {
subtitle: 'Manage your products', subtitle: 'Manage your products',
onTap: () => context.router.push(ProductRoute()), onTap: () => context.router.push(ProductRoute()),
), ),
ProfileDivider(),
ProfileTile(
icon: Icons.download_outlined,
title: 'Download Report',
subtitle: 'Download your sales or inventory report',
onTap: () => context.router.push(DownloadReportRoute()),
),
], ],
), ),
); );

View File

@ -50,10 +50,19 @@ class AppRouter extends RootStackRouter {
// Finance page // Finance page
AutoRoute(page: FinanceRoute.page), AutoRoute(page: FinanceRoute.page),
// Order
AutoRoute(page: OrderDetailRoute.page),
// Outlet
AutoRoute(page: OutletInformationRoute.page),
// Download Report
AutoRoute(page: DownloadReportRoute.page),
// Error // Error
AutoRoute(page: ErrorRoute.page), AutoRoute(page: ErrorRoute.page),
// Order // Coming Soong
AutoRoute(page: OrderDetailRoute.page), AutoRoute(page: ComingSoonRoute.page),
]; ];
} }

View File

@ -9,92 +9,130 @@
// coverage:ignore-file // coverage:ignore-file
// ignore_for_file: no_leading_underscores_for_library_prefixes // ignore_for_file: no_leading_underscores_for_library_prefixes
import 'package:apskel_owner_flutter/domain/order/order.dart' as _i22; import 'package:apskel_owner_flutter/domain/order/order.dart' as _i25;
import 'package:apskel_owner_flutter/presentation/pages/auth/login/login_page.dart' import 'package:apskel_owner_flutter/presentation/pages/auth/login/login_page.dart'
as _i8;
import 'package:apskel_owner_flutter/presentation/pages/customer/customer_page.dart'
as _i1;
import 'package:apskel_owner_flutter/presentation/pages/error/error_page.dart'
as _i3;
import 'package:apskel_owner_flutter/presentation/pages/finance/finance_page.dart'
as _i4;
import 'package:apskel_owner_flutter/presentation/pages/form/daily_task_form_page.dart'
as _i2;
import 'package:apskel_owner_flutter/presentation/pages/home/home_page.dart'
as _i5;
import 'package:apskel_owner_flutter/presentation/pages/inventory/inventory_page.dart'
as _i6;
import 'package:apskel_owner_flutter/presentation/pages/language/language_page.dart'
as _i7;
import 'package:apskel_owner_flutter/presentation/pages/main/main_page.dart'
as _i9;
import 'package:apskel_owner_flutter/presentation/pages/order/order_detail/order_detail_page.dart'
as _i10; as _i10;
import 'package:apskel_owner_flutter/presentation/pages/order/order_list/order_page.dart' import 'package:apskel_owner_flutter/presentation/pages/coming_soon/coming_soon_page.dart'
as _i1;
import 'package:apskel_owner_flutter/presentation/pages/customer/customer_page.dart'
as _i2;
import 'package:apskel_owner_flutter/presentation/pages/download/download_report_page.dart'
as _i4;
import 'package:apskel_owner_flutter/presentation/pages/error/error_page.dart'
as _i5;
import 'package:apskel_owner_flutter/presentation/pages/finance/finance_page.dart'
as _i6;
import 'package:apskel_owner_flutter/presentation/pages/form/daily_task_form_page.dart'
as _i3;
import 'package:apskel_owner_flutter/presentation/pages/home/home_page.dart'
as _i7;
import 'package:apskel_owner_flutter/presentation/pages/inventory/inventory_page.dart'
as _i8;
import 'package:apskel_owner_flutter/presentation/pages/language/language_page.dart'
as _i9;
import 'package:apskel_owner_flutter/presentation/pages/main/main_page.dart'
as _i11; as _i11;
import 'package:apskel_owner_flutter/presentation/pages/product/product_analytic/product_analytic_page.dart' import 'package:apskel_owner_flutter/presentation/pages/order/order_detail/order_detail_page.dart'
as _i12; as _i12;
import 'package:apskel_owner_flutter/presentation/pages/product/product_list/product_page.dart' import 'package:apskel_owner_flutter/presentation/pages/order/order_list/order_page.dart'
as _i13; as _i13;
import 'package:apskel_owner_flutter/presentation/pages/profile/profile_page.dart' import 'package:apskel_owner_flutter/presentation/pages/outlet/outlet_information_page.dart'
as _i14; as _i14;
import 'package:apskel_owner_flutter/presentation/pages/purchase/purchase_page.dart' import 'package:apskel_owner_flutter/presentation/pages/product/product_analytic/product_analytic_page.dart'
as _i15; as _i15;
import 'package:apskel_owner_flutter/presentation/pages/report/report_page.dart' import 'package:apskel_owner_flutter/presentation/pages/product/product_list/product_page.dart'
as _i16; as _i16;
import 'package:apskel_owner_flutter/presentation/pages/sales/sales_page.dart' import 'package:apskel_owner_flutter/presentation/pages/profile/profile_page.dart'
as _i17; as _i17;
import 'package:apskel_owner_flutter/presentation/pages/schedule/schedule_page.dart' import 'package:apskel_owner_flutter/presentation/pages/purchase/purchase_page.dart'
as _i18; as _i18;
import 'package:apskel_owner_flutter/presentation/pages/splash/splash_page.dart' import 'package:apskel_owner_flutter/presentation/pages/report/report_page.dart'
as _i19; as _i19;
import 'package:auto_route/auto_route.dart' as _i20; import 'package:apskel_owner_flutter/presentation/pages/sales/sales_page.dart'
import 'package:flutter/material.dart' as _i21; as _i20;
import 'package:apskel_owner_flutter/presentation/pages/schedule/schedule_page.dart'
as _i21;
import 'package:apskel_owner_flutter/presentation/pages/splash/splash_page.dart'
as _i22;
import 'package:auto_route/auto_route.dart' as _i23;
import 'package:flutter/material.dart' as _i24;
/// generated route for /// generated route for
/// [_i1.CustomerPage] /// [_i1.ComingSoonPage]
class CustomerRoute extends _i20.PageRouteInfo<void> { class ComingSoonRoute extends _i23.PageRouteInfo<void> {
const CustomerRoute({List<_i20.PageRouteInfo>? children}) const ComingSoonRoute({List<_i23.PageRouteInfo>? children})
: super(ComingSoonRoute.name, initialChildren: children);
static const String name = 'ComingSoonRoute';
static _i23.PageInfo page = _i23.PageInfo(
name,
builder: (data) {
return const _i1.ComingSoonPage();
},
);
}
/// generated route for
/// [_i2.CustomerPage]
class CustomerRoute extends _i23.PageRouteInfo<void> {
const CustomerRoute({List<_i23.PageRouteInfo>? children})
: super(CustomerRoute.name, initialChildren: children); : super(CustomerRoute.name, initialChildren: children);
static const String name = 'CustomerRoute'; static const String name = 'CustomerRoute';
static _i20.PageInfo page = _i20.PageInfo( static _i23.PageInfo page = _i23.PageInfo(
name, name,
builder: (data) { builder: (data) {
return _i20.WrappedRoute(child: const _i1.CustomerPage()); return _i23.WrappedRoute(child: const _i2.CustomerPage());
}, },
); );
} }
/// generated route for /// generated route for
/// [_i2.DailyTasksFormPage] /// [_i3.DailyTasksFormPage]
class DailyTasksFormRoute extends _i20.PageRouteInfo<void> { class DailyTasksFormRoute extends _i23.PageRouteInfo<void> {
const DailyTasksFormRoute({List<_i20.PageRouteInfo>? children}) const DailyTasksFormRoute({List<_i23.PageRouteInfo>? children})
: super(DailyTasksFormRoute.name, initialChildren: children); : super(DailyTasksFormRoute.name, initialChildren: children);
static const String name = 'DailyTasksFormRoute'; static const String name = 'DailyTasksFormRoute';
static _i20.PageInfo page = _i20.PageInfo( static _i23.PageInfo page = _i23.PageInfo(
name, name,
builder: (data) { builder: (data) {
return const _i2.DailyTasksFormPage(); return const _i3.DailyTasksFormPage();
}, },
); );
} }
/// generated route for /// generated route for
/// [_i3.ErrorPage] /// [_i4.DownloadReportPage]
class ErrorRoute extends _i20.PageRouteInfo<ErrorRouteArgs> { class DownloadReportRoute extends _i23.PageRouteInfo<void> {
const DownloadReportRoute({List<_i23.PageRouteInfo>? children})
: super(DownloadReportRoute.name, initialChildren: children);
static const String name = 'DownloadReportRoute';
static _i23.PageInfo page = _i23.PageInfo(
name,
builder: (data) {
return const _i4.DownloadReportPage();
},
);
}
/// generated route for
/// [_i5.ErrorPage]
class ErrorRoute extends _i23.PageRouteInfo<ErrorRouteArgs> {
ErrorRoute({ ErrorRoute({
_i21.Key? key, _i24.Key? key,
String? title, String? title,
String? message, String? message,
_i21.VoidCallback? onRetry, _i24.VoidCallback? onRetry,
_i21.VoidCallback? onBack, _i24.VoidCallback? onBack,
String? errorCode, String? errorCode,
_i21.IconData? errorIcon, _i24.IconData? errorIcon,
List<_i20.PageRouteInfo>? children, List<_i23.PageRouteInfo>? children,
}) : super( }) : super(
ErrorRoute.name, ErrorRoute.name,
args: ErrorRouteArgs( args: ErrorRouteArgs(
@ -111,13 +149,13 @@ class ErrorRoute extends _i20.PageRouteInfo<ErrorRouteArgs> {
static const String name = 'ErrorRoute'; static const String name = 'ErrorRoute';
static _i20.PageInfo page = _i20.PageInfo( static _i23.PageInfo page = _i23.PageInfo(
name, name,
builder: (data) { builder: (data) {
final args = data.argsAs<ErrorRouteArgs>( final args = data.argsAs<ErrorRouteArgs>(
orElse: () => const ErrorRouteArgs(), orElse: () => const ErrorRouteArgs(),
); );
return _i3.ErrorPage( return _i5.ErrorPage(
key: args.key, key: args.key,
title: args.title, title: args.title,
message: args.message, message: args.message,
@ -141,19 +179,19 @@ class ErrorRouteArgs {
this.errorIcon, this.errorIcon,
}); });
final _i21.Key? key; final _i24.Key? key;
final String? title; final String? title;
final String? message; final String? message;
final _i21.VoidCallback? onRetry; final _i24.VoidCallback? onRetry;
final _i21.VoidCallback? onBack; final _i24.VoidCallback? onBack;
final String? errorCode; final String? errorCode;
final _i21.IconData? errorIcon; final _i24.IconData? errorIcon;
@override @override
String toString() { String toString() {
@ -162,108 +200,108 @@ class ErrorRouteArgs {
} }
/// generated route for /// generated route for
/// [_i4.FinancePage] /// [_i6.FinancePage]
class FinanceRoute extends _i20.PageRouteInfo<void> { class FinanceRoute extends _i23.PageRouteInfo<void> {
const FinanceRoute({List<_i20.PageRouteInfo>? children}) const FinanceRoute({List<_i23.PageRouteInfo>? children})
: super(FinanceRoute.name, initialChildren: children); : super(FinanceRoute.name, initialChildren: children);
static const String name = 'FinanceRoute'; static const String name = 'FinanceRoute';
static _i20.PageInfo page = _i20.PageInfo( static _i23.PageInfo page = _i23.PageInfo(
name, name,
builder: (data) { builder: (data) {
return _i20.WrappedRoute(child: const _i4.FinancePage()); return _i23.WrappedRoute(child: const _i6.FinancePage());
}, },
); );
} }
/// generated route for /// generated route for
/// [_i5.HomePage] /// [_i7.HomePage]
class HomeRoute extends _i20.PageRouteInfo<void> { class HomeRoute extends _i23.PageRouteInfo<void> {
const HomeRoute({List<_i20.PageRouteInfo>? children}) const HomeRoute({List<_i23.PageRouteInfo>? children})
: super(HomeRoute.name, initialChildren: children); : super(HomeRoute.name, initialChildren: children);
static const String name = 'HomeRoute'; static const String name = 'HomeRoute';
static _i20.PageInfo page = _i20.PageInfo( static _i23.PageInfo page = _i23.PageInfo(
name, name,
builder: (data) { builder: (data) {
return const _i5.HomePage(); return _i23.WrappedRoute(child: const _i7.HomePage());
}, },
); );
} }
/// generated route for /// generated route for
/// [_i6.InventoryPage] /// [_i8.InventoryPage]
class InventoryRoute extends _i20.PageRouteInfo<void> { class InventoryRoute extends _i23.PageRouteInfo<void> {
const InventoryRoute({List<_i20.PageRouteInfo>? children}) const InventoryRoute({List<_i23.PageRouteInfo>? children})
: super(InventoryRoute.name, initialChildren: children); : super(InventoryRoute.name, initialChildren: children);
static const String name = 'InventoryRoute'; static const String name = 'InventoryRoute';
static _i20.PageInfo page = _i20.PageInfo( static _i23.PageInfo page = _i23.PageInfo(
name, name,
builder: (data) { builder: (data) {
return _i20.WrappedRoute(child: const _i6.InventoryPage()); return _i23.WrappedRoute(child: const _i8.InventoryPage());
}, },
); );
} }
/// generated route for /// generated route for
/// [_i7.LanguagePage] /// [_i9.LanguagePage]
class LanguageRoute extends _i20.PageRouteInfo<void> { class LanguageRoute extends _i23.PageRouteInfo<void> {
const LanguageRoute({List<_i20.PageRouteInfo>? children}) const LanguageRoute({List<_i23.PageRouteInfo>? children})
: super(LanguageRoute.name, initialChildren: children); : super(LanguageRoute.name, initialChildren: children);
static const String name = 'LanguageRoute'; static const String name = 'LanguageRoute';
static _i20.PageInfo page = _i20.PageInfo( static _i23.PageInfo page = _i23.PageInfo(
name, name,
builder: (data) { builder: (data) {
return const _i7.LanguagePage(); return const _i9.LanguagePage();
}, },
); );
} }
/// generated route for /// generated route for
/// [_i8.LoginPage] /// [_i10.LoginPage]
class LoginRoute extends _i20.PageRouteInfo<void> { class LoginRoute extends _i23.PageRouteInfo<void> {
const LoginRoute({List<_i20.PageRouteInfo>? children}) const LoginRoute({List<_i23.PageRouteInfo>? children})
: super(LoginRoute.name, initialChildren: children); : super(LoginRoute.name, initialChildren: children);
static const String name = 'LoginRoute'; static const String name = 'LoginRoute';
static _i20.PageInfo page = _i20.PageInfo( static _i23.PageInfo page = _i23.PageInfo(
name, name,
builder: (data) { builder: (data) {
return _i20.WrappedRoute(child: const _i8.LoginPage()); return _i23.WrappedRoute(child: const _i10.LoginPage());
}, },
); );
} }
/// generated route for /// generated route for
/// [_i9.MainPage] /// [_i11.MainPage]
class MainRoute extends _i20.PageRouteInfo<void> { class MainRoute extends _i23.PageRouteInfo<void> {
const MainRoute({List<_i20.PageRouteInfo>? children}) const MainRoute({List<_i23.PageRouteInfo>? children})
: super(MainRoute.name, initialChildren: children); : super(MainRoute.name, initialChildren: children);
static const String name = 'MainRoute'; static const String name = 'MainRoute';
static _i20.PageInfo page = _i20.PageInfo( static _i23.PageInfo page = _i23.PageInfo(
name, name,
builder: (data) { builder: (data) {
return const _i9.MainPage(); return const _i11.MainPage();
}, },
); );
} }
/// generated route for /// generated route for
/// [_i10.OrderDetailPage] /// [_i12.OrderDetailPage]
class OrderDetailRoute extends _i20.PageRouteInfo<OrderDetailRouteArgs> { class OrderDetailRoute extends _i23.PageRouteInfo<OrderDetailRouteArgs> {
OrderDetailRoute({ OrderDetailRoute({
_i21.Key? key, _i24.Key? key,
required _i22.Order order, required _i25.Order order,
List<_i20.PageRouteInfo>? children, List<_i23.PageRouteInfo>? children,
}) : super( }) : super(
OrderDetailRoute.name, OrderDetailRoute.name,
args: OrderDetailRouteArgs(key: key, order: order), args: OrderDetailRouteArgs(key: key, order: order),
@ -272,11 +310,11 @@ class OrderDetailRoute extends _i20.PageRouteInfo<OrderDetailRouteArgs> {
static const String name = 'OrderDetailRoute'; static const String name = 'OrderDetailRoute';
static _i20.PageInfo page = _i20.PageInfo( static _i23.PageInfo page = _i23.PageInfo(
name, name,
builder: (data) { builder: (data) {
final args = data.argsAs<OrderDetailRouteArgs>(); final args = data.argsAs<OrderDetailRouteArgs>();
return _i10.OrderDetailPage(key: args.key, order: args.order); return _i12.OrderDetailPage(key: args.key, order: args.order);
}, },
); );
} }
@ -284,9 +322,9 @@ class OrderDetailRoute extends _i20.PageRouteInfo<OrderDetailRouteArgs> {
class OrderDetailRouteArgs { class OrderDetailRouteArgs {
const OrderDetailRouteArgs({this.key, required this.order}); const OrderDetailRouteArgs({this.key, required this.order});
final _i21.Key? key; final _i24.Key? key;
final _i22.Order order; final _i25.Order order;
@override @override
String toString() { String toString() {
@ -295,145 +333,161 @@ class OrderDetailRouteArgs {
} }
/// generated route for /// generated route for
/// [_i11.OrderPage] /// [_i13.OrderPage]
class OrderRoute extends _i20.PageRouteInfo<void> { class OrderRoute extends _i23.PageRouteInfo<void> {
const OrderRoute({List<_i20.PageRouteInfo>? children}) const OrderRoute({List<_i23.PageRouteInfo>? children})
: super(OrderRoute.name, initialChildren: children); : super(OrderRoute.name, initialChildren: children);
static const String name = 'OrderRoute'; static const String name = 'OrderRoute';
static _i20.PageInfo page = _i20.PageInfo( static _i23.PageInfo page = _i23.PageInfo(
name, name,
builder: (data) { builder: (data) {
return _i20.WrappedRoute(child: const _i11.OrderPage()); return _i23.WrappedRoute(child: const _i13.OrderPage());
}, },
); );
} }
/// generated route for /// generated route for
/// [_i12.ProductAnalyticPage] /// [_i14.OutletInformationPage]
class ProductAnalyticRoute extends _i20.PageRouteInfo<void> { class OutletInformationRoute extends _i23.PageRouteInfo<void> {
const ProductAnalyticRoute({List<_i20.PageRouteInfo>? children}) const OutletInformationRoute({List<_i23.PageRouteInfo>? children})
: super(OutletInformationRoute.name, initialChildren: children);
static const String name = 'OutletInformationRoute';
static _i23.PageInfo page = _i23.PageInfo(
name,
builder: (data) {
return _i23.WrappedRoute(child: const _i14.OutletInformationPage());
},
);
}
/// generated route for
/// [_i15.ProductAnalyticPage]
class ProductAnalyticRoute extends _i23.PageRouteInfo<void> {
const ProductAnalyticRoute({List<_i23.PageRouteInfo>? children})
: super(ProductAnalyticRoute.name, initialChildren: children); : super(ProductAnalyticRoute.name, initialChildren: children);
static const String name = 'ProductAnalyticRoute'; static const String name = 'ProductAnalyticRoute';
static _i20.PageInfo page = _i20.PageInfo( static _i23.PageInfo page = _i23.PageInfo(
name, name,
builder: (data) { builder: (data) {
return _i20.WrappedRoute(child: const _i12.ProductAnalyticPage()); return _i23.WrappedRoute(child: const _i15.ProductAnalyticPage());
}, },
); );
} }
/// generated route for /// generated route for
/// [_i13.ProductPage] /// [_i16.ProductPage]
class ProductRoute extends _i20.PageRouteInfo<void> { class ProductRoute extends _i23.PageRouteInfo<void> {
const ProductRoute({List<_i20.PageRouteInfo>? children}) const ProductRoute({List<_i23.PageRouteInfo>? children})
: super(ProductRoute.name, initialChildren: children); : super(ProductRoute.name, initialChildren: children);
static const String name = 'ProductRoute'; static const String name = 'ProductRoute';
static _i20.PageInfo page = _i20.PageInfo( static _i23.PageInfo page = _i23.PageInfo(
name, name,
builder: (data) { builder: (data) {
return _i20.WrappedRoute(child: const _i13.ProductPage()); return _i23.WrappedRoute(child: const _i16.ProductPage());
}, },
); );
} }
/// generated route for /// generated route for
/// [_i14.ProfilePage] /// [_i17.ProfilePage]
class ProfileRoute extends _i20.PageRouteInfo<void> { class ProfileRoute extends _i23.PageRouteInfo<void> {
const ProfileRoute({List<_i20.PageRouteInfo>? children}) const ProfileRoute({List<_i23.PageRouteInfo>? children})
: super(ProfileRoute.name, initialChildren: children); : super(ProfileRoute.name, initialChildren: children);
static const String name = 'ProfileRoute'; static const String name = 'ProfileRoute';
static _i20.PageInfo page = _i20.PageInfo( static _i23.PageInfo page = _i23.PageInfo(
name, name,
builder: (data) { builder: (data) {
return _i20.WrappedRoute(child: const _i14.ProfilePage()); return _i23.WrappedRoute(child: const _i17.ProfilePage());
}, },
); );
} }
/// generated route for /// generated route for
/// [_i15.PurchasePage] /// [_i18.PurchasePage]
class PurchaseRoute extends _i20.PageRouteInfo<void> { class PurchaseRoute extends _i23.PageRouteInfo<void> {
const PurchaseRoute({List<_i20.PageRouteInfo>? children}) const PurchaseRoute({List<_i23.PageRouteInfo>? children})
: super(PurchaseRoute.name, initialChildren: children); : super(PurchaseRoute.name, initialChildren: children);
static const String name = 'PurchaseRoute'; static const String name = 'PurchaseRoute';
static _i20.PageInfo page = _i20.PageInfo( static _i23.PageInfo page = _i23.PageInfo(
name, name,
builder: (data) { builder: (data) {
return const _i15.PurchasePage(); return const _i18.PurchasePage();
}, },
); );
} }
/// generated route for /// generated route for
/// [_i16.ReportPage] /// [_i19.ReportPage]
class ReportRoute extends _i20.PageRouteInfo<void> { class ReportRoute extends _i23.PageRouteInfo<void> {
const ReportRoute({List<_i20.PageRouteInfo>? children}) const ReportRoute({List<_i23.PageRouteInfo>? children})
: super(ReportRoute.name, initialChildren: children); : super(ReportRoute.name, initialChildren: children);
static const String name = 'ReportRoute'; static const String name = 'ReportRoute';
static _i20.PageInfo page = _i20.PageInfo( static _i23.PageInfo page = _i23.PageInfo(
name, name,
builder: (data) { builder: (data) {
return _i20.WrappedRoute(child: const _i16.ReportPage()); return _i23.WrappedRoute(child: const _i19.ReportPage());
}, },
); );
} }
/// generated route for /// generated route for
/// [_i17.SalesPage] /// [_i20.SalesPage]
class SalesRoute extends _i20.PageRouteInfo<void> { class SalesRoute extends _i23.PageRouteInfo<void> {
const SalesRoute({List<_i20.PageRouteInfo>? children}) const SalesRoute({List<_i23.PageRouteInfo>? children})
: super(SalesRoute.name, initialChildren: children); : super(SalesRoute.name, initialChildren: children);
static const String name = 'SalesRoute'; static const String name = 'SalesRoute';
static _i20.PageInfo page = _i20.PageInfo( static _i23.PageInfo page = _i23.PageInfo(
name, name,
builder: (data) { builder: (data) {
return _i20.WrappedRoute(child: const _i17.SalesPage()); return _i23.WrappedRoute(child: const _i20.SalesPage());
}, },
); );
} }
/// generated route for /// generated route for
/// [_i18.SchedulePage] /// [_i21.SchedulePage]
class ScheduleRoute extends _i20.PageRouteInfo<void> { class ScheduleRoute extends _i23.PageRouteInfo<void> {
const ScheduleRoute({List<_i20.PageRouteInfo>? children}) const ScheduleRoute({List<_i23.PageRouteInfo>? children})
: super(ScheduleRoute.name, initialChildren: children); : super(ScheduleRoute.name, initialChildren: children);
static const String name = 'ScheduleRoute'; static const String name = 'ScheduleRoute';
static _i20.PageInfo page = _i20.PageInfo( static _i23.PageInfo page = _i23.PageInfo(
name, name,
builder: (data) { builder: (data) {
return const _i18.SchedulePage(); return const _i21.SchedulePage();
}, },
); );
} }
/// generated route for /// generated route for
/// [_i19.SplashPage] /// [_i22.SplashPage]
class SplashRoute extends _i20.PageRouteInfo<void> { class SplashRoute extends _i23.PageRouteInfo<void> {
const SplashRoute({List<_i20.PageRouteInfo>? children}) const SplashRoute({List<_i23.PageRouteInfo>? children})
: super(SplashRoute.name, initialChildren: children); : super(SplashRoute.name, initialChildren: children);
static const String name = 'SplashRoute'; static const String name = 'SplashRoute';
static _i20.PageInfo page = _i20.PageInfo( static _i23.PageInfo page = _i23.PageInfo(
name, name,
builder: (data) { builder: (data) {
return const _i19.SplashPage(); return const _i22.SplashPage();
}, },
); );
} }