Compare commits

..

6 Commits

Author SHA1 Message Date
efrilm
f07d07b3a8 feat: transaction report 2025-08-19 17:39:00 +07:00
efrilm
1aa65d1732 feat: inventory report 2025-08-19 17:05:55 +07:00
efrilm
50934bfed9 feat: about app 2025-08-19 16:05:42 +07:00
efrilm
838707becf fix: bloc 2025-08-19 15:36:34 +07:00
efrilm
1b1e8c5bb4 feat: change password 2025-08-19 15:35:18 +07:00
efrilm
7919825955 feat: update user 2025-08-19 15:05:08 +07:00
69 changed files with 7877 additions and 1119 deletions

View File

@ -1,5 +1,10 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES"/>
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO"/>
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO"/>
<application
android:label="Apskel Owner"

View File

@ -1,9 +1,10 @@
import 'package:bloc/bloc.dart';
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/auth/auth.dart';
import '../../domain/user/user.dart';
part 'auth_event.dart';
part 'auth_state.dart';

View File

@ -23,10 +23,10 @@ class LoginFormBloc extends Bloc<LoginFormEvent, LoginFormState> {
) {
return event.map(
emailChanged: (e) async {
emit(state.copyWith(email: e.email));
emit(state.copyWith(email: e.email, failureOrAuthOption: none()));
},
passwordChanged: (e) async {
emit(state.copyWith(password: e.password));
emit(state.copyWith(password: e.password, failureOrAuthOption: none()));
},
submitted: (e) async {
Either<AuthFailure, Auth>? failureOrAuth;

View File

@ -0,0 +1,66 @@
import 'package:bloc/bloc.dart';
import 'package:dartz/dartz.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:injectable/injectable.dart';
import '../../../domain/analytic/analytic.dart';
import '../../../domain/analytic/repositories/i_analytic_repository.dart';
import '../../../domain/outlet/outlet.dart';
part 'inventory_report_event.dart';
part 'inventory_report_state.dart';
part 'inventory_report_bloc.freezed.dart';
@injectable
class InventoryReportBloc
extends Bloc<InventoryReportEvent, InventoryReportState> {
final IAnalyticRepository _analyticRepository;
final IOutletRepository _outletRepository;
InventoryReportBloc(this._analyticRepository, this._outletRepository)
: super(InventoryReportState.initial()) {
on<InventoryReportEvent>(_onInventoryReportEvent);
}
Future<void> _onInventoryReportEvent(
InventoryReportEvent event,
Emitter<InventoryReportState> emit,
) {
return event.map(
fetchedOutlet: (e) async {
emit(
state.copyWith(isFetchingOutlet: true, failureOptionOutlet: none()),
);
final result = await _outletRepository.currentOutlet();
var data = result.fold(
(f) => state.copyWith(failureOptionOutlet: optionOf(f)),
(currentOutlet) => state.copyWith(outlet: currentOutlet),
);
emit(data.copyWith(isFetchingOutlet: false));
},
fetchedInventory: (e) async {
emit(
state.copyWith(
isFetching: true,
failureOptionInventoryAnalytic: none(),
),
);
final result = await _analyticRepository.getInventory(
dateFrom: e.dateFrom,
dateTo: e.dateTo,
);
var data = result.fold(
(f) => state.copyWith(failureOptionInventoryAnalytic: optionOf(f)),
(inventoryAnalytic) =>
state.copyWith(inventoryAnalytic: inventoryAnalytic),
);
emit(data.copyWith(isFetching: false));
},
);
}
}

View File

@ -0,0 +1,645 @@
// 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 'inventory_report_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 _$InventoryReportEvent {
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function() fetchedOutlet,
required TResult Function(DateTime dateFrom, DateTime dateTo)
fetchedInventory,
}) => throw _privateConstructorUsedError;
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>({
TResult? Function()? fetchedOutlet,
TResult? Function(DateTime dateFrom, DateTime dateTo)? fetchedInventory,
}) => throw _privateConstructorUsedError;
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({
TResult Function()? fetchedOutlet,
TResult Function(DateTime dateFrom, DateTime dateTo)? fetchedInventory,
required TResult orElse(),
}) => throw _privateConstructorUsedError;
@optionalTypeArgs
TResult map<TResult extends Object?>({
required TResult Function(_FetchedOutlet value) fetchedOutlet,
required TResult Function(_FetchedInventory value) fetchedInventory,
}) => throw _privateConstructorUsedError;
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>({
TResult? Function(_FetchedOutlet value)? fetchedOutlet,
TResult? Function(_FetchedInventory value)? fetchedInventory,
}) => throw _privateConstructorUsedError;
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>({
TResult Function(_FetchedOutlet value)? fetchedOutlet,
TResult Function(_FetchedInventory value)? fetchedInventory,
required TResult orElse(),
}) => throw _privateConstructorUsedError;
}
/// @nodoc
abstract class $InventoryReportEventCopyWith<$Res> {
factory $InventoryReportEventCopyWith(
InventoryReportEvent value,
$Res Function(InventoryReportEvent) then,
) = _$InventoryReportEventCopyWithImpl<$Res, InventoryReportEvent>;
}
/// @nodoc
class _$InventoryReportEventCopyWithImpl<
$Res,
$Val extends InventoryReportEvent
>
implements $InventoryReportEventCopyWith<$Res> {
_$InventoryReportEventCopyWithImpl(this._value, this._then);
// ignore: unused_field
final $Val _value;
// ignore: unused_field
final $Res Function($Val) _then;
/// Create a copy of InventoryReportEvent
/// with the given fields replaced by the non-null parameter values.
}
/// @nodoc
abstract class _$$FetchedOutletImplCopyWith<$Res> {
factory _$$FetchedOutletImplCopyWith(
_$FetchedOutletImpl value,
$Res Function(_$FetchedOutletImpl) then,
) = __$$FetchedOutletImplCopyWithImpl<$Res>;
}
/// @nodoc
class __$$FetchedOutletImplCopyWithImpl<$Res>
extends _$InventoryReportEventCopyWithImpl<$Res, _$FetchedOutletImpl>
implements _$$FetchedOutletImplCopyWith<$Res> {
__$$FetchedOutletImplCopyWithImpl(
_$FetchedOutletImpl _value,
$Res Function(_$FetchedOutletImpl) _then,
) : super(_value, _then);
/// Create a copy of InventoryReportEvent
/// with the given fields replaced by the non-null parameter values.
}
/// @nodoc
class _$FetchedOutletImpl implements _FetchedOutlet {
const _$FetchedOutletImpl();
@override
String toString() {
return 'InventoryReportEvent.fetchedOutlet()';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType && other is _$FetchedOutletImpl);
}
@override
int get hashCode => runtimeType.hashCode;
@override
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function() fetchedOutlet,
required TResult Function(DateTime dateFrom, DateTime dateTo)
fetchedInventory,
}) {
return fetchedOutlet();
}
@override
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>({
TResult? Function()? fetchedOutlet,
TResult? Function(DateTime dateFrom, DateTime dateTo)? fetchedInventory,
}) {
return fetchedOutlet?.call();
}
@override
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({
TResult Function()? fetchedOutlet,
TResult Function(DateTime dateFrom, DateTime dateTo)? fetchedInventory,
required TResult orElse(),
}) {
if (fetchedOutlet != null) {
return fetchedOutlet();
}
return orElse();
}
@override
@optionalTypeArgs
TResult map<TResult extends Object?>({
required TResult Function(_FetchedOutlet value) fetchedOutlet,
required TResult Function(_FetchedInventory value) fetchedInventory,
}) {
return fetchedOutlet(this);
}
@override
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>({
TResult? Function(_FetchedOutlet value)? fetchedOutlet,
TResult? Function(_FetchedInventory value)? fetchedInventory,
}) {
return fetchedOutlet?.call(this);
}
@override
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>({
TResult Function(_FetchedOutlet value)? fetchedOutlet,
TResult Function(_FetchedInventory value)? fetchedInventory,
required TResult orElse(),
}) {
if (fetchedOutlet != null) {
return fetchedOutlet(this);
}
return orElse();
}
}
abstract class _FetchedOutlet implements InventoryReportEvent {
const factory _FetchedOutlet() = _$FetchedOutletImpl;
}
/// @nodoc
abstract class _$$FetchedInventoryImplCopyWith<$Res> {
factory _$$FetchedInventoryImplCopyWith(
_$FetchedInventoryImpl value,
$Res Function(_$FetchedInventoryImpl) then,
) = __$$FetchedInventoryImplCopyWithImpl<$Res>;
@useResult
$Res call({DateTime dateFrom, DateTime dateTo});
}
/// @nodoc
class __$$FetchedInventoryImplCopyWithImpl<$Res>
extends _$InventoryReportEventCopyWithImpl<$Res, _$FetchedInventoryImpl>
implements _$$FetchedInventoryImplCopyWith<$Res> {
__$$FetchedInventoryImplCopyWithImpl(
_$FetchedInventoryImpl _value,
$Res Function(_$FetchedInventoryImpl) _then,
) : super(_value, _then);
/// Create a copy of InventoryReportEvent
/// 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(
_$FetchedInventoryImpl(
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 _$FetchedInventoryImpl implements _FetchedInventory {
const _$FetchedInventoryImpl(this.dateFrom, this.dateTo);
@override
final DateTime dateFrom;
@override
final DateTime dateTo;
@override
String toString() {
return 'InventoryReportEvent.fetchedInventory(dateFrom: $dateFrom, dateTo: $dateTo)';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType &&
other is _$FetchedInventoryImpl &&
(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 InventoryReportEvent
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@override
@pragma('vm:prefer-inline')
_$$FetchedInventoryImplCopyWith<_$FetchedInventoryImpl> get copyWith =>
__$$FetchedInventoryImplCopyWithImpl<_$FetchedInventoryImpl>(
this,
_$identity,
);
@override
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function() fetchedOutlet,
required TResult Function(DateTime dateFrom, DateTime dateTo)
fetchedInventory,
}) {
return fetchedInventory(dateFrom, dateTo);
}
@override
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>({
TResult? Function()? fetchedOutlet,
TResult? Function(DateTime dateFrom, DateTime dateTo)? fetchedInventory,
}) {
return fetchedInventory?.call(dateFrom, dateTo);
}
@override
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({
TResult Function()? fetchedOutlet,
TResult Function(DateTime dateFrom, DateTime dateTo)? fetchedInventory,
required TResult orElse(),
}) {
if (fetchedInventory != null) {
return fetchedInventory(dateFrom, dateTo);
}
return orElse();
}
@override
@optionalTypeArgs
TResult map<TResult extends Object?>({
required TResult Function(_FetchedOutlet value) fetchedOutlet,
required TResult Function(_FetchedInventory value) fetchedInventory,
}) {
return fetchedInventory(this);
}
@override
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>({
TResult? Function(_FetchedOutlet value)? fetchedOutlet,
TResult? Function(_FetchedInventory value)? fetchedInventory,
}) {
return fetchedInventory?.call(this);
}
@override
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>({
TResult Function(_FetchedOutlet value)? fetchedOutlet,
TResult Function(_FetchedInventory value)? fetchedInventory,
required TResult orElse(),
}) {
if (fetchedInventory != null) {
return fetchedInventory(this);
}
return orElse();
}
}
abstract class _FetchedInventory implements InventoryReportEvent {
const factory _FetchedInventory(
final DateTime dateFrom,
final DateTime dateTo,
) = _$FetchedInventoryImpl;
DateTime get dateFrom;
DateTime get dateTo;
/// Create a copy of InventoryReportEvent
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
_$$FetchedInventoryImplCopyWith<_$FetchedInventoryImpl> get copyWith =>
throw _privateConstructorUsedError;
}
/// @nodoc
mixin _$InventoryReportState {
InventoryAnalytic get inventoryAnalytic => throw _privateConstructorUsedError;
Option<AnalyticFailure> get failureOptionInventoryAnalytic =>
throw _privateConstructorUsedError;
Outlet get outlet => throw _privateConstructorUsedError;
Option<OutletFailure> get failureOptionOutlet =>
throw _privateConstructorUsedError;
bool get isFetching => throw _privateConstructorUsedError;
bool get isFetchingOutlet => throw _privateConstructorUsedError;
/// Create a copy of InventoryReportState
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
$InventoryReportStateCopyWith<InventoryReportState> get copyWith =>
throw _privateConstructorUsedError;
}
/// @nodoc
abstract class $InventoryReportStateCopyWith<$Res> {
factory $InventoryReportStateCopyWith(
InventoryReportState value,
$Res Function(InventoryReportState) then,
) = _$InventoryReportStateCopyWithImpl<$Res, InventoryReportState>;
@useResult
$Res call({
InventoryAnalytic inventoryAnalytic,
Option<AnalyticFailure> failureOptionInventoryAnalytic,
Outlet outlet,
Option<OutletFailure> failureOptionOutlet,
bool isFetching,
bool isFetchingOutlet,
});
$InventoryAnalyticCopyWith<$Res> get inventoryAnalytic;
$OutletCopyWith<$Res> get outlet;
}
/// @nodoc
class _$InventoryReportStateCopyWithImpl<
$Res,
$Val extends InventoryReportState
>
implements $InventoryReportStateCopyWith<$Res> {
_$InventoryReportStateCopyWithImpl(this._value, this._then);
// ignore: unused_field
final $Val _value;
// ignore: unused_field
final $Res Function($Val) _then;
/// Create a copy of InventoryReportState
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({
Object? inventoryAnalytic = null,
Object? failureOptionInventoryAnalytic = null,
Object? outlet = null,
Object? failureOptionOutlet = null,
Object? isFetching = null,
Object? isFetchingOutlet = null,
}) {
return _then(
_value.copyWith(
inventoryAnalytic: null == inventoryAnalytic
? _value.inventoryAnalytic
: inventoryAnalytic // ignore: cast_nullable_to_non_nullable
as InventoryAnalytic,
failureOptionInventoryAnalytic:
null == failureOptionInventoryAnalytic
? _value.failureOptionInventoryAnalytic
: failureOptionInventoryAnalytic // ignore: cast_nullable_to_non_nullable
as Option<AnalyticFailure>,
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,
isFetchingOutlet: null == isFetchingOutlet
? _value.isFetchingOutlet
: isFetchingOutlet // ignore: cast_nullable_to_non_nullable
as bool,
)
as $Val,
);
}
/// Create a copy of InventoryReportState
/// with the given fields replaced by the non-null parameter values.
@override
@pragma('vm:prefer-inline')
$InventoryAnalyticCopyWith<$Res> get inventoryAnalytic {
return $InventoryAnalyticCopyWith<$Res>(_value.inventoryAnalytic, (value) {
return _then(_value.copyWith(inventoryAnalytic: value) as $Val);
});
}
/// Create a copy of InventoryReportState
/// 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 _$$InventoryReportStateImplCopyWith<$Res>
implements $InventoryReportStateCopyWith<$Res> {
factory _$$InventoryReportStateImplCopyWith(
_$InventoryReportStateImpl value,
$Res Function(_$InventoryReportStateImpl) then,
) = __$$InventoryReportStateImplCopyWithImpl<$Res>;
@override
@useResult
$Res call({
InventoryAnalytic inventoryAnalytic,
Option<AnalyticFailure> failureOptionInventoryAnalytic,
Outlet outlet,
Option<OutletFailure> failureOptionOutlet,
bool isFetching,
bool isFetchingOutlet,
});
@override
$InventoryAnalyticCopyWith<$Res> get inventoryAnalytic;
@override
$OutletCopyWith<$Res> get outlet;
}
/// @nodoc
class __$$InventoryReportStateImplCopyWithImpl<$Res>
extends _$InventoryReportStateCopyWithImpl<$Res, _$InventoryReportStateImpl>
implements _$$InventoryReportStateImplCopyWith<$Res> {
__$$InventoryReportStateImplCopyWithImpl(
_$InventoryReportStateImpl _value,
$Res Function(_$InventoryReportStateImpl) _then,
) : super(_value, _then);
/// Create a copy of InventoryReportState
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({
Object? inventoryAnalytic = null,
Object? failureOptionInventoryAnalytic = null,
Object? outlet = null,
Object? failureOptionOutlet = null,
Object? isFetching = null,
Object? isFetchingOutlet = null,
}) {
return _then(
_$InventoryReportStateImpl(
inventoryAnalytic: null == inventoryAnalytic
? _value.inventoryAnalytic
: inventoryAnalytic // ignore: cast_nullable_to_non_nullable
as InventoryAnalytic,
failureOptionInventoryAnalytic: null == failureOptionInventoryAnalytic
? _value.failureOptionInventoryAnalytic
: failureOptionInventoryAnalytic // ignore: cast_nullable_to_non_nullable
as Option<AnalyticFailure>,
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,
isFetchingOutlet: null == isFetchingOutlet
? _value.isFetchingOutlet
: isFetchingOutlet // ignore: cast_nullable_to_non_nullable
as bool,
),
);
}
}
/// @nodoc
class _$InventoryReportStateImpl implements _InventoryReportState {
const _$InventoryReportStateImpl({
required this.inventoryAnalytic,
required this.failureOptionInventoryAnalytic,
required this.outlet,
required this.failureOptionOutlet,
this.isFetching = false,
this.isFetchingOutlet = false,
});
@override
final InventoryAnalytic inventoryAnalytic;
@override
final Option<AnalyticFailure> failureOptionInventoryAnalytic;
@override
final Outlet outlet;
@override
final Option<OutletFailure> failureOptionOutlet;
@override
@JsonKey()
final bool isFetching;
@override
@JsonKey()
final bool isFetchingOutlet;
@override
String toString() {
return 'InventoryReportState(inventoryAnalytic: $inventoryAnalytic, failureOptionInventoryAnalytic: $failureOptionInventoryAnalytic, outlet: $outlet, failureOptionOutlet: $failureOptionOutlet, isFetching: $isFetching, isFetchingOutlet: $isFetchingOutlet)';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType &&
other is _$InventoryReportStateImpl &&
(identical(other.inventoryAnalytic, inventoryAnalytic) ||
other.inventoryAnalytic == inventoryAnalytic) &&
(identical(
other.failureOptionInventoryAnalytic,
failureOptionInventoryAnalytic,
) ||
other.failureOptionInventoryAnalytic ==
failureOptionInventoryAnalytic) &&
(identical(other.outlet, outlet) || other.outlet == outlet) &&
(identical(other.failureOptionOutlet, failureOptionOutlet) ||
other.failureOptionOutlet == failureOptionOutlet) &&
(identical(other.isFetching, isFetching) ||
other.isFetching == isFetching) &&
(identical(other.isFetchingOutlet, isFetchingOutlet) ||
other.isFetchingOutlet == isFetchingOutlet));
}
@override
int get hashCode => Object.hash(
runtimeType,
inventoryAnalytic,
failureOptionInventoryAnalytic,
outlet,
failureOptionOutlet,
isFetching,
isFetchingOutlet,
);
/// Create a copy of InventoryReportState
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@override
@pragma('vm:prefer-inline')
_$$InventoryReportStateImplCopyWith<_$InventoryReportStateImpl>
get copyWith =>
__$$InventoryReportStateImplCopyWithImpl<_$InventoryReportStateImpl>(
this,
_$identity,
);
}
abstract class _InventoryReportState implements InventoryReportState {
const factory _InventoryReportState({
required final InventoryAnalytic inventoryAnalytic,
required final Option<AnalyticFailure> failureOptionInventoryAnalytic,
required final Outlet outlet,
required final Option<OutletFailure> failureOptionOutlet,
final bool isFetching,
final bool isFetchingOutlet,
}) = _$InventoryReportStateImpl;
@override
InventoryAnalytic get inventoryAnalytic;
@override
Option<AnalyticFailure> get failureOptionInventoryAnalytic;
@override
Outlet get outlet;
@override
Option<OutletFailure> get failureOptionOutlet;
@override
bool get isFetching;
@override
bool get isFetchingOutlet;
/// Create a copy of InventoryReportState
/// with the given fields replaced by the non-null parameter values.
@override
@JsonKey(includeFromJson: false, includeToJson: false)
_$$InventoryReportStateImplCopyWith<_$InventoryReportStateImpl>
get copyWith => throw _privateConstructorUsedError;
}

View File

@ -0,0 +1,10 @@
part of 'inventory_report_bloc.dart';
@freezed
class InventoryReportEvent with _$InventoryReportEvent {
const factory InventoryReportEvent.fetchedOutlet() = _FetchedOutlet;
const factory InventoryReportEvent.fetchedInventory(
DateTime dateFrom,
DateTime dateTo,
) = _FetchedInventory;
}

View File

@ -0,0 +1,20 @@
part of 'inventory_report_bloc.dart';
@freezed
class InventoryReportState with _$InventoryReportState {
const factory InventoryReportState({
required InventoryAnalytic inventoryAnalytic,
required Option<AnalyticFailure> failureOptionInventoryAnalytic,
required Outlet outlet,
required Option<OutletFailure> failureOptionOutlet,
@Default(false) bool isFetching,
@Default(false) bool isFetchingOutlet,
}) = _InventoryReportState;
factory InventoryReportState.initial() => InventoryReportState(
inventoryAnalytic: InventoryAnalytic.empty(),
failureOptionInventoryAnalytic: none(),
outlet: Outlet.empty(),
failureOptionOutlet: none(),
);
}

View File

@ -0,0 +1,91 @@
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';
import '../../../domain/outlet/outlet.dart';
part 'transaction_report_event.dart';
part 'transaction_report_state.dart';
part 'transaction_report_bloc.freezed.dart';
@injectable
class TransactionReportBloc
extends Bloc<TransactionReportEvent, TransactionReportState> {
final IAnalyticRepository _analyticRepository;
final IOutletRepository _outletRepository;
TransactionReportBloc(this._analyticRepository, this._outletRepository)
: super(TransactionReportState.initial()) {
on<TransactionReportEvent>(_onTransactionReportEvent);
}
Future<void> _onTransactionReportEvent(
TransactionReportEvent event,
Emitter<TransactionReportState> emit,
) {
return event.map(
fetchedOutlet: (e) async {
emit(
state.copyWith(isFetchingOutlet: true, failureOptionOutlet: none()),
);
final result = await _outletRepository.currentOutlet();
var data = result.fold(
(f) => state.copyWith(failureOptionOutlet: optionOf(f)),
(currentOutlet) => state.copyWith(outlet: currentOutlet),
);
emit(data.copyWith(isFetchingOutlet: false));
},
fetchedTransaction: (e) async {
emit(state.copyWith(isFetching: true, failureOptionAnalytic: none()));
var newState = state;
final category = await _analyticRepository.getCategory(
dateFrom: e.dateFrom,
dateTo: e.dateTo,
);
final profitLoss = await _analyticRepository.getProfitLoss(
dateFrom: e.dateFrom,
dateTo: e.dateTo,
);
final paymentMethod = await _analyticRepository.getPaymentMethod(
dateFrom: e.dateFrom,
dateTo: e.dateTo,
);
final product = await _analyticRepository.getProduct(
dateFrom: e.dateFrom,
dateTo: e.dateTo,
);
newState = category.fold(
(f) => newState.copyWith(failureOptionAnalytic: optionOf(f)),
(categoryAnalytic) =>
newState.copyWith(categoryAnalytic: categoryAnalytic),
);
newState = profitLoss.fold(
(f) => newState.copyWith(failureOptionAnalytic: optionOf(f)),
(profitLossAnalytic) =>
newState.copyWith(profitLossAnalytic: profitLossAnalytic),
);
newState = paymentMethod.fold(
(f) => newState.copyWith(failureOptionAnalytic: optionOf(f)),
(paymentMethodAnalytic) =>
newState.copyWith(paymentMethodAnalytic: paymentMethodAnalytic),
);
newState = product.fold(
(f) => newState.copyWith(failureOptionAnalytic: optionOf(f)),
(productAnalytic) =>
newState.copyWith(productAnalytic: productAnalytic),
);
emit(newState.copyWith(isFetching: false));
},
);
}
}

View File

@ -0,0 +1,752 @@
// 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 'transaction_report_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 _$TransactionReportEvent {
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function() fetchedOutlet,
required TResult Function(DateTime dateFrom, DateTime dateTo)
fetchedTransaction,
}) => throw _privateConstructorUsedError;
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>({
TResult? Function()? fetchedOutlet,
TResult? Function(DateTime dateFrom, DateTime dateTo)? fetchedTransaction,
}) => throw _privateConstructorUsedError;
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({
TResult Function()? fetchedOutlet,
TResult Function(DateTime dateFrom, DateTime dateTo)? fetchedTransaction,
required TResult orElse(),
}) => throw _privateConstructorUsedError;
@optionalTypeArgs
TResult map<TResult extends Object?>({
required TResult Function(_FetchedOutlet value) fetchedOutlet,
required TResult Function(_FetchedTransaction value) fetchedTransaction,
}) => throw _privateConstructorUsedError;
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>({
TResult? Function(_FetchedOutlet value)? fetchedOutlet,
TResult? Function(_FetchedTransaction value)? fetchedTransaction,
}) => throw _privateConstructorUsedError;
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>({
TResult Function(_FetchedOutlet value)? fetchedOutlet,
TResult Function(_FetchedTransaction value)? fetchedTransaction,
required TResult orElse(),
}) => throw _privateConstructorUsedError;
}
/// @nodoc
abstract class $TransactionReportEventCopyWith<$Res> {
factory $TransactionReportEventCopyWith(
TransactionReportEvent value,
$Res Function(TransactionReportEvent) then,
) = _$TransactionReportEventCopyWithImpl<$Res, TransactionReportEvent>;
}
/// @nodoc
class _$TransactionReportEventCopyWithImpl<
$Res,
$Val extends TransactionReportEvent
>
implements $TransactionReportEventCopyWith<$Res> {
_$TransactionReportEventCopyWithImpl(this._value, this._then);
// ignore: unused_field
final $Val _value;
// ignore: unused_field
final $Res Function($Val) _then;
/// Create a copy of TransactionReportEvent
/// with the given fields replaced by the non-null parameter values.
}
/// @nodoc
abstract class _$$FetchedOutletImplCopyWith<$Res> {
factory _$$FetchedOutletImplCopyWith(
_$FetchedOutletImpl value,
$Res Function(_$FetchedOutletImpl) then,
) = __$$FetchedOutletImplCopyWithImpl<$Res>;
}
/// @nodoc
class __$$FetchedOutletImplCopyWithImpl<$Res>
extends _$TransactionReportEventCopyWithImpl<$Res, _$FetchedOutletImpl>
implements _$$FetchedOutletImplCopyWith<$Res> {
__$$FetchedOutletImplCopyWithImpl(
_$FetchedOutletImpl _value,
$Res Function(_$FetchedOutletImpl) _then,
) : super(_value, _then);
/// Create a copy of TransactionReportEvent
/// with the given fields replaced by the non-null parameter values.
}
/// @nodoc
class _$FetchedOutletImpl implements _FetchedOutlet {
const _$FetchedOutletImpl();
@override
String toString() {
return 'TransactionReportEvent.fetchedOutlet()';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType && other is _$FetchedOutletImpl);
}
@override
int get hashCode => runtimeType.hashCode;
@override
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function() fetchedOutlet,
required TResult Function(DateTime dateFrom, DateTime dateTo)
fetchedTransaction,
}) {
return fetchedOutlet();
}
@override
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>({
TResult? Function()? fetchedOutlet,
TResult? Function(DateTime dateFrom, DateTime dateTo)? fetchedTransaction,
}) {
return fetchedOutlet?.call();
}
@override
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({
TResult Function()? fetchedOutlet,
TResult Function(DateTime dateFrom, DateTime dateTo)? fetchedTransaction,
required TResult orElse(),
}) {
if (fetchedOutlet != null) {
return fetchedOutlet();
}
return orElse();
}
@override
@optionalTypeArgs
TResult map<TResult extends Object?>({
required TResult Function(_FetchedOutlet value) fetchedOutlet,
required TResult Function(_FetchedTransaction value) fetchedTransaction,
}) {
return fetchedOutlet(this);
}
@override
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>({
TResult? Function(_FetchedOutlet value)? fetchedOutlet,
TResult? Function(_FetchedTransaction value)? fetchedTransaction,
}) {
return fetchedOutlet?.call(this);
}
@override
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>({
TResult Function(_FetchedOutlet value)? fetchedOutlet,
TResult Function(_FetchedTransaction value)? fetchedTransaction,
required TResult orElse(),
}) {
if (fetchedOutlet != null) {
return fetchedOutlet(this);
}
return orElse();
}
}
abstract class _FetchedOutlet implements TransactionReportEvent {
const factory _FetchedOutlet() = _$FetchedOutletImpl;
}
/// @nodoc
abstract class _$$FetchedTransactionImplCopyWith<$Res> {
factory _$$FetchedTransactionImplCopyWith(
_$FetchedTransactionImpl value,
$Res Function(_$FetchedTransactionImpl) then,
) = __$$FetchedTransactionImplCopyWithImpl<$Res>;
@useResult
$Res call({DateTime dateFrom, DateTime dateTo});
}
/// @nodoc
class __$$FetchedTransactionImplCopyWithImpl<$Res>
extends _$TransactionReportEventCopyWithImpl<$Res, _$FetchedTransactionImpl>
implements _$$FetchedTransactionImplCopyWith<$Res> {
__$$FetchedTransactionImplCopyWithImpl(
_$FetchedTransactionImpl _value,
$Res Function(_$FetchedTransactionImpl) _then,
) : super(_value, _then);
/// Create a copy of TransactionReportEvent
/// 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(
_$FetchedTransactionImpl(
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 _$FetchedTransactionImpl implements _FetchedTransaction {
const _$FetchedTransactionImpl(this.dateFrom, this.dateTo);
@override
final DateTime dateFrom;
@override
final DateTime dateTo;
@override
String toString() {
return 'TransactionReportEvent.fetchedTransaction(dateFrom: $dateFrom, dateTo: $dateTo)';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType &&
other is _$FetchedTransactionImpl &&
(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 TransactionReportEvent
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@override
@pragma('vm:prefer-inline')
_$$FetchedTransactionImplCopyWith<_$FetchedTransactionImpl> get copyWith =>
__$$FetchedTransactionImplCopyWithImpl<_$FetchedTransactionImpl>(
this,
_$identity,
);
@override
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function() fetchedOutlet,
required TResult Function(DateTime dateFrom, DateTime dateTo)
fetchedTransaction,
}) {
return fetchedTransaction(dateFrom, dateTo);
}
@override
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>({
TResult? Function()? fetchedOutlet,
TResult? Function(DateTime dateFrom, DateTime dateTo)? fetchedTransaction,
}) {
return fetchedTransaction?.call(dateFrom, dateTo);
}
@override
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({
TResult Function()? fetchedOutlet,
TResult Function(DateTime dateFrom, DateTime dateTo)? fetchedTransaction,
required TResult orElse(),
}) {
if (fetchedTransaction != null) {
return fetchedTransaction(dateFrom, dateTo);
}
return orElse();
}
@override
@optionalTypeArgs
TResult map<TResult extends Object?>({
required TResult Function(_FetchedOutlet value) fetchedOutlet,
required TResult Function(_FetchedTransaction value) fetchedTransaction,
}) {
return fetchedTransaction(this);
}
@override
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>({
TResult? Function(_FetchedOutlet value)? fetchedOutlet,
TResult? Function(_FetchedTransaction value)? fetchedTransaction,
}) {
return fetchedTransaction?.call(this);
}
@override
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>({
TResult Function(_FetchedOutlet value)? fetchedOutlet,
TResult Function(_FetchedTransaction value)? fetchedTransaction,
required TResult orElse(),
}) {
if (fetchedTransaction != null) {
return fetchedTransaction(this);
}
return orElse();
}
}
abstract class _FetchedTransaction implements TransactionReportEvent {
const factory _FetchedTransaction(
final DateTime dateFrom,
final DateTime dateTo,
) = _$FetchedTransactionImpl;
DateTime get dateFrom;
DateTime get dateTo;
/// Create a copy of TransactionReportEvent
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
_$$FetchedTransactionImplCopyWith<_$FetchedTransactionImpl> get copyWith =>
throw _privateConstructorUsedError;
}
/// @nodoc
mixin _$TransactionReportState {
CategoryAnalytic get categoryAnalytic => throw _privateConstructorUsedError;
ProfitLossAnalytic get profitLossAnalytic =>
throw _privateConstructorUsedError;
PaymentMethodAnalytic get paymentMethodAnalytic =>
throw _privateConstructorUsedError;
ProductAnalytic get productAnalytic => throw _privateConstructorUsedError;
Option<AnalyticFailure> get failureOptionAnalytic =>
throw _privateConstructorUsedError;
Outlet get outlet => throw _privateConstructorUsedError;
Option<OutletFailure> get failureOptionOutlet =>
throw _privateConstructorUsedError;
bool get isFetching => throw _privateConstructorUsedError;
bool get isFetchingOutlet => throw _privateConstructorUsedError;
/// Create a copy of TransactionReportState
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
$TransactionReportStateCopyWith<TransactionReportState> get copyWith =>
throw _privateConstructorUsedError;
}
/// @nodoc
abstract class $TransactionReportStateCopyWith<$Res> {
factory $TransactionReportStateCopyWith(
TransactionReportState value,
$Res Function(TransactionReportState) then,
) = _$TransactionReportStateCopyWithImpl<$Res, TransactionReportState>;
@useResult
$Res call({
CategoryAnalytic categoryAnalytic,
ProfitLossAnalytic profitLossAnalytic,
PaymentMethodAnalytic paymentMethodAnalytic,
ProductAnalytic productAnalytic,
Option<AnalyticFailure> failureOptionAnalytic,
Outlet outlet,
Option<OutletFailure> failureOptionOutlet,
bool isFetching,
bool isFetchingOutlet,
});
$CategoryAnalyticCopyWith<$Res> get categoryAnalytic;
$ProfitLossAnalyticCopyWith<$Res> get profitLossAnalytic;
$PaymentMethodAnalyticCopyWith<$Res> get paymentMethodAnalytic;
$ProductAnalyticCopyWith<$Res> get productAnalytic;
$OutletCopyWith<$Res> get outlet;
}
/// @nodoc
class _$TransactionReportStateCopyWithImpl<
$Res,
$Val extends TransactionReportState
>
implements $TransactionReportStateCopyWith<$Res> {
_$TransactionReportStateCopyWithImpl(this._value, this._then);
// ignore: unused_field
final $Val _value;
// ignore: unused_field
final $Res Function($Val) _then;
/// Create a copy of TransactionReportState
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({
Object? categoryAnalytic = null,
Object? profitLossAnalytic = null,
Object? paymentMethodAnalytic = null,
Object? productAnalytic = null,
Object? failureOptionAnalytic = null,
Object? outlet = null,
Object? failureOptionOutlet = null,
Object? isFetching = null,
Object? isFetchingOutlet = null,
}) {
return _then(
_value.copyWith(
categoryAnalytic: null == categoryAnalytic
? _value.categoryAnalytic
: categoryAnalytic // ignore: cast_nullable_to_non_nullable
as CategoryAnalytic,
profitLossAnalytic: null == profitLossAnalytic
? _value.profitLossAnalytic
: profitLossAnalytic // ignore: cast_nullable_to_non_nullable
as ProfitLossAnalytic,
paymentMethodAnalytic: null == paymentMethodAnalytic
? _value.paymentMethodAnalytic
: paymentMethodAnalytic // ignore: cast_nullable_to_non_nullable
as PaymentMethodAnalytic,
productAnalytic: null == productAnalytic
? _value.productAnalytic
: productAnalytic // ignore: cast_nullable_to_non_nullable
as ProductAnalytic,
failureOptionAnalytic: null == failureOptionAnalytic
? _value.failureOptionAnalytic
: failureOptionAnalytic // ignore: cast_nullable_to_non_nullable
as Option<AnalyticFailure>,
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,
isFetchingOutlet: null == isFetchingOutlet
? _value.isFetchingOutlet
: isFetchingOutlet // ignore: cast_nullable_to_non_nullable
as bool,
)
as $Val,
);
}
/// Create a copy of TransactionReportState
/// with the given fields replaced by the non-null parameter values.
@override
@pragma('vm:prefer-inline')
$CategoryAnalyticCopyWith<$Res> get categoryAnalytic {
return $CategoryAnalyticCopyWith<$Res>(_value.categoryAnalytic, (value) {
return _then(_value.copyWith(categoryAnalytic: value) as $Val);
});
}
/// Create a copy of TransactionReportState
/// with the given fields replaced by the non-null parameter values.
@override
@pragma('vm:prefer-inline')
$ProfitLossAnalyticCopyWith<$Res> get profitLossAnalytic {
return $ProfitLossAnalyticCopyWith<$Res>(_value.profitLossAnalytic, (
value,
) {
return _then(_value.copyWith(profitLossAnalytic: value) as $Val);
});
}
/// Create a copy of TransactionReportState
/// with the given fields replaced by the non-null parameter values.
@override
@pragma('vm:prefer-inline')
$PaymentMethodAnalyticCopyWith<$Res> get paymentMethodAnalytic {
return $PaymentMethodAnalyticCopyWith<$Res>(_value.paymentMethodAnalytic, (
value,
) {
return _then(_value.copyWith(paymentMethodAnalytic: value) as $Val);
});
}
/// Create a copy of TransactionReportState
/// with the given fields replaced by the non-null parameter values.
@override
@pragma('vm:prefer-inline')
$ProductAnalyticCopyWith<$Res> get productAnalytic {
return $ProductAnalyticCopyWith<$Res>(_value.productAnalytic, (value) {
return _then(_value.copyWith(productAnalytic: value) as $Val);
});
}
/// Create a copy of TransactionReportState
/// 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 _$$TransactionReportStateImplCopyWith<$Res>
implements $TransactionReportStateCopyWith<$Res> {
factory _$$TransactionReportStateImplCopyWith(
_$TransactionReportStateImpl value,
$Res Function(_$TransactionReportStateImpl) then,
) = __$$TransactionReportStateImplCopyWithImpl<$Res>;
@override
@useResult
$Res call({
CategoryAnalytic categoryAnalytic,
ProfitLossAnalytic profitLossAnalytic,
PaymentMethodAnalytic paymentMethodAnalytic,
ProductAnalytic productAnalytic,
Option<AnalyticFailure> failureOptionAnalytic,
Outlet outlet,
Option<OutletFailure> failureOptionOutlet,
bool isFetching,
bool isFetchingOutlet,
});
@override
$CategoryAnalyticCopyWith<$Res> get categoryAnalytic;
@override
$ProfitLossAnalyticCopyWith<$Res> get profitLossAnalytic;
@override
$PaymentMethodAnalyticCopyWith<$Res> get paymentMethodAnalytic;
@override
$ProductAnalyticCopyWith<$Res> get productAnalytic;
@override
$OutletCopyWith<$Res> get outlet;
}
/// @nodoc
class __$$TransactionReportStateImplCopyWithImpl<$Res>
extends
_$TransactionReportStateCopyWithImpl<$Res, _$TransactionReportStateImpl>
implements _$$TransactionReportStateImplCopyWith<$Res> {
__$$TransactionReportStateImplCopyWithImpl(
_$TransactionReportStateImpl _value,
$Res Function(_$TransactionReportStateImpl) _then,
) : super(_value, _then);
/// Create a copy of TransactionReportState
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({
Object? categoryAnalytic = null,
Object? profitLossAnalytic = null,
Object? paymentMethodAnalytic = null,
Object? productAnalytic = null,
Object? failureOptionAnalytic = null,
Object? outlet = null,
Object? failureOptionOutlet = null,
Object? isFetching = null,
Object? isFetchingOutlet = null,
}) {
return _then(
_$TransactionReportStateImpl(
categoryAnalytic: null == categoryAnalytic
? _value.categoryAnalytic
: categoryAnalytic // ignore: cast_nullable_to_non_nullable
as CategoryAnalytic,
profitLossAnalytic: null == profitLossAnalytic
? _value.profitLossAnalytic
: profitLossAnalytic // ignore: cast_nullable_to_non_nullable
as ProfitLossAnalytic,
paymentMethodAnalytic: null == paymentMethodAnalytic
? _value.paymentMethodAnalytic
: paymentMethodAnalytic // ignore: cast_nullable_to_non_nullable
as PaymentMethodAnalytic,
productAnalytic: null == productAnalytic
? _value.productAnalytic
: productAnalytic // ignore: cast_nullable_to_non_nullable
as ProductAnalytic,
failureOptionAnalytic: null == failureOptionAnalytic
? _value.failureOptionAnalytic
: failureOptionAnalytic // ignore: cast_nullable_to_non_nullable
as Option<AnalyticFailure>,
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,
isFetchingOutlet: null == isFetchingOutlet
? _value.isFetchingOutlet
: isFetchingOutlet // ignore: cast_nullable_to_non_nullable
as bool,
),
);
}
}
/// @nodoc
class _$TransactionReportStateImpl implements _TransactionReportState {
const _$TransactionReportStateImpl({
required this.categoryAnalytic,
required this.profitLossAnalytic,
required this.paymentMethodAnalytic,
required this.productAnalytic,
required this.failureOptionAnalytic,
required this.outlet,
required this.failureOptionOutlet,
this.isFetching = false,
this.isFetchingOutlet = false,
});
@override
final CategoryAnalytic categoryAnalytic;
@override
final ProfitLossAnalytic profitLossAnalytic;
@override
final PaymentMethodAnalytic paymentMethodAnalytic;
@override
final ProductAnalytic productAnalytic;
@override
final Option<AnalyticFailure> failureOptionAnalytic;
@override
final Outlet outlet;
@override
final Option<OutletFailure> failureOptionOutlet;
@override
@JsonKey()
final bool isFetching;
@override
@JsonKey()
final bool isFetchingOutlet;
@override
String toString() {
return 'TransactionReportState(categoryAnalytic: $categoryAnalytic, profitLossAnalytic: $profitLossAnalytic, paymentMethodAnalytic: $paymentMethodAnalytic, productAnalytic: $productAnalytic, failureOptionAnalytic: $failureOptionAnalytic, outlet: $outlet, failureOptionOutlet: $failureOptionOutlet, isFetching: $isFetching, isFetchingOutlet: $isFetchingOutlet)';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType &&
other is _$TransactionReportStateImpl &&
(identical(other.categoryAnalytic, categoryAnalytic) ||
other.categoryAnalytic == categoryAnalytic) &&
(identical(other.profitLossAnalytic, profitLossAnalytic) ||
other.profitLossAnalytic == profitLossAnalytic) &&
(identical(other.paymentMethodAnalytic, paymentMethodAnalytic) ||
other.paymentMethodAnalytic == paymentMethodAnalytic) &&
(identical(other.productAnalytic, productAnalytic) ||
other.productAnalytic == productAnalytic) &&
(identical(other.failureOptionAnalytic, failureOptionAnalytic) ||
other.failureOptionAnalytic == failureOptionAnalytic) &&
(identical(other.outlet, outlet) || other.outlet == outlet) &&
(identical(other.failureOptionOutlet, failureOptionOutlet) ||
other.failureOptionOutlet == failureOptionOutlet) &&
(identical(other.isFetching, isFetching) ||
other.isFetching == isFetching) &&
(identical(other.isFetchingOutlet, isFetchingOutlet) ||
other.isFetchingOutlet == isFetchingOutlet));
}
@override
int get hashCode => Object.hash(
runtimeType,
categoryAnalytic,
profitLossAnalytic,
paymentMethodAnalytic,
productAnalytic,
failureOptionAnalytic,
outlet,
failureOptionOutlet,
isFetching,
isFetchingOutlet,
);
/// Create a copy of TransactionReportState
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@override
@pragma('vm:prefer-inline')
_$$TransactionReportStateImplCopyWith<_$TransactionReportStateImpl>
get copyWith =>
__$$TransactionReportStateImplCopyWithImpl<_$TransactionReportStateImpl>(
this,
_$identity,
);
}
abstract class _TransactionReportState implements TransactionReportState {
const factory _TransactionReportState({
required final CategoryAnalytic categoryAnalytic,
required final ProfitLossAnalytic profitLossAnalytic,
required final PaymentMethodAnalytic paymentMethodAnalytic,
required final ProductAnalytic productAnalytic,
required final Option<AnalyticFailure> failureOptionAnalytic,
required final Outlet outlet,
required final Option<OutletFailure> failureOptionOutlet,
final bool isFetching,
final bool isFetchingOutlet,
}) = _$TransactionReportStateImpl;
@override
CategoryAnalytic get categoryAnalytic;
@override
ProfitLossAnalytic get profitLossAnalytic;
@override
PaymentMethodAnalytic get paymentMethodAnalytic;
@override
ProductAnalytic get productAnalytic;
@override
Option<AnalyticFailure> get failureOptionAnalytic;
@override
Outlet get outlet;
@override
Option<OutletFailure> get failureOptionOutlet;
@override
bool get isFetching;
@override
bool get isFetchingOutlet;
/// Create a copy of TransactionReportState
/// with the given fields replaced by the non-null parameter values.
@override
@JsonKey(includeFromJson: false, includeToJson: false)
_$$TransactionReportStateImplCopyWith<_$TransactionReportStateImpl>
get copyWith => throw _privateConstructorUsedError;
}

View File

@ -0,0 +1,10 @@
part of 'transaction_report_bloc.dart';
@freezed
class TransactionReportEvent with _$TransactionReportEvent {
const factory TransactionReportEvent.fetchedOutlet() = _FetchedOutlet;
const factory TransactionReportEvent.fetchedTransaction(
DateTime dateFrom,
DateTime dateTo,
) = _FetchedTransaction;
}

View File

@ -0,0 +1,26 @@
part of 'transaction_report_bloc.dart';
@freezed
class TransactionReportState with _$TransactionReportState {
const factory TransactionReportState({
required CategoryAnalytic categoryAnalytic,
required ProfitLossAnalytic profitLossAnalytic,
required PaymentMethodAnalytic paymentMethodAnalytic,
required ProductAnalytic productAnalytic,
required Option<AnalyticFailure> failureOptionAnalytic,
required Outlet outlet,
required Option<OutletFailure> failureOptionOutlet,
@Default(false) bool isFetching,
@Default(false) bool isFetchingOutlet,
}) = _TransactionReportState;
factory TransactionReportState.initial() => TransactionReportState(
failureOptionAnalytic: none(),
outlet: Outlet.empty(),
failureOptionOutlet: none(),
categoryAnalytic: CategoryAnalytic.empty(),
profitLossAnalytic: ProfitLossAnalytic.empty(),
paymentMethodAnalytic: PaymentMethodAnalytic.empty(),
productAnalytic: ProductAnalytic.empty(),
);
}

View File

@ -0,0 +1,70 @@
import 'package:bloc/bloc.dart';
import 'package:dartz/dartz.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:injectable/injectable.dart';
import '../../../domain/user/user.dart';
part 'change_password_form_event.dart';
part 'change_password_form_state.dart';
part 'change_password_form_bloc.freezed.dart';
@injectable
class ChangePasswordFormBloc
extends Bloc<ChangePasswordFormEvent, ChangePasswordFormState> {
final IUserRepository _repository;
ChangePasswordFormBloc(this._repository)
: super(ChangePasswordFormState.initial()) {
on<ChangePasswordFormEvent>(_onChangePasswordFormEvent);
}
Future<void> _onChangePasswordFormEvent(
ChangePasswordFormEvent event,
Emitter<ChangePasswordFormState> emit,
) {
return event.map(
newPasswordChanged: (e) async {
emit(
state.copyWith(
newPassword: e.newPassword,
failureOrChangePasswordOption: none(),
),
);
},
currentPasswordChanged: (e) async {
emit(
state.copyWith(
currentPassword: e.currentPassword,
failureOrChangePasswordOption: none(),
),
);
},
submitted: (e) async {
Either<UserFailure, Unit>? failureOrSuccess;
emit(
state.copyWith(
isSubmitting: true,
failureOrChangePasswordOption: none(),
),
);
final oldPasswordValid = state.newPassword.isNotEmpty;
final currentPasswordValid = state.currentPassword.isNotEmpty;
if (oldPasswordValid && currentPasswordValid) {
failureOrSuccess = await _repository.changePassword(
newPassword: state.newPassword,
currentPassword: state.currentPassword,
);
emit(
state.copyWith(
isSubmitting: false,
failureOrChangePasswordOption: optionOf(failureOrSuccess),
),
);
}
emit(state.copyWith(showErrorMessages: true, isSubmitting: false));
},
);
}
}

View File

@ -0,0 +1,766 @@
// 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 'change_password_form_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 _$ChangePasswordFormEvent {
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function(String newPassword) newPasswordChanged,
required TResult Function(String currentPassword) currentPasswordChanged,
required TResult Function() submitted,
}) => throw _privateConstructorUsedError;
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>({
TResult? Function(String newPassword)? newPasswordChanged,
TResult? Function(String currentPassword)? currentPasswordChanged,
TResult? Function()? submitted,
}) => throw _privateConstructorUsedError;
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({
TResult Function(String newPassword)? newPasswordChanged,
TResult Function(String currentPassword)? currentPasswordChanged,
TResult Function()? submitted,
required TResult orElse(),
}) => throw _privateConstructorUsedError;
@optionalTypeArgs
TResult map<TResult extends Object?>({
required TResult Function(_NewPasswordChanged value) newPasswordChanged,
required TResult Function(_CurrentPasswordChanged value)
currentPasswordChanged,
required TResult Function(_Submitted value) submitted,
}) => throw _privateConstructorUsedError;
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>({
TResult? Function(_NewPasswordChanged value)? newPasswordChanged,
TResult? Function(_CurrentPasswordChanged value)? currentPasswordChanged,
TResult? Function(_Submitted value)? submitted,
}) => throw _privateConstructorUsedError;
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>({
TResult Function(_NewPasswordChanged value)? newPasswordChanged,
TResult Function(_CurrentPasswordChanged value)? currentPasswordChanged,
TResult Function(_Submitted value)? submitted,
required TResult orElse(),
}) => throw _privateConstructorUsedError;
}
/// @nodoc
abstract class $ChangePasswordFormEventCopyWith<$Res> {
factory $ChangePasswordFormEventCopyWith(
ChangePasswordFormEvent value,
$Res Function(ChangePasswordFormEvent) then,
) = _$ChangePasswordFormEventCopyWithImpl<$Res, ChangePasswordFormEvent>;
}
/// @nodoc
class _$ChangePasswordFormEventCopyWithImpl<
$Res,
$Val extends ChangePasswordFormEvent
>
implements $ChangePasswordFormEventCopyWith<$Res> {
_$ChangePasswordFormEventCopyWithImpl(this._value, this._then);
// ignore: unused_field
final $Val _value;
// ignore: unused_field
final $Res Function($Val) _then;
/// Create a copy of ChangePasswordFormEvent
/// with the given fields replaced by the non-null parameter values.
}
/// @nodoc
abstract class _$$NewPasswordChangedImplCopyWith<$Res> {
factory _$$NewPasswordChangedImplCopyWith(
_$NewPasswordChangedImpl value,
$Res Function(_$NewPasswordChangedImpl) then,
) = __$$NewPasswordChangedImplCopyWithImpl<$Res>;
@useResult
$Res call({String newPassword});
}
/// @nodoc
class __$$NewPasswordChangedImplCopyWithImpl<$Res>
extends
_$ChangePasswordFormEventCopyWithImpl<$Res, _$NewPasswordChangedImpl>
implements _$$NewPasswordChangedImplCopyWith<$Res> {
__$$NewPasswordChangedImplCopyWithImpl(
_$NewPasswordChangedImpl _value,
$Res Function(_$NewPasswordChangedImpl) _then,
) : super(_value, _then);
/// Create a copy of ChangePasswordFormEvent
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({Object? newPassword = null}) {
return _then(
_$NewPasswordChangedImpl(
null == newPassword
? _value.newPassword
: newPassword // ignore: cast_nullable_to_non_nullable
as String,
),
);
}
}
/// @nodoc
class _$NewPasswordChangedImpl implements _NewPasswordChanged {
const _$NewPasswordChangedImpl(this.newPassword);
@override
final String newPassword;
@override
String toString() {
return 'ChangePasswordFormEvent.newPasswordChanged(newPassword: $newPassword)';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType &&
other is _$NewPasswordChangedImpl &&
(identical(other.newPassword, newPassword) ||
other.newPassword == newPassword));
}
@override
int get hashCode => Object.hash(runtimeType, newPassword);
/// Create a copy of ChangePasswordFormEvent
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@override
@pragma('vm:prefer-inline')
_$$NewPasswordChangedImplCopyWith<_$NewPasswordChangedImpl> get copyWith =>
__$$NewPasswordChangedImplCopyWithImpl<_$NewPasswordChangedImpl>(
this,
_$identity,
);
@override
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function(String newPassword) newPasswordChanged,
required TResult Function(String currentPassword) currentPasswordChanged,
required TResult Function() submitted,
}) {
return newPasswordChanged(newPassword);
}
@override
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>({
TResult? Function(String newPassword)? newPasswordChanged,
TResult? Function(String currentPassword)? currentPasswordChanged,
TResult? Function()? submitted,
}) {
return newPasswordChanged?.call(newPassword);
}
@override
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({
TResult Function(String newPassword)? newPasswordChanged,
TResult Function(String currentPassword)? currentPasswordChanged,
TResult Function()? submitted,
required TResult orElse(),
}) {
if (newPasswordChanged != null) {
return newPasswordChanged(newPassword);
}
return orElse();
}
@override
@optionalTypeArgs
TResult map<TResult extends Object?>({
required TResult Function(_NewPasswordChanged value) newPasswordChanged,
required TResult Function(_CurrentPasswordChanged value)
currentPasswordChanged,
required TResult Function(_Submitted value) submitted,
}) {
return newPasswordChanged(this);
}
@override
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>({
TResult? Function(_NewPasswordChanged value)? newPasswordChanged,
TResult? Function(_CurrentPasswordChanged value)? currentPasswordChanged,
TResult? Function(_Submitted value)? submitted,
}) {
return newPasswordChanged?.call(this);
}
@override
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>({
TResult Function(_NewPasswordChanged value)? newPasswordChanged,
TResult Function(_CurrentPasswordChanged value)? currentPasswordChanged,
TResult Function(_Submitted value)? submitted,
required TResult orElse(),
}) {
if (newPasswordChanged != null) {
return newPasswordChanged(this);
}
return orElse();
}
}
abstract class _NewPasswordChanged implements ChangePasswordFormEvent {
const factory _NewPasswordChanged(final String newPassword) =
_$NewPasswordChangedImpl;
String get newPassword;
/// Create a copy of ChangePasswordFormEvent
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
_$$NewPasswordChangedImplCopyWith<_$NewPasswordChangedImpl> get copyWith =>
throw _privateConstructorUsedError;
}
/// @nodoc
abstract class _$$CurrentPasswordChangedImplCopyWith<$Res> {
factory _$$CurrentPasswordChangedImplCopyWith(
_$CurrentPasswordChangedImpl value,
$Res Function(_$CurrentPasswordChangedImpl) then,
) = __$$CurrentPasswordChangedImplCopyWithImpl<$Res>;
@useResult
$Res call({String currentPassword});
}
/// @nodoc
class __$$CurrentPasswordChangedImplCopyWithImpl<$Res>
extends
_$ChangePasswordFormEventCopyWithImpl<
$Res,
_$CurrentPasswordChangedImpl
>
implements _$$CurrentPasswordChangedImplCopyWith<$Res> {
__$$CurrentPasswordChangedImplCopyWithImpl(
_$CurrentPasswordChangedImpl _value,
$Res Function(_$CurrentPasswordChangedImpl) _then,
) : super(_value, _then);
/// Create a copy of ChangePasswordFormEvent
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({Object? currentPassword = null}) {
return _then(
_$CurrentPasswordChangedImpl(
null == currentPassword
? _value.currentPassword
: currentPassword // ignore: cast_nullable_to_non_nullable
as String,
),
);
}
}
/// @nodoc
class _$CurrentPasswordChangedImpl implements _CurrentPasswordChanged {
const _$CurrentPasswordChangedImpl(this.currentPassword);
@override
final String currentPassword;
@override
String toString() {
return 'ChangePasswordFormEvent.currentPasswordChanged(currentPassword: $currentPassword)';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType &&
other is _$CurrentPasswordChangedImpl &&
(identical(other.currentPassword, currentPassword) ||
other.currentPassword == currentPassword));
}
@override
int get hashCode => Object.hash(runtimeType, currentPassword);
/// Create a copy of ChangePasswordFormEvent
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@override
@pragma('vm:prefer-inline')
_$$CurrentPasswordChangedImplCopyWith<_$CurrentPasswordChangedImpl>
get copyWith =>
__$$CurrentPasswordChangedImplCopyWithImpl<_$CurrentPasswordChangedImpl>(
this,
_$identity,
);
@override
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function(String newPassword) newPasswordChanged,
required TResult Function(String currentPassword) currentPasswordChanged,
required TResult Function() submitted,
}) {
return currentPasswordChanged(currentPassword);
}
@override
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>({
TResult? Function(String newPassword)? newPasswordChanged,
TResult? Function(String currentPassword)? currentPasswordChanged,
TResult? Function()? submitted,
}) {
return currentPasswordChanged?.call(currentPassword);
}
@override
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({
TResult Function(String newPassword)? newPasswordChanged,
TResult Function(String currentPassword)? currentPasswordChanged,
TResult Function()? submitted,
required TResult orElse(),
}) {
if (currentPasswordChanged != null) {
return currentPasswordChanged(currentPassword);
}
return orElse();
}
@override
@optionalTypeArgs
TResult map<TResult extends Object?>({
required TResult Function(_NewPasswordChanged value) newPasswordChanged,
required TResult Function(_CurrentPasswordChanged value)
currentPasswordChanged,
required TResult Function(_Submitted value) submitted,
}) {
return currentPasswordChanged(this);
}
@override
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>({
TResult? Function(_NewPasswordChanged value)? newPasswordChanged,
TResult? Function(_CurrentPasswordChanged value)? currentPasswordChanged,
TResult? Function(_Submitted value)? submitted,
}) {
return currentPasswordChanged?.call(this);
}
@override
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>({
TResult Function(_NewPasswordChanged value)? newPasswordChanged,
TResult Function(_CurrentPasswordChanged value)? currentPasswordChanged,
TResult Function(_Submitted value)? submitted,
required TResult orElse(),
}) {
if (currentPasswordChanged != null) {
return currentPasswordChanged(this);
}
return orElse();
}
}
abstract class _CurrentPasswordChanged implements ChangePasswordFormEvent {
const factory _CurrentPasswordChanged(final String currentPassword) =
_$CurrentPasswordChangedImpl;
String get currentPassword;
/// Create a copy of ChangePasswordFormEvent
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
_$$CurrentPasswordChangedImplCopyWith<_$CurrentPasswordChangedImpl>
get copyWith => throw _privateConstructorUsedError;
}
/// @nodoc
abstract class _$$SubmittedImplCopyWith<$Res> {
factory _$$SubmittedImplCopyWith(
_$SubmittedImpl value,
$Res Function(_$SubmittedImpl) then,
) = __$$SubmittedImplCopyWithImpl<$Res>;
}
/// @nodoc
class __$$SubmittedImplCopyWithImpl<$Res>
extends _$ChangePasswordFormEventCopyWithImpl<$Res, _$SubmittedImpl>
implements _$$SubmittedImplCopyWith<$Res> {
__$$SubmittedImplCopyWithImpl(
_$SubmittedImpl _value,
$Res Function(_$SubmittedImpl) _then,
) : super(_value, _then);
/// Create a copy of ChangePasswordFormEvent
/// with the given fields replaced by the non-null parameter values.
}
/// @nodoc
class _$SubmittedImpl implements _Submitted {
const _$SubmittedImpl();
@override
String toString() {
return 'ChangePasswordFormEvent.submitted()';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType && other is _$SubmittedImpl);
}
@override
int get hashCode => runtimeType.hashCode;
@override
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function(String newPassword) newPasswordChanged,
required TResult Function(String currentPassword) currentPasswordChanged,
required TResult Function() submitted,
}) {
return submitted();
}
@override
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>({
TResult? Function(String newPassword)? newPasswordChanged,
TResult? Function(String currentPassword)? currentPasswordChanged,
TResult? Function()? submitted,
}) {
return submitted?.call();
}
@override
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({
TResult Function(String newPassword)? newPasswordChanged,
TResult Function(String currentPassword)? currentPasswordChanged,
TResult Function()? submitted,
required TResult orElse(),
}) {
if (submitted != null) {
return submitted();
}
return orElse();
}
@override
@optionalTypeArgs
TResult map<TResult extends Object?>({
required TResult Function(_NewPasswordChanged value) newPasswordChanged,
required TResult Function(_CurrentPasswordChanged value)
currentPasswordChanged,
required TResult Function(_Submitted value) submitted,
}) {
return submitted(this);
}
@override
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>({
TResult? Function(_NewPasswordChanged value)? newPasswordChanged,
TResult? Function(_CurrentPasswordChanged value)? currentPasswordChanged,
TResult? Function(_Submitted value)? submitted,
}) {
return submitted?.call(this);
}
@override
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>({
TResult Function(_NewPasswordChanged value)? newPasswordChanged,
TResult Function(_CurrentPasswordChanged value)? currentPasswordChanged,
TResult Function(_Submitted value)? submitted,
required TResult orElse(),
}) {
if (submitted != null) {
return submitted(this);
}
return orElse();
}
}
abstract class _Submitted implements ChangePasswordFormEvent {
const factory _Submitted() = _$SubmittedImpl;
}
/// @nodoc
mixin _$ChangePasswordFormState {
String get newPassword => throw _privateConstructorUsedError;
String get currentPassword => throw _privateConstructorUsedError;
Option<Either<UserFailure, Unit>> get failureOrChangePasswordOption =>
throw _privateConstructorUsedError;
bool get isSubmitting => throw _privateConstructorUsedError;
bool get showErrorMessages => throw _privateConstructorUsedError;
/// Create a copy of ChangePasswordFormState
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
$ChangePasswordFormStateCopyWith<ChangePasswordFormState> get copyWith =>
throw _privateConstructorUsedError;
}
/// @nodoc
abstract class $ChangePasswordFormStateCopyWith<$Res> {
factory $ChangePasswordFormStateCopyWith(
ChangePasswordFormState value,
$Res Function(ChangePasswordFormState) then,
) = _$ChangePasswordFormStateCopyWithImpl<$Res, ChangePasswordFormState>;
@useResult
$Res call({
String newPassword,
String currentPassword,
Option<Either<UserFailure, Unit>> failureOrChangePasswordOption,
bool isSubmitting,
bool showErrorMessages,
});
}
/// @nodoc
class _$ChangePasswordFormStateCopyWithImpl<
$Res,
$Val extends ChangePasswordFormState
>
implements $ChangePasswordFormStateCopyWith<$Res> {
_$ChangePasswordFormStateCopyWithImpl(this._value, this._then);
// ignore: unused_field
final $Val _value;
// ignore: unused_field
final $Res Function($Val) _then;
/// Create a copy of ChangePasswordFormState
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({
Object? newPassword = null,
Object? currentPassword = null,
Object? failureOrChangePasswordOption = null,
Object? isSubmitting = null,
Object? showErrorMessages = null,
}) {
return _then(
_value.copyWith(
newPassword: null == newPassword
? _value.newPassword
: newPassword // ignore: cast_nullable_to_non_nullable
as String,
currentPassword: null == currentPassword
? _value.currentPassword
: currentPassword // ignore: cast_nullable_to_non_nullable
as String,
failureOrChangePasswordOption: null == failureOrChangePasswordOption
? _value.failureOrChangePasswordOption
: failureOrChangePasswordOption // ignore: cast_nullable_to_non_nullable
as Option<Either<UserFailure, Unit>>,
isSubmitting: null == isSubmitting
? _value.isSubmitting
: isSubmitting // ignore: cast_nullable_to_non_nullable
as bool,
showErrorMessages: null == showErrorMessages
? _value.showErrorMessages
: showErrorMessages // ignore: cast_nullable_to_non_nullable
as bool,
)
as $Val,
);
}
}
/// @nodoc
abstract class _$$ChangePasswordFormStateImplCopyWith<$Res>
implements $ChangePasswordFormStateCopyWith<$Res> {
factory _$$ChangePasswordFormStateImplCopyWith(
_$ChangePasswordFormStateImpl value,
$Res Function(_$ChangePasswordFormStateImpl) then,
) = __$$ChangePasswordFormStateImplCopyWithImpl<$Res>;
@override
@useResult
$Res call({
String newPassword,
String currentPassword,
Option<Either<UserFailure, Unit>> failureOrChangePasswordOption,
bool isSubmitting,
bool showErrorMessages,
});
}
/// @nodoc
class __$$ChangePasswordFormStateImplCopyWithImpl<$Res>
extends
_$ChangePasswordFormStateCopyWithImpl<
$Res,
_$ChangePasswordFormStateImpl
>
implements _$$ChangePasswordFormStateImplCopyWith<$Res> {
__$$ChangePasswordFormStateImplCopyWithImpl(
_$ChangePasswordFormStateImpl _value,
$Res Function(_$ChangePasswordFormStateImpl) _then,
) : super(_value, _then);
/// Create a copy of ChangePasswordFormState
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({
Object? newPassword = null,
Object? currentPassword = null,
Object? failureOrChangePasswordOption = null,
Object? isSubmitting = null,
Object? showErrorMessages = null,
}) {
return _then(
_$ChangePasswordFormStateImpl(
newPassword: null == newPassword
? _value.newPassword
: newPassword // ignore: cast_nullable_to_non_nullable
as String,
currentPassword: null == currentPassword
? _value.currentPassword
: currentPassword // ignore: cast_nullable_to_non_nullable
as String,
failureOrChangePasswordOption: null == failureOrChangePasswordOption
? _value.failureOrChangePasswordOption
: failureOrChangePasswordOption // ignore: cast_nullable_to_non_nullable
as Option<Either<UserFailure, Unit>>,
isSubmitting: null == isSubmitting
? _value.isSubmitting
: isSubmitting // ignore: cast_nullable_to_non_nullable
as bool,
showErrorMessages: null == showErrorMessages
? _value.showErrorMessages
: showErrorMessages // ignore: cast_nullable_to_non_nullable
as bool,
),
);
}
}
/// @nodoc
class _$ChangePasswordFormStateImpl implements _ChangePasswordFormState {
const _$ChangePasswordFormStateImpl({
required this.newPassword,
required this.currentPassword,
required this.failureOrChangePasswordOption,
this.isSubmitting = false,
this.showErrorMessages = false,
});
@override
final String newPassword;
@override
final String currentPassword;
@override
final Option<Either<UserFailure, Unit>> failureOrChangePasswordOption;
@override
@JsonKey()
final bool isSubmitting;
@override
@JsonKey()
final bool showErrorMessages;
@override
String toString() {
return 'ChangePasswordFormState(newPassword: $newPassword, currentPassword: $currentPassword, failureOrChangePasswordOption: $failureOrChangePasswordOption, isSubmitting: $isSubmitting, showErrorMessages: $showErrorMessages)';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType &&
other is _$ChangePasswordFormStateImpl &&
(identical(other.newPassword, newPassword) ||
other.newPassword == newPassword) &&
(identical(other.currentPassword, currentPassword) ||
other.currentPassword == currentPassword) &&
(identical(
other.failureOrChangePasswordOption,
failureOrChangePasswordOption,
) ||
other.failureOrChangePasswordOption ==
failureOrChangePasswordOption) &&
(identical(other.isSubmitting, isSubmitting) ||
other.isSubmitting == isSubmitting) &&
(identical(other.showErrorMessages, showErrorMessages) ||
other.showErrorMessages == showErrorMessages));
}
@override
int get hashCode => Object.hash(
runtimeType,
newPassword,
currentPassword,
failureOrChangePasswordOption,
isSubmitting,
showErrorMessages,
);
/// Create a copy of ChangePasswordFormState
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@override
@pragma('vm:prefer-inline')
_$$ChangePasswordFormStateImplCopyWith<_$ChangePasswordFormStateImpl>
get copyWith =>
__$$ChangePasswordFormStateImplCopyWithImpl<
_$ChangePasswordFormStateImpl
>(this, _$identity);
}
abstract class _ChangePasswordFormState implements ChangePasswordFormState {
const factory _ChangePasswordFormState({
required final String newPassword,
required final String currentPassword,
required final Option<Either<UserFailure, Unit>>
failureOrChangePasswordOption,
final bool isSubmitting,
final bool showErrorMessages,
}) = _$ChangePasswordFormStateImpl;
@override
String get newPassword;
@override
String get currentPassword;
@override
Option<Either<UserFailure, Unit>> get failureOrChangePasswordOption;
@override
bool get isSubmitting;
@override
bool get showErrorMessages;
/// Create a copy of ChangePasswordFormState
/// with the given fields replaced by the non-null parameter values.
@override
@JsonKey(includeFromJson: false, includeToJson: false)
_$$ChangePasswordFormStateImplCopyWith<_$ChangePasswordFormStateImpl>
get copyWith => throw _privateConstructorUsedError;
}

View File

@ -0,0 +1,11 @@
part of 'change_password_form_bloc.dart';
@freezed
class ChangePasswordFormEvent with _$ChangePasswordFormEvent {
const factory ChangePasswordFormEvent.newPasswordChanged(String newPassword) =
_NewPasswordChanged;
const factory ChangePasswordFormEvent.currentPasswordChanged(
String currentPassword,
) = _CurrentPasswordChanged;
const factory ChangePasswordFormEvent.submitted() = _Submitted;
}

View File

@ -0,0 +1,18 @@
part of 'change_password_form_bloc.dart';
@freezed
class ChangePasswordFormState with _$ChangePasswordFormState {
const factory ChangePasswordFormState({
required String newPassword,
required String currentPassword,
required Option<Either<UserFailure, Unit>> failureOrChangePasswordOption,
@Default(false) bool isSubmitting,
@Default(false) bool showErrorMessages,
}) = _ChangePasswordFormState;
factory ChangePasswordFormState.initial() => ChangePasswordFormState(
currentPassword: '',
newPassword: '',
failureOrChangePasswordOption: none(),
);
}

View File

@ -0,0 +1,46 @@
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/user/user.dart';
part 'user_edit_form_event.dart';
part 'user_edit_form_state.dart';
part 'user_edit_form_bloc.freezed.dart';
@injectable
class UserEditFormBloc extends Bloc<UserEditFormEvent, UserEditFormState> {
final IUserRepository _repository;
UserEditFormBloc(this._repository) : super(UserEditFormState.initial()) {
on<UserEditFormEvent>(_onUserEditFormEvent);
}
Future<void> _onUserEditFormEvent(
UserEditFormEvent event,
Emitter<UserEditFormState> emit,
) {
return event.map(
nameChanged: (e) async {
emit(state.copyWith(name: e.name, failureOrUserOption: none()));
},
submitted: (e) async {
Either<UserFailure, User>? failureOrUser;
emit(state.copyWith(isSubmitting: true, failureOrUserOption: none()));
final nameValid = state.name.isNotEmpty;
if (nameValid) {
failureOrUser = await _repository.editUser(name: state.name);
emit(
state.copyWith(
isSubmitting: false,
failureOrUserOption: optionOf(failureOrUser),
),
);
}
emit(state.copyWith(showErrorMessages: true, isSubmitting: false));
},
);
}
}

View File

@ -0,0 +1,542 @@
// 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 'user_edit_form_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 _$UserEditFormEvent {
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function(String name) nameChanged,
required TResult Function() submitted,
}) => throw _privateConstructorUsedError;
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>({
TResult? Function(String name)? nameChanged,
TResult? Function()? submitted,
}) => throw _privateConstructorUsedError;
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({
TResult Function(String name)? nameChanged,
TResult Function()? submitted,
required TResult orElse(),
}) => throw _privateConstructorUsedError;
@optionalTypeArgs
TResult map<TResult extends Object?>({
required TResult Function(_NameChanged value) nameChanged,
required TResult Function(_Submitted value) submitted,
}) => throw _privateConstructorUsedError;
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>({
TResult? Function(_NameChanged value)? nameChanged,
TResult? Function(_Submitted value)? submitted,
}) => throw _privateConstructorUsedError;
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>({
TResult Function(_NameChanged value)? nameChanged,
TResult Function(_Submitted value)? submitted,
required TResult orElse(),
}) => throw _privateConstructorUsedError;
}
/// @nodoc
abstract class $UserEditFormEventCopyWith<$Res> {
factory $UserEditFormEventCopyWith(
UserEditFormEvent value,
$Res Function(UserEditFormEvent) then,
) = _$UserEditFormEventCopyWithImpl<$Res, UserEditFormEvent>;
}
/// @nodoc
class _$UserEditFormEventCopyWithImpl<$Res, $Val extends UserEditFormEvent>
implements $UserEditFormEventCopyWith<$Res> {
_$UserEditFormEventCopyWithImpl(this._value, this._then);
// ignore: unused_field
final $Val _value;
// ignore: unused_field
final $Res Function($Val) _then;
/// Create a copy of UserEditFormEvent
/// with the given fields replaced by the non-null parameter values.
}
/// @nodoc
abstract class _$$NameChangedImplCopyWith<$Res> {
factory _$$NameChangedImplCopyWith(
_$NameChangedImpl value,
$Res Function(_$NameChangedImpl) then,
) = __$$NameChangedImplCopyWithImpl<$Res>;
@useResult
$Res call({String name});
}
/// @nodoc
class __$$NameChangedImplCopyWithImpl<$Res>
extends _$UserEditFormEventCopyWithImpl<$Res, _$NameChangedImpl>
implements _$$NameChangedImplCopyWith<$Res> {
__$$NameChangedImplCopyWithImpl(
_$NameChangedImpl _value,
$Res Function(_$NameChangedImpl) _then,
) : super(_value, _then);
/// Create a copy of UserEditFormEvent
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({Object? name = null}) {
return _then(
_$NameChangedImpl(
null == name
? _value.name
: name // ignore: cast_nullable_to_non_nullable
as String,
),
);
}
}
/// @nodoc
class _$NameChangedImpl implements _NameChanged {
const _$NameChangedImpl(this.name);
@override
final String name;
@override
String toString() {
return 'UserEditFormEvent.nameChanged(name: $name)';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType &&
other is _$NameChangedImpl &&
(identical(other.name, name) || other.name == name));
}
@override
int get hashCode => Object.hash(runtimeType, name);
/// Create a copy of UserEditFormEvent
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@override
@pragma('vm:prefer-inline')
_$$NameChangedImplCopyWith<_$NameChangedImpl> get copyWith =>
__$$NameChangedImplCopyWithImpl<_$NameChangedImpl>(this, _$identity);
@override
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function(String name) nameChanged,
required TResult Function() submitted,
}) {
return nameChanged(name);
}
@override
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>({
TResult? Function(String name)? nameChanged,
TResult? Function()? submitted,
}) {
return nameChanged?.call(name);
}
@override
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({
TResult Function(String name)? nameChanged,
TResult Function()? submitted,
required TResult orElse(),
}) {
if (nameChanged != null) {
return nameChanged(name);
}
return orElse();
}
@override
@optionalTypeArgs
TResult map<TResult extends Object?>({
required TResult Function(_NameChanged value) nameChanged,
required TResult Function(_Submitted value) submitted,
}) {
return nameChanged(this);
}
@override
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>({
TResult? Function(_NameChanged value)? nameChanged,
TResult? Function(_Submitted value)? submitted,
}) {
return nameChanged?.call(this);
}
@override
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>({
TResult Function(_NameChanged value)? nameChanged,
TResult Function(_Submitted value)? submitted,
required TResult orElse(),
}) {
if (nameChanged != null) {
return nameChanged(this);
}
return orElse();
}
}
abstract class _NameChanged implements UserEditFormEvent {
const factory _NameChanged(final String name) = _$NameChangedImpl;
String get name;
/// Create a copy of UserEditFormEvent
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
_$$NameChangedImplCopyWith<_$NameChangedImpl> get copyWith =>
throw _privateConstructorUsedError;
}
/// @nodoc
abstract class _$$SubmittedImplCopyWith<$Res> {
factory _$$SubmittedImplCopyWith(
_$SubmittedImpl value,
$Res Function(_$SubmittedImpl) then,
) = __$$SubmittedImplCopyWithImpl<$Res>;
}
/// @nodoc
class __$$SubmittedImplCopyWithImpl<$Res>
extends _$UserEditFormEventCopyWithImpl<$Res, _$SubmittedImpl>
implements _$$SubmittedImplCopyWith<$Res> {
__$$SubmittedImplCopyWithImpl(
_$SubmittedImpl _value,
$Res Function(_$SubmittedImpl) _then,
) : super(_value, _then);
/// Create a copy of UserEditFormEvent
/// with the given fields replaced by the non-null parameter values.
}
/// @nodoc
class _$SubmittedImpl implements _Submitted {
const _$SubmittedImpl();
@override
String toString() {
return 'UserEditFormEvent.submitted()';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType && other is _$SubmittedImpl);
}
@override
int get hashCode => runtimeType.hashCode;
@override
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function(String name) nameChanged,
required TResult Function() submitted,
}) {
return submitted();
}
@override
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>({
TResult? Function(String name)? nameChanged,
TResult? Function()? submitted,
}) {
return submitted?.call();
}
@override
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({
TResult Function(String name)? nameChanged,
TResult Function()? submitted,
required TResult orElse(),
}) {
if (submitted != null) {
return submitted();
}
return orElse();
}
@override
@optionalTypeArgs
TResult map<TResult extends Object?>({
required TResult Function(_NameChanged value) nameChanged,
required TResult Function(_Submitted value) submitted,
}) {
return submitted(this);
}
@override
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>({
TResult? Function(_NameChanged value)? nameChanged,
TResult? Function(_Submitted value)? submitted,
}) {
return submitted?.call(this);
}
@override
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>({
TResult Function(_NameChanged value)? nameChanged,
TResult Function(_Submitted value)? submitted,
required TResult orElse(),
}) {
if (submitted != null) {
return submitted(this);
}
return orElse();
}
}
abstract class _Submitted implements UserEditFormEvent {
const factory _Submitted() = _$SubmittedImpl;
}
/// @nodoc
mixin _$UserEditFormState {
String get name => throw _privateConstructorUsedError;
Option<Either<UserFailure, User>> get failureOrUserOption =>
throw _privateConstructorUsedError;
bool get isSubmitting => throw _privateConstructorUsedError;
bool get showErrorMessages => throw _privateConstructorUsedError;
/// Create a copy of UserEditFormState
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
$UserEditFormStateCopyWith<UserEditFormState> get copyWith =>
throw _privateConstructorUsedError;
}
/// @nodoc
abstract class $UserEditFormStateCopyWith<$Res> {
factory $UserEditFormStateCopyWith(
UserEditFormState value,
$Res Function(UserEditFormState) then,
) = _$UserEditFormStateCopyWithImpl<$Res, UserEditFormState>;
@useResult
$Res call({
String name,
Option<Either<UserFailure, User>> failureOrUserOption,
bool isSubmitting,
bool showErrorMessages,
});
}
/// @nodoc
class _$UserEditFormStateCopyWithImpl<$Res, $Val extends UserEditFormState>
implements $UserEditFormStateCopyWith<$Res> {
_$UserEditFormStateCopyWithImpl(this._value, this._then);
// ignore: unused_field
final $Val _value;
// ignore: unused_field
final $Res Function($Val) _then;
/// Create a copy of UserEditFormState
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({
Object? name = null,
Object? failureOrUserOption = null,
Object? isSubmitting = null,
Object? showErrorMessages = null,
}) {
return _then(
_value.copyWith(
name: null == name
? _value.name
: name // ignore: cast_nullable_to_non_nullable
as String,
failureOrUserOption: null == failureOrUserOption
? _value.failureOrUserOption
: failureOrUserOption // ignore: cast_nullable_to_non_nullable
as Option<Either<UserFailure, User>>,
isSubmitting: null == isSubmitting
? _value.isSubmitting
: isSubmitting // ignore: cast_nullable_to_non_nullable
as bool,
showErrorMessages: null == showErrorMessages
? _value.showErrorMessages
: showErrorMessages // ignore: cast_nullable_to_non_nullable
as bool,
)
as $Val,
);
}
}
/// @nodoc
abstract class _$$UserEditFormStateImplCopyWith<$Res>
implements $UserEditFormStateCopyWith<$Res> {
factory _$$UserEditFormStateImplCopyWith(
_$UserEditFormStateImpl value,
$Res Function(_$UserEditFormStateImpl) then,
) = __$$UserEditFormStateImplCopyWithImpl<$Res>;
@override
@useResult
$Res call({
String name,
Option<Either<UserFailure, User>> failureOrUserOption,
bool isSubmitting,
bool showErrorMessages,
});
}
/// @nodoc
class __$$UserEditFormStateImplCopyWithImpl<$Res>
extends _$UserEditFormStateCopyWithImpl<$Res, _$UserEditFormStateImpl>
implements _$$UserEditFormStateImplCopyWith<$Res> {
__$$UserEditFormStateImplCopyWithImpl(
_$UserEditFormStateImpl _value,
$Res Function(_$UserEditFormStateImpl) _then,
) : super(_value, _then);
/// Create a copy of UserEditFormState
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({
Object? name = null,
Object? failureOrUserOption = null,
Object? isSubmitting = null,
Object? showErrorMessages = null,
}) {
return _then(
_$UserEditFormStateImpl(
name: null == name
? _value.name
: name // ignore: cast_nullable_to_non_nullable
as String,
failureOrUserOption: null == failureOrUserOption
? _value.failureOrUserOption
: failureOrUserOption // ignore: cast_nullable_to_non_nullable
as Option<Either<UserFailure, User>>,
isSubmitting: null == isSubmitting
? _value.isSubmitting
: isSubmitting // ignore: cast_nullable_to_non_nullable
as bool,
showErrorMessages: null == showErrorMessages
? _value.showErrorMessages
: showErrorMessages // ignore: cast_nullable_to_non_nullable
as bool,
),
);
}
}
/// @nodoc
class _$UserEditFormStateImpl implements _UserEditFormState {
const _$UserEditFormStateImpl({
required this.name,
required this.failureOrUserOption,
this.isSubmitting = false,
this.showErrorMessages = false,
});
@override
final String name;
@override
final Option<Either<UserFailure, User>> failureOrUserOption;
@override
@JsonKey()
final bool isSubmitting;
@override
@JsonKey()
final bool showErrorMessages;
@override
String toString() {
return 'UserEditFormState(name: $name, failureOrUserOption: $failureOrUserOption, isSubmitting: $isSubmitting, showErrorMessages: $showErrorMessages)';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType &&
other is _$UserEditFormStateImpl &&
(identical(other.name, name) || other.name == name) &&
(identical(other.failureOrUserOption, failureOrUserOption) ||
other.failureOrUserOption == failureOrUserOption) &&
(identical(other.isSubmitting, isSubmitting) ||
other.isSubmitting == isSubmitting) &&
(identical(other.showErrorMessages, showErrorMessages) ||
other.showErrorMessages == showErrorMessages));
}
@override
int get hashCode => Object.hash(
runtimeType,
name,
failureOrUserOption,
isSubmitting,
showErrorMessages,
);
/// Create a copy of UserEditFormState
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@override
@pragma('vm:prefer-inline')
_$$UserEditFormStateImplCopyWith<_$UserEditFormStateImpl> get copyWith =>
__$$UserEditFormStateImplCopyWithImpl<_$UserEditFormStateImpl>(
this,
_$identity,
);
}
abstract class _UserEditFormState implements UserEditFormState {
const factory _UserEditFormState({
required final String name,
required final Option<Either<UserFailure, User>> failureOrUserOption,
final bool isSubmitting,
final bool showErrorMessages,
}) = _$UserEditFormStateImpl;
@override
String get name;
@override
Option<Either<UserFailure, User>> get failureOrUserOption;
@override
bool get isSubmitting;
@override
bool get showErrorMessages;
/// Create a copy of UserEditFormState
/// with the given fields replaced by the non-null parameter values.
@override
@JsonKey(includeFromJson: false, includeToJson: false)
_$$UserEditFormStateImplCopyWith<_$UserEditFormStateImpl> get copyWith =>
throw _privateConstructorUsedError;
}

View File

@ -0,0 +1,7 @@
part of 'user_edit_form_bloc.dart';
@freezed
class UserEditFormEvent with _$UserEditFormEvent {
const factory UserEditFormEvent.nameChanged(String name) = _NameChanged;
const factory UserEditFormEvent.submitted() = _Submitted;
}

View File

@ -0,0 +1,14 @@
part of 'user_edit_form_bloc.dart';
@freezed
class UserEditFormState with _$UserEditFormState {
const factory UserEditFormState({
required String name,
required Option<Either<UserFailure, User>> failureOrUserOption,
@Default(false) bool isSubmitting,
@Default(false) bool showErrorMessages,
}) = _UserEditFormState;
factory UserEditFormState.initial() =>
UserEditFormState(name: '', failureOrUserOption: none());
}

View File

@ -30,4 +30,7 @@ class ApiPath {
// Outlet
static const String outlet = '/api/v1/outlets';
// User
static const String user = '/api/v1/users';
}

View File

@ -0,0 +1,79 @@
import 'dart:developer';
import 'dart:io';
import 'package:open_file/open_file.dart';
import 'package:path_provider/path_provider.dart';
import 'package:pdf/widgets.dart';
class HelperPdfService {
static Future<File> saveDocument({
required String name,
required Document pdf,
}) async {
try {
log("Starting PDF save process for: $name");
log("PDF document object: $pdf");
final bytes = await pdf.save();
log("PDF bytes generated successfully, size: ${bytes.length} bytes");
if (bytes.isEmpty) {
log("WARNING: PDF bytes are empty!");
return Future.error("PDF bytes are empty");
}
final dir = await getApplicationDocumentsDirectory();
log("Documents directory: ${dir.path}");
final file = File('${dir.path}/$name');
log("Saving PDF to: ${file.path}");
await file.writeAsBytes(bytes);
log("PDF saved successfully to: ${file.path}");
// Verify file was created
if (await file.exists()) {
final fileSize = await file.length();
log("File exists and size is: $fileSize bytes");
} else {
log("ERROR: File was not created!");
return Future.error("File was not created");
}
return file;
} catch (e) {
log("Failed to save document: $e");
log("Error stack trace: ${StackTrace.current}");
return Future.error("Failed to save document: $e");
}
}
static Future openFile(File file) async {
try {
final url = file.path;
log("Attempting to open file: $url");
if (!await file.exists()) {
log("ERROR: File does not exist: $url");
return;
}
final fileSize = await file.length();
log("File exists and size is: $fileSize bytes");
log("Calling OpenFile.open...");
final result = await OpenFile.open(url, type: "application/pdf");
log("OpenFile result: $result");
if (result.type == ResultType.done) {
log("File opened successfully");
} else {
log("File opening failed with result: ${result.type}");
log("Error message: ${result.message}");
}
} catch (e) {
log("Failed to open file: $e");
log("Error stack trace: ${StackTrace.current}");
}
}
}

View File

@ -0,0 +1,72 @@
import 'dart:developer';
import 'package:device_info_plus/device_info_plus.dart';
import 'package:permission_handler/permission_handler.dart';
class PermessionHelper {
Future<bool> checkPermission() async {
final deviceInfo = await DeviceInfoPlugin().androidInfo;
bool permissionStatus;
if (deviceInfo.version.sdkInt > 32) {
permissionStatus = await Permission.photos.request().isGranted;
} else {
permissionStatus = await Permission.storage.request().isGranted;
}
if (permissionStatus) {
log('Izin penyimpanan sudah diberikan.');
} else {
if (deviceInfo.version.sdkInt > 32) {
log('deviceInfo.version.sdkInt > 32.');
permissionStatus = await Permission.photos.request().isGranted;
} else {
permissionStatus = await Permission.storage.request().isGranted;
}
// } else {
// openAppSettings();
// }
}
log('permissionStatus: $permissionStatus');
return permissionStatus;
}
void permessionPrinter() async {
Map<Permission, PermissionStatus> statuses = await [
Permission.bluetooth,
Permission.bluetoothScan,
Permission.bluetoothAdvertise,
Permission.bluetoothConnect,
].request();
log("statuses: $statuses");
}
}
// try {
// final status =
// await PermessionHelper().checkPermission();
// if (status) {
// final pdfFile = await InventoryReport.previewPdf(
// searchDateFormatted: widget.searchDateFormatted,
// inventory: widget.inventory,
// );
// log("pdfFile: $pdfFile");
// await HelperPdfService.openFile(pdfFile);
// } else {
// ScaffoldMessenger.of(context).showSnackBar(
// const SnackBar(
// content: Text(
// 'Storage permission is required to save PDF'),
// backgroundColor: Colors.red,
// ),
// );
// }
// } catch (e) {
// log("Error generating PDF: $e");
// ScaffoldMessenger.of(context).showSnackBar(
// SnackBar(
// content: Text('Failed to generate PDF: $e'),
// backgroundColor: Colors.red,
// ),
// );
// }

View File

@ -2,10 +2,10 @@ import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:dartz/dartz.dart';
import '../../common/api/api_failure.dart';
import '../user/user.dart';
part 'failures/auth_failure.dart';
part 'repositories/i_auth_repository.dart';
part 'entities/auth_entity.dart';
part 'entities/user_entity.dart';
part 'auth.freezed.dart';

View File

@ -691,349 +691,3 @@ abstract class _Auth extends Auth {
_$$AuthImplCopyWith<_$AuthImpl> get copyWith =>
throw _privateConstructorUsedError;
}
/// @nodoc
mixin _$User {
String get id => throw _privateConstructorUsedError;
String get organizationId => throw _privateConstructorUsedError;
String get outletId => throw _privateConstructorUsedError;
String get name => throw _privateConstructorUsedError;
String get email => throw _privateConstructorUsedError;
String get role => throw _privateConstructorUsedError;
Map<String, dynamic> get permissions => throw _privateConstructorUsedError;
bool get isActive => throw _privateConstructorUsedError;
DateTime get createdAt => throw _privateConstructorUsedError;
DateTime get updatedAt => throw _privateConstructorUsedError;
/// Create a copy of User
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
$UserCopyWith<User> get copyWith => throw _privateConstructorUsedError;
}
/// @nodoc
abstract class $UserCopyWith<$Res> {
factory $UserCopyWith(User value, $Res Function(User) then) =
_$UserCopyWithImpl<$Res, User>;
@useResult
$Res call({
String id,
String organizationId,
String outletId,
String name,
String email,
String role,
Map<String, dynamic> permissions,
bool isActive,
DateTime createdAt,
DateTime updatedAt,
});
}
/// @nodoc
class _$UserCopyWithImpl<$Res, $Val extends User>
implements $UserCopyWith<$Res> {
_$UserCopyWithImpl(this._value, this._then);
// ignore: unused_field
final $Val _value;
// ignore: unused_field
final $Res Function($Val) _then;
/// Create a copy of User
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({
Object? id = null,
Object? organizationId = null,
Object? outletId = null,
Object? name = null,
Object? email = null,
Object? role = null,
Object? permissions = null,
Object? isActive = null,
Object? createdAt = null,
Object? updatedAt = null,
}) {
return _then(
_value.copyWith(
id: null == id
? _value.id
: id // ignore: cast_nullable_to_non_nullable
as String,
organizationId: null == organizationId
? _value.organizationId
: organizationId // ignore: cast_nullable_to_non_nullable
as String,
outletId: null == outletId
? _value.outletId
: outletId // ignore: cast_nullable_to_non_nullable
as String,
name: null == name
? _value.name
: name // ignore: cast_nullable_to_non_nullable
as String,
email: null == email
? _value.email
: email // ignore: cast_nullable_to_non_nullable
as String,
role: null == role
? _value.role
: role // ignore: cast_nullable_to_non_nullable
as String,
permissions: null == permissions
? _value.permissions
: permissions // ignore: cast_nullable_to_non_nullable
as Map<String, dynamic>,
isActive: null == isActive
? _value.isActive
: isActive // ignore: cast_nullable_to_non_nullable
as bool,
createdAt: null == createdAt
? _value.createdAt
: createdAt // ignore: cast_nullable_to_non_nullable
as DateTime,
updatedAt: null == updatedAt
? _value.updatedAt
: updatedAt // ignore: cast_nullable_to_non_nullable
as DateTime,
)
as $Val,
);
}
}
/// @nodoc
abstract class _$$UserImplCopyWith<$Res> implements $UserCopyWith<$Res> {
factory _$$UserImplCopyWith(
_$UserImpl value,
$Res Function(_$UserImpl) then,
) = __$$UserImplCopyWithImpl<$Res>;
@override
@useResult
$Res call({
String id,
String organizationId,
String outletId,
String name,
String email,
String role,
Map<String, dynamic> permissions,
bool isActive,
DateTime createdAt,
DateTime updatedAt,
});
}
/// @nodoc
class __$$UserImplCopyWithImpl<$Res>
extends _$UserCopyWithImpl<$Res, _$UserImpl>
implements _$$UserImplCopyWith<$Res> {
__$$UserImplCopyWithImpl(_$UserImpl _value, $Res Function(_$UserImpl) _then)
: super(_value, _then);
/// Create a copy of User
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({
Object? id = null,
Object? organizationId = null,
Object? outletId = null,
Object? name = null,
Object? email = null,
Object? role = null,
Object? permissions = null,
Object? isActive = null,
Object? createdAt = null,
Object? updatedAt = null,
}) {
return _then(
_$UserImpl(
id: null == id
? _value.id
: id // ignore: cast_nullable_to_non_nullable
as String,
organizationId: null == organizationId
? _value.organizationId
: organizationId // ignore: cast_nullable_to_non_nullable
as String,
outletId: null == outletId
? _value.outletId
: outletId // ignore: cast_nullable_to_non_nullable
as String,
name: null == name
? _value.name
: name // ignore: cast_nullable_to_non_nullable
as String,
email: null == email
? _value.email
: email // ignore: cast_nullable_to_non_nullable
as String,
role: null == role
? _value.role
: role // ignore: cast_nullable_to_non_nullable
as String,
permissions: null == permissions
? _value._permissions
: permissions // ignore: cast_nullable_to_non_nullable
as Map<String, dynamic>,
isActive: null == isActive
? _value.isActive
: isActive // ignore: cast_nullable_to_non_nullable
as bool,
createdAt: null == createdAt
? _value.createdAt
: createdAt // ignore: cast_nullable_to_non_nullable
as DateTime,
updatedAt: null == updatedAt
? _value.updatedAt
: updatedAt // ignore: cast_nullable_to_non_nullable
as DateTime,
),
);
}
}
/// @nodoc
class _$UserImpl extends _User {
const _$UserImpl({
required this.id,
required this.organizationId,
required this.outletId,
required this.name,
required this.email,
required this.role,
required final Map<String, dynamic> permissions,
required this.isActive,
required this.createdAt,
required this.updatedAt,
}) : _permissions = permissions,
super._();
@override
final String id;
@override
final String organizationId;
@override
final String outletId;
@override
final String name;
@override
final String email;
@override
final String role;
final Map<String, dynamic> _permissions;
@override
Map<String, dynamic> get permissions {
if (_permissions is EqualUnmodifiableMapView) return _permissions;
// ignore: implicit_dynamic_type
return EqualUnmodifiableMapView(_permissions);
}
@override
final bool isActive;
@override
final DateTime createdAt;
@override
final DateTime updatedAt;
@override
String toString() {
return 'User(id: $id, organizationId: $organizationId, outletId: $outletId, name: $name, email: $email, role: $role, permissions: $permissions, isActive: $isActive, createdAt: $createdAt, updatedAt: $updatedAt)';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType &&
other is _$UserImpl &&
(identical(other.id, id) || other.id == id) &&
(identical(other.organizationId, organizationId) ||
other.organizationId == organizationId) &&
(identical(other.outletId, outletId) ||
other.outletId == outletId) &&
(identical(other.name, name) || other.name == name) &&
(identical(other.email, email) || other.email == email) &&
(identical(other.role, role) || other.role == role) &&
const DeepCollectionEquality().equals(
other._permissions,
_permissions,
) &&
(identical(other.isActive, isActive) ||
other.isActive == isActive) &&
(identical(other.createdAt, createdAt) ||
other.createdAt == createdAt) &&
(identical(other.updatedAt, updatedAt) ||
other.updatedAt == updatedAt));
}
@override
int get hashCode => Object.hash(
runtimeType,
id,
organizationId,
outletId,
name,
email,
role,
const DeepCollectionEquality().hash(_permissions),
isActive,
createdAt,
updatedAt,
);
/// Create a copy of User
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@override
@pragma('vm:prefer-inline')
_$$UserImplCopyWith<_$UserImpl> get copyWith =>
__$$UserImplCopyWithImpl<_$UserImpl>(this, _$identity);
}
abstract class _User extends User {
const factory _User({
required final String id,
required final String organizationId,
required final String outletId,
required final String name,
required final String email,
required final String role,
required final Map<String, dynamic> permissions,
required final bool isActive,
required final DateTime createdAt,
required final DateTime updatedAt,
}) = _$UserImpl;
const _User._() : super._();
@override
String get id;
@override
String get organizationId;
@override
String get outletId;
@override
String get name;
@override
String get email;
@override
String get role;
@override
Map<String, dynamic> get permissions;
@override
bool get isActive;
@override
DateTime get createdAt;
@override
DateTime get updatedAt;
/// Create a copy of User
/// with the given fields replaced by the non-null parameter values.
@override
@JsonKey(includeFromJson: false, includeToJson: false)
_$$UserImplCopyWith<_$UserImpl> get copyWith =>
throw _privateConstructorUsedError;
}

View File

@ -1,4 +1,4 @@
part of '../auth.dart';
part of '../user.dart';
@freezed
class User with _$User {

View File

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

View File

@ -0,0 +1,9 @@
part of '../user.dart';
abstract class IUserRepository {
Future<Either<UserFailure, User>> editUser({required String name});
Future<Either<UserFailure, Unit>> changePassword({
required String newPassword,
required String currentPassword,
});
}

10
lib/domain/user/user.dart Normal file
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 'user.freezed.dart';
part 'entities/user_entity.dart';
part 'failures/user_failure.dart';
part 'repositories/i_user_repository.dart';

View File

@ -0,0 +1,995 @@
// 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 'user.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 _$User {
String get id => throw _privateConstructorUsedError;
String get organizationId => throw _privateConstructorUsedError;
String get outletId => throw _privateConstructorUsedError;
String get name => throw _privateConstructorUsedError;
String get email => throw _privateConstructorUsedError;
String get role => throw _privateConstructorUsedError;
Map<String, dynamic> get permissions => throw _privateConstructorUsedError;
bool get isActive => throw _privateConstructorUsedError;
DateTime get createdAt => throw _privateConstructorUsedError;
DateTime get updatedAt => throw _privateConstructorUsedError;
/// Create a copy of User
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
$UserCopyWith<User> get copyWith => throw _privateConstructorUsedError;
}
/// @nodoc
abstract class $UserCopyWith<$Res> {
factory $UserCopyWith(User value, $Res Function(User) then) =
_$UserCopyWithImpl<$Res, User>;
@useResult
$Res call({
String id,
String organizationId,
String outletId,
String name,
String email,
String role,
Map<String, dynamic> permissions,
bool isActive,
DateTime createdAt,
DateTime updatedAt,
});
}
/// @nodoc
class _$UserCopyWithImpl<$Res, $Val extends User>
implements $UserCopyWith<$Res> {
_$UserCopyWithImpl(this._value, this._then);
// ignore: unused_field
final $Val _value;
// ignore: unused_field
final $Res Function($Val) _then;
/// Create a copy of User
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({
Object? id = null,
Object? organizationId = null,
Object? outletId = null,
Object? name = null,
Object? email = null,
Object? role = null,
Object? permissions = null,
Object? isActive = null,
Object? createdAt = null,
Object? updatedAt = null,
}) {
return _then(
_value.copyWith(
id: null == id
? _value.id
: id // ignore: cast_nullable_to_non_nullable
as String,
organizationId: null == organizationId
? _value.organizationId
: organizationId // ignore: cast_nullable_to_non_nullable
as String,
outletId: null == outletId
? _value.outletId
: outletId // ignore: cast_nullable_to_non_nullable
as String,
name: null == name
? _value.name
: name // ignore: cast_nullable_to_non_nullable
as String,
email: null == email
? _value.email
: email // ignore: cast_nullable_to_non_nullable
as String,
role: null == role
? _value.role
: role // ignore: cast_nullable_to_non_nullable
as String,
permissions: null == permissions
? _value.permissions
: permissions // ignore: cast_nullable_to_non_nullable
as Map<String, dynamic>,
isActive: null == isActive
? _value.isActive
: isActive // ignore: cast_nullable_to_non_nullable
as bool,
createdAt: null == createdAt
? _value.createdAt
: createdAt // ignore: cast_nullable_to_non_nullable
as DateTime,
updatedAt: null == updatedAt
? _value.updatedAt
: updatedAt // ignore: cast_nullable_to_non_nullable
as DateTime,
)
as $Val,
);
}
}
/// @nodoc
abstract class _$$UserImplCopyWith<$Res> implements $UserCopyWith<$Res> {
factory _$$UserImplCopyWith(
_$UserImpl value,
$Res Function(_$UserImpl) then,
) = __$$UserImplCopyWithImpl<$Res>;
@override
@useResult
$Res call({
String id,
String organizationId,
String outletId,
String name,
String email,
String role,
Map<String, dynamic> permissions,
bool isActive,
DateTime createdAt,
DateTime updatedAt,
});
}
/// @nodoc
class __$$UserImplCopyWithImpl<$Res>
extends _$UserCopyWithImpl<$Res, _$UserImpl>
implements _$$UserImplCopyWith<$Res> {
__$$UserImplCopyWithImpl(_$UserImpl _value, $Res Function(_$UserImpl) _then)
: super(_value, _then);
/// Create a copy of User
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({
Object? id = null,
Object? organizationId = null,
Object? outletId = null,
Object? name = null,
Object? email = null,
Object? role = null,
Object? permissions = null,
Object? isActive = null,
Object? createdAt = null,
Object? updatedAt = null,
}) {
return _then(
_$UserImpl(
id: null == id
? _value.id
: id // ignore: cast_nullable_to_non_nullable
as String,
organizationId: null == organizationId
? _value.organizationId
: organizationId // ignore: cast_nullable_to_non_nullable
as String,
outletId: null == outletId
? _value.outletId
: outletId // ignore: cast_nullable_to_non_nullable
as String,
name: null == name
? _value.name
: name // ignore: cast_nullable_to_non_nullable
as String,
email: null == email
? _value.email
: email // ignore: cast_nullable_to_non_nullable
as String,
role: null == role
? _value.role
: role // ignore: cast_nullable_to_non_nullable
as String,
permissions: null == permissions
? _value._permissions
: permissions // ignore: cast_nullable_to_non_nullable
as Map<String, dynamic>,
isActive: null == isActive
? _value.isActive
: isActive // ignore: cast_nullable_to_non_nullable
as bool,
createdAt: null == createdAt
? _value.createdAt
: createdAt // ignore: cast_nullable_to_non_nullable
as DateTime,
updatedAt: null == updatedAt
? _value.updatedAt
: updatedAt // ignore: cast_nullable_to_non_nullable
as DateTime,
),
);
}
}
/// @nodoc
class _$UserImpl extends _User {
const _$UserImpl({
required this.id,
required this.organizationId,
required this.outletId,
required this.name,
required this.email,
required this.role,
required final Map<String, dynamic> permissions,
required this.isActive,
required this.createdAt,
required this.updatedAt,
}) : _permissions = permissions,
super._();
@override
final String id;
@override
final String organizationId;
@override
final String outletId;
@override
final String name;
@override
final String email;
@override
final String role;
final Map<String, dynamic> _permissions;
@override
Map<String, dynamic> get permissions {
if (_permissions is EqualUnmodifiableMapView) return _permissions;
// ignore: implicit_dynamic_type
return EqualUnmodifiableMapView(_permissions);
}
@override
final bool isActive;
@override
final DateTime createdAt;
@override
final DateTime updatedAt;
@override
String toString() {
return 'User(id: $id, organizationId: $organizationId, outletId: $outletId, name: $name, email: $email, role: $role, permissions: $permissions, isActive: $isActive, createdAt: $createdAt, updatedAt: $updatedAt)';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType &&
other is _$UserImpl &&
(identical(other.id, id) || other.id == id) &&
(identical(other.organizationId, organizationId) ||
other.organizationId == organizationId) &&
(identical(other.outletId, outletId) ||
other.outletId == outletId) &&
(identical(other.name, name) || other.name == name) &&
(identical(other.email, email) || other.email == email) &&
(identical(other.role, role) || other.role == role) &&
const DeepCollectionEquality().equals(
other._permissions,
_permissions,
) &&
(identical(other.isActive, isActive) ||
other.isActive == isActive) &&
(identical(other.createdAt, createdAt) ||
other.createdAt == createdAt) &&
(identical(other.updatedAt, updatedAt) ||
other.updatedAt == updatedAt));
}
@override
int get hashCode => Object.hash(
runtimeType,
id,
organizationId,
outletId,
name,
email,
role,
const DeepCollectionEquality().hash(_permissions),
isActive,
createdAt,
updatedAt,
);
/// Create a copy of User
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@override
@pragma('vm:prefer-inline')
_$$UserImplCopyWith<_$UserImpl> get copyWith =>
__$$UserImplCopyWithImpl<_$UserImpl>(this, _$identity);
}
abstract class _User extends User {
const factory _User({
required final String id,
required final String organizationId,
required final String outletId,
required final String name,
required final String email,
required final String role,
required final Map<String, dynamic> permissions,
required final bool isActive,
required final DateTime createdAt,
required final DateTime updatedAt,
}) = _$UserImpl;
const _User._() : super._();
@override
String get id;
@override
String get organizationId;
@override
String get outletId;
@override
String get name;
@override
String get email;
@override
String get role;
@override
Map<String, dynamic> get permissions;
@override
bool get isActive;
@override
DateTime get createdAt;
@override
DateTime get updatedAt;
/// Create a copy of User
/// with the given fields replaced by the non-null parameter values.
@override
@JsonKey(includeFromJson: false, includeToJson: false)
_$$UserImplCopyWith<_$UserImpl> get copyWith =>
throw _privateConstructorUsedError;
}
/// @nodoc
mixin _$UserFailure {
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function(ApiFailure failure) serverError,
required TResult Function() unexpectedError,
required TResult Function() empty,
required TResult Function(String erroMessage) dynamicErrorMessage,
}) => throw _privateConstructorUsedError;
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>({
TResult? Function(ApiFailure failure)? serverError,
TResult? Function()? unexpectedError,
TResult? Function()? empty,
TResult? Function(String erroMessage)? dynamicErrorMessage,
}) => throw _privateConstructorUsedError;
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({
TResult Function(ApiFailure failure)? serverError,
TResult Function()? unexpectedError,
TResult Function()? empty,
TResult Function(String erroMessage)? dynamicErrorMessage,
required TResult orElse(),
}) => throw _privateConstructorUsedError;
@optionalTypeArgs
TResult map<TResult extends Object?>({
required TResult Function(_ServerError value) serverError,
required TResult Function(_UnexpectedError value) unexpectedError,
required TResult Function(_Empty value) empty,
required TResult Function(_DynamicErrorMessage value) dynamicErrorMessage,
}) => throw _privateConstructorUsedError;
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>({
TResult? Function(_ServerError value)? serverError,
TResult? Function(_UnexpectedError value)? unexpectedError,
TResult? Function(_Empty value)? empty,
TResult? Function(_DynamicErrorMessage value)? dynamicErrorMessage,
}) => throw _privateConstructorUsedError;
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>({
TResult Function(_ServerError value)? serverError,
TResult Function(_UnexpectedError value)? unexpectedError,
TResult Function(_Empty value)? empty,
TResult Function(_DynamicErrorMessage value)? dynamicErrorMessage,
required TResult orElse(),
}) => throw _privateConstructorUsedError;
}
/// @nodoc
abstract class $UserFailureCopyWith<$Res> {
factory $UserFailureCopyWith(
UserFailure value,
$Res Function(UserFailure) then,
) = _$UserFailureCopyWithImpl<$Res, UserFailure>;
}
/// @nodoc
class _$UserFailureCopyWithImpl<$Res, $Val extends UserFailure>
implements $UserFailureCopyWith<$Res> {
_$UserFailureCopyWithImpl(this._value, this._then);
// ignore: unused_field
final $Val _value;
// ignore: unused_field
final $Res Function($Val) _then;
/// Create a copy of UserFailure
/// with the given fields replaced by the non-null parameter values.
}
/// @nodoc
abstract class _$$ServerErrorImplCopyWith<$Res> {
factory _$$ServerErrorImplCopyWith(
_$ServerErrorImpl value,
$Res Function(_$ServerErrorImpl) then,
) = __$$ServerErrorImplCopyWithImpl<$Res>;
@useResult
$Res call({ApiFailure failure});
$ApiFailureCopyWith<$Res> get failure;
}
/// @nodoc
class __$$ServerErrorImplCopyWithImpl<$Res>
extends _$UserFailureCopyWithImpl<$Res, _$ServerErrorImpl>
implements _$$ServerErrorImplCopyWith<$Res> {
__$$ServerErrorImplCopyWithImpl(
_$ServerErrorImpl _value,
$Res Function(_$ServerErrorImpl) _then,
) : super(_value, _then);
/// Create a copy of UserFailure
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({Object? failure = null}) {
return _then(
_$ServerErrorImpl(
null == failure
? _value.failure
: failure // ignore: cast_nullable_to_non_nullable
as ApiFailure,
),
);
}
/// Create a copy of UserFailure
/// with the given fields replaced by the non-null parameter values.
@override
@pragma('vm:prefer-inline')
$ApiFailureCopyWith<$Res> get failure {
return $ApiFailureCopyWith<$Res>(_value.failure, (value) {
return _then(_value.copyWith(failure: value));
});
}
}
/// @nodoc
class _$ServerErrorImpl implements _ServerError {
const _$ServerErrorImpl(this.failure);
@override
final ApiFailure failure;
@override
String toString() {
return 'UserFailure.serverError(failure: $failure)';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType &&
other is _$ServerErrorImpl &&
(identical(other.failure, failure) || other.failure == failure));
}
@override
int get hashCode => Object.hash(runtimeType, failure);
/// Create a copy of UserFailure
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@override
@pragma('vm:prefer-inline')
_$$ServerErrorImplCopyWith<_$ServerErrorImpl> get copyWith =>
__$$ServerErrorImplCopyWithImpl<_$ServerErrorImpl>(this, _$identity);
@override
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function(ApiFailure failure) serverError,
required TResult Function() unexpectedError,
required TResult Function() empty,
required TResult Function(String erroMessage) dynamicErrorMessage,
}) {
return serverError(failure);
}
@override
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>({
TResult? Function(ApiFailure failure)? serverError,
TResult? Function()? unexpectedError,
TResult? Function()? empty,
TResult? Function(String erroMessage)? dynamicErrorMessage,
}) {
return serverError?.call(failure);
}
@override
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({
TResult Function(ApiFailure failure)? serverError,
TResult Function()? unexpectedError,
TResult Function()? empty,
TResult Function(String erroMessage)? dynamicErrorMessage,
required TResult orElse(),
}) {
if (serverError != null) {
return serverError(failure);
}
return orElse();
}
@override
@optionalTypeArgs
TResult map<TResult extends Object?>({
required TResult Function(_ServerError value) serverError,
required TResult Function(_UnexpectedError value) unexpectedError,
required TResult Function(_Empty value) empty,
required TResult Function(_DynamicErrorMessage value) dynamicErrorMessage,
}) {
return serverError(this);
}
@override
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>({
TResult? Function(_ServerError value)? serverError,
TResult? Function(_UnexpectedError value)? unexpectedError,
TResult? Function(_Empty value)? empty,
TResult? Function(_DynamicErrorMessage value)? dynamicErrorMessage,
}) {
return serverError?.call(this);
}
@override
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>({
TResult Function(_ServerError value)? serverError,
TResult Function(_UnexpectedError value)? unexpectedError,
TResult Function(_Empty value)? empty,
TResult Function(_DynamicErrorMessage value)? dynamicErrorMessage,
required TResult orElse(),
}) {
if (serverError != null) {
return serverError(this);
}
return orElse();
}
}
abstract class _ServerError implements UserFailure {
const factory _ServerError(final ApiFailure failure) = _$ServerErrorImpl;
ApiFailure get failure;
/// Create a copy of UserFailure
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
_$$ServerErrorImplCopyWith<_$ServerErrorImpl> get copyWith =>
throw _privateConstructorUsedError;
}
/// @nodoc
abstract class _$$UnexpectedErrorImplCopyWith<$Res> {
factory _$$UnexpectedErrorImplCopyWith(
_$UnexpectedErrorImpl value,
$Res Function(_$UnexpectedErrorImpl) then,
) = __$$UnexpectedErrorImplCopyWithImpl<$Res>;
}
/// @nodoc
class __$$UnexpectedErrorImplCopyWithImpl<$Res>
extends _$UserFailureCopyWithImpl<$Res, _$UnexpectedErrorImpl>
implements _$$UnexpectedErrorImplCopyWith<$Res> {
__$$UnexpectedErrorImplCopyWithImpl(
_$UnexpectedErrorImpl _value,
$Res Function(_$UnexpectedErrorImpl) _then,
) : super(_value, _then);
/// Create a copy of UserFailure
/// with the given fields replaced by the non-null parameter values.
}
/// @nodoc
class _$UnexpectedErrorImpl implements _UnexpectedError {
const _$UnexpectedErrorImpl();
@override
String toString() {
return 'UserFailure.unexpectedError()';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType && other is _$UnexpectedErrorImpl);
}
@override
int get hashCode => runtimeType.hashCode;
@override
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function(ApiFailure failure) serverError,
required TResult Function() unexpectedError,
required TResult Function() empty,
required TResult Function(String erroMessage) dynamicErrorMessage,
}) {
return unexpectedError();
}
@override
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>({
TResult? Function(ApiFailure failure)? serverError,
TResult? Function()? unexpectedError,
TResult? Function()? empty,
TResult? Function(String erroMessage)? dynamicErrorMessage,
}) {
return unexpectedError?.call();
}
@override
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({
TResult Function(ApiFailure failure)? serverError,
TResult Function()? unexpectedError,
TResult Function()? empty,
TResult Function(String erroMessage)? dynamicErrorMessage,
required TResult orElse(),
}) {
if (unexpectedError != null) {
return unexpectedError();
}
return orElse();
}
@override
@optionalTypeArgs
TResult map<TResult extends Object?>({
required TResult Function(_ServerError value) serverError,
required TResult Function(_UnexpectedError value) unexpectedError,
required TResult Function(_Empty value) empty,
required TResult Function(_DynamicErrorMessage value) dynamicErrorMessage,
}) {
return unexpectedError(this);
}
@override
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>({
TResult? Function(_ServerError value)? serverError,
TResult? Function(_UnexpectedError value)? unexpectedError,
TResult? Function(_Empty value)? empty,
TResult? Function(_DynamicErrorMessage value)? dynamicErrorMessage,
}) {
return unexpectedError?.call(this);
}
@override
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>({
TResult Function(_ServerError value)? serverError,
TResult Function(_UnexpectedError value)? unexpectedError,
TResult Function(_Empty value)? empty,
TResult Function(_DynamicErrorMessage value)? dynamicErrorMessage,
required TResult orElse(),
}) {
if (unexpectedError != null) {
return unexpectedError(this);
}
return orElse();
}
}
abstract class _UnexpectedError implements UserFailure {
const factory _UnexpectedError() = _$UnexpectedErrorImpl;
}
/// @nodoc
abstract class _$$EmptyImplCopyWith<$Res> {
factory _$$EmptyImplCopyWith(
_$EmptyImpl value,
$Res Function(_$EmptyImpl) then,
) = __$$EmptyImplCopyWithImpl<$Res>;
}
/// @nodoc
class __$$EmptyImplCopyWithImpl<$Res>
extends _$UserFailureCopyWithImpl<$Res, _$EmptyImpl>
implements _$$EmptyImplCopyWith<$Res> {
__$$EmptyImplCopyWithImpl(
_$EmptyImpl _value,
$Res Function(_$EmptyImpl) _then,
) : super(_value, _then);
/// Create a copy of UserFailure
/// with the given fields replaced by the non-null parameter values.
}
/// @nodoc
class _$EmptyImpl implements _Empty {
const _$EmptyImpl();
@override
String toString() {
return 'UserFailure.empty()';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType && other is _$EmptyImpl);
}
@override
int get hashCode => runtimeType.hashCode;
@override
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function(ApiFailure failure) serverError,
required TResult Function() unexpectedError,
required TResult Function() empty,
required TResult Function(String erroMessage) dynamicErrorMessage,
}) {
return empty();
}
@override
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>({
TResult? Function(ApiFailure failure)? serverError,
TResult? Function()? unexpectedError,
TResult? Function()? empty,
TResult? Function(String erroMessage)? dynamicErrorMessage,
}) {
return empty?.call();
}
@override
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({
TResult Function(ApiFailure failure)? serverError,
TResult Function()? unexpectedError,
TResult Function()? empty,
TResult Function(String erroMessage)? dynamicErrorMessage,
required TResult orElse(),
}) {
if (empty != null) {
return empty();
}
return orElse();
}
@override
@optionalTypeArgs
TResult map<TResult extends Object?>({
required TResult Function(_ServerError value) serverError,
required TResult Function(_UnexpectedError value) unexpectedError,
required TResult Function(_Empty value) empty,
required TResult Function(_DynamicErrorMessage value) dynamicErrorMessage,
}) {
return empty(this);
}
@override
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>({
TResult? Function(_ServerError value)? serverError,
TResult? Function(_UnexpectedError value)? unexpectedError,
TResult? Function(_Empty value)? empty,
TResult? Function(_DynamicErrorMessage value)? dynamicErrorMessage,
}) {
return empty?.call(this);
}
@override
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>({
TResult Function(_ServerError value)? serverError,
TResult Function(_UnexpectedError value)? unexpectedError,
TResult Function(_Empty value)? empty,
TResult Function(_DynamicErrorMessage value)? dynamicErrorMessage,
required TResult orElse(),
}) {
if (empty != null) {
return empty(this);
}
return orElse();
}
}
abstract class _Empty implements UserFailure {
const factory _Empty() = _$EmptyImpl;
}
/// @nodoc
abstract class _$$DynamicErrorMessageImplCopyWith<$Res> {
factory _$$DynamicErrorMessageImplCopyWith(
_$DynamicErrorMessageImpl value,
$Res Function(_$DynamicErrorMessageImpl) then,
) = __$$DynamicErrorMessageImplCopyWithImpl<$Res>;
@useResult
$Res call({String erroMessage});
}
/// @nodoc
class __$$DynamicErrorMessageImplCopyWithImpl<$Res>
extends _$UserFailureCopyWithImpl<$Res, _$DynamicErrorMessageImpl>
implements _$$DynamicErrorMessageImplCopyWith<$Res> {
__$$DynamicErrorMessageImplCopyWithImpl(
_$DynamicErrorMessageImpl _value,
$Res Function(_$DynamicErrorMessageImpl) _then,
) : super(_value, _then);
/// Create a copy of UserFailure
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({Object? erroMessage = null}) {
return _then(
_$DynamicErrorMessageImpl(
null == erroMessage
? _value.erroMessage
: erroMessage // ignore: cast_nullable_to_non_nullable
as String,
),
);
}
}
/// @nodoc
class _$DynamicErrorMessageImpl implements _DynamicErrorMessage {
const _$DynamicErrorMessageImpl(this.erroMessage);
@override
final String erroMessage;
@override
String toString() {
return 'UserFailure.dynamicErrorMessage(erroMessage: $erroMessage)';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType &&
other is _$DynamicErrorMessageImpl &&
(identical(other.erroMessage, erroMessage) ||
other.erroMessage == erroMessage));
}
@override
int get hashCode => Object.hash(runtimeType, erroMessage);
/// Create a copy of UserFailure
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@override
@pragma('vm:prefer-inline')
_$$DynamicErrorMessageImplCopyWith<_$DynamicErrorMessageImpl> get copyWith =>
__$$DynamicErrorMessageImplCopyWithImpl<_$DynamicErrorMessageImpl>(
this,
_$identity,
);
@override
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function(ApiFailure failure) serverError,
required TResult Function() unexpectedError,
required TResult Function() empty,
required TResult Function(String erroMessage) dynamicErrorMessage,
}) {
return dynamicErrorMessage(erroMessage);
}
@override
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>({
TResult? Function(ApiFailure failure)? serverError,
TResult? Function()? unexpectedError,
TResult? Function()? empty,
TResult? Function(String erroMessage)? dynamicErrorMessage,
}) {
return dynamicErrorMessage?.call(erroMessage);
}
@override
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({
TResult Function(ApiFailure failure)? serverError,
TResult Function()? unexpectedError,
TResult Function()? empty,
TResult Function(String erroMessage)? dynamicErrorMessage,
required TResult orElse(),
}) {
if (dynamicErrorMessage != null) {
return dynamicErrorMessage(erroMessage);
}
return orElse();
}
@override
@optionalTypeArgs
TResult map<TResult extends Object?>({
required TResult Function(_ServerError value) serverError,
required TResult Function(_UnexpectedError value) unexpectedError,
required TResult Function(_Empty value) empty,
required TResult Function(_DynamicErrorMessage value) dynamicErrorMessage,
}) {
return dynamicErrorMessage(this);
}
@override
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>({
TResult? Function(_ServerError value)? serverError,
TResult? Function(_UnexpectedError value)? unexpectedError,
TResult? Function(_Empty value)? empty,
TResult? Function(_DynamicErrorMessage value)? dynamicErrorMessage,
}) {
return dynamicErrorMessage?.call(this);
}
@override
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>({
TResult Function(_ServerError value)? serverError,
TResult Function(_UnexpectedError value)? unexpectedError,
TResult Function(_Empty value)? empty,
TResult Function(_DynamicErrorMessage value)? dynamicErrorMessage,
required TResult orElse(),
}) {
if (dynamicErrorMessage != null) {
return dynamicErrorMessage(this);
}
return orElse();
}
}
abstract class _DynamicErrorMessage implements UserFailure {
const factory _DynamicErrorMessage(final String erroMessage) =
_$DynamicErrorMessageImpl;
String get erroMessage;
/// Create a copy of UserFailure
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
_$$DynamicErrorMessageImplCopyWith<_$DynamicErrorMessageImpl> get copyWith =>
throw _privateConstructorUsedError;
}

View File

@ -5,7 +5,7 @@ import 'package:injectable/injectable.dart';
import '../../../domain/analytic/analytic.dart';
import '../../../domain/analytic/repositories/i_analytic_repository.dart';
import '../../../domain/auth/auth.dart';
import '../../../domain/user/user.dart';
import '../../auth/datasources/local_data_provider.dart';
import '../datasource/remote_data_provider.dart';

View File

@ -1,9 +1,10 @@
import 'package:freezed_annotation/freezed_annotation.dart';
import '../../domain/auth/auth.dart';
import '../../domain/user/user.dart';
import '../user/user_dtos.dart';
part 'auth_dtos.freezed.dart';
part 'auth_dtos.g.dart';
part 'dto/auth_dto.dart';
part 'dto/user_dto.dart';

View File

@ -242,401 +242,3 @@ abstract class _AuthDto extends AuthDto {
_$$AuthDtoImplCopyWith<_$AuthDtoImpl> get copyWith =>
throw _privateConstructorUsedError;
}
UserDto _$UserDtoFromJson(Map<String, dynamic> json) {
return _UserDto.fromJson(json);
}
/// @nodoc
mixin _$UserDto {
@JsonKey(name: 'id')
String? get id => throw _privateConstructorUsedError;
@JsonKey(name: 'organization_id')
String? get organizationId => throw _privateConstructorUsedError;
@JsonKey(name: 'outlet_id')
String? get outletId => throw _privateConstructorUsedError;
@JsonKey(name: 'name')
String? get name => throw _privateConstructorUsedError;
@JsonKey(name: 'email')
String? get email => throw _privateConstructorUsedError;
@JsonKey(name: 'role')
String? get role => throw _privateConstructorUsedError;
@JsonKey(name: 'permissions')
Map<String, dynamic>? get permissions => 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 UserDto to a JSON map.
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
/// Create a copy of UserDto
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
$UserDtoCopyWith<UserDto> get copyWith => throw _privateConstructorUsedError;
}
/// @nodoc
abstract class $UserDtoCopyWith<$Res> {
factory $UserDtoCopyWith(UserDto value, $Res Function(UserDto) then) =
_$UserDtoCopyWithImpl<$Res, UserDto>;
@useResult
$Res call({
@JsonKey(name: 'id') String? id,
@JsonKey(name: 'organization_id') String? organizationId,
@JsonKey(name: 'outlet_id') String? outletId,
@JsonKey(name: 'name') String? name,
@JsonKey(name: 'email') String? email,
@JsonKey(name: 'role') String? role,
@JsonKey(name: 'permissions') Map<String, dynamic>? permissions,
@JsonKey(name: 'is_active') bool? isActive,
@JsonKey(name: 'created_at') String? createdAt,
@JsonKey(name: 'updated_at') String? updatedAt,
});
}
/// @nodoc
class _$UserDtoCopyWithImpl<$Res, $Val extends UserDto>
implements $UserDtoCopyWith<$Res> {
_$UserDtoCopyWithImpl(this._value, this._then);
// ignore: unused_field
final $Val _value;
// ignore: unused_field
final $Res Function($Val) _then;
/// Create a copy of UserDto
/// 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? outletId = freezed,
Object? name = freezed,
Object? email = freezed,
Object? role = freezed,
Object? permissions = 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?,
outletId: freezed == outletId
? _value.outletId
: outletId // ignore: cast_nullable_to_non_nullable
as String?,
name: freezed == name
? _value.name
: name // ignore: cast_nullable_to_non_nullable
as String?,
email: freezed == email
? _value.email
: email // ignore: cast_nullable_to_non_nullable
as String?,
role: freezed == role
? _value.role
: role // ignore: cast_nullable_to_non_nullable
as String?,
permissions: freezed == permissions
? _value.permissions
: permissions // ignore: cast_nullable_to_non_nullable
as Map<String, dynamic>?,
isActive: freezed == isActive
? _value.isActive
: isActive // ignore: cast_nullable_to_non_nullable
as bool?,
createdAt: freezed == createdAt
? _value.createdAt
: createdAt // ignore: cast_nullable_to_non_nullable
as String?,
updatedAt: freezed == updatedAt
? _value.updatedAt
: updatedAt // ignore: cast_nullable_to_non_nullable
as String?,
)
as $Val,
);
}
}
/// @nodoc
abstract class _$$UserDtoImplCopyWith<$Res> implements $UserDtoCopyWith<$Res> {
factory _$$UserDtoImplCopyWith(
_$UserDtoImpl value,
$Res Function(_$UserDtoImpl) then,
) = __$$UserDtoImplCopyWithImpl<$Res>;
@override
@useResult
$Res call({
@JsonKey(name: 'id') String? id,
@JsonKey(name: 'organization_id') String? organizationId,
@JsonKey(name: 'outlet_id') String? outletId,
@JsonKey(name: 'name') String? name,
@JsonKey(name: 'email') String? email,
@JsonKey(name: 'role') String? role,
@JsonKey(name: 'permissions') Map<String, dynamic>? permissions,
@JsonKey(name: 'is_active') bool? isActive,
@JsonKey(name: 'created_at') String? createdAt,
@JsonKey(name: 'updated_at') String? updatedAt,
});
}
/// @nodoc
class __$$UserDtoImplCopyWithImpl<$Res>
extends _$UserDtoCopyWithImpl<$Res, _$UserDtoImpl>
implements _$$UserDtoImplCopyWith<$Res> {
__$$UserDtoImplCopyWithImpl(
_$UserDtoImpl _value,
$Res Function(_$UserDtoImpl) _then,
) : super(_value, _then);
/// Create a copy of UserDto
/// 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? outletId = freezed,
Object? name = freezed,
Object? email = freezed,
Object? role = freezed,
Object? permissions = freezed,
Object? isActive = freezed,
Object? createdAt = freezed,
Object? updatedAt = freezed,
}) {
return _then(
_$UserDtoImpl(
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?,
outletId: freezed == outletId
? _value.outletId
: outletId // ignore: cast_nullable_to_non_nullable
as String?,
name: freezed == name
? _value.name
: name // ignore: cast_nullable_to_non_nullable
as String?,
email: freezed == email
? _value.email
: email // ignore: cast_nullable_to_non_nullable
as String?,
role: freezed == role
? _value.role
: role // ignore: cast_nullable_to_non_nullable
as String?,
permissions: freezed == permissions
? _value._permissions
: permissions // ignore: cast_nullable_to_non_nullable
as Map<String, dynamic>?,
isActive: freezed == isActive
? _value.isActive
: isActive // ignore: cast_nullable_to_non_nullable
as bool?,
createdAt: freezed == createdAt
? _value.createdAt
: createdAt // ignore: cast_nullable_to_non_nullable
as String?,
updatedAt: freezed == updatedAt
? _value.updatedAt
: updatedAt // ignore: cast_nullable_to_non_nullable
as String?,
),
);
}
}
/// @nodoc
@JsonSerializable()
class _$UserDtoImpl extends _UserDto {
const _$UserDtoImpl({
@JsonKey(name: 'id') this.id,
@JsonKey(name: 'organization_id') this.organizationId,
@JsonKey(name: 'outlet_id') this.outletId,
@JsonKey(name: 'name') this.name,
@JsonKey(name: 'email') this.email,
@JsonKey(name: 'role') this.role,
@JsonKey(name: 'permissions') final Map<String, dynamic>? permissions,
@JsonKey(name: 'is_active') this.isActive,
@JsonKey(name: 'created_at') this.createdAt,
@JsonKey(name: 'updated_at') this.updatedAt,
}) : _permissions = permissions,
super._();
factory _$UserDtoImpl.fromJson(Map<String, dynamic> json) =>
_$$UserDtoImplFromJson(json);
@override
@JsonKey(name: 'id')
final String? id;
@override
@JsonKey(name: 'organization_id')
final String? organizationId;
@override
@JsonKey(name: 'outlet_id')
final String? outletId;
@override
@JsonKey(name: 'name')
final String? name;
@override
@JsonKey(name: 'email')
final String? email;
@override
@JsonKey(name: 'role')
final String? role;
final Map<String, dynamic>? _permissions;
@override
@JsonKey(name: 'permissions')
Map<String, dynamic>? get permissions {
final value = _permissions;
if (value == null) return null;
if (_permissions is EqualUnmodifiableMapView) return _permissions;
// ignore: implicit_dynamic_type
return EqualUnmodifiableMapView(value);
}
@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 'UserDto(id: $id, organizationId: $organizationId, outletId: $outletId, name: $name, email: $email, role: $role, permissions: $permissions, isActive: $isActive, createdAt: $createdAt, updatedAt: $updatedAt)';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType &&
other is _$UserDtoImpl &&
(identical(other.id, id) || other.id == id) &&
(identical(other.organizationId, organizationId) ||
other.organizationId == organizationId) &&
(identical(other.outletId, outletId) ||
other.outletId == outletId) &&
(identical(other.name, name) || other.name == name) &&
(identical(other.email, email) || other.email == email) &&
(identical(other.role, role) || other.role == role) &&
const DeepCollectionEquality().equals(
other._permissions,
_permissions,
) &&
(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,
outletId,
name,
email,
role,
const DeepCollectionEquality().hash(_permissions),
isActive,
createdAt,
updatedAt,
);
/// Create a copy of UserDto
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@override
@pragma('vm:prefer-inline')
_$$UserDtoImplCopyWith<_$UserDtoImpl> get copyWith =>
__$$UserDtoImplCopyWithImpl<_$UserDtoImpl>(this, _$identity);
@override
Map<String, dynamic> toJson() {
return _$$UserDtoImplToJson(this);
}
}
abstract class _UserDto extends UserDto {
const factory _UserDto({
@JsonKey(name: 'id') final String? id,
@JsonKey(name: 'organization_id') final String? organizationId,
@JsonKey(name: 'outlet_id') final String? outletId,
@JsonKey(name: 'name') final String? name,
@JsonKey(name: 'email') final String? email,
@JsonKey(name: 'role') final String? role,
@JsonKey(name: 'permissions') final Map<String, dynamic>? permissions,
@JsonKey(name: 'is_active') final bool? isActive,
@JsonKey(name: 'created_at') final String? createdAt,
@JsonKey(name: 'updated_at') final String? updatedAt,
}) = _$UserDtoImpl;
const _UserDto._() : super._();
factory _UserDto.fromJson(Map<String, dynamic> json) = _$UserDtoImpl.fromJson;
@override
@JsonKey(name: 'id')
String? get id;
@override
@JsonKey(name: 'organization_id')
String? get organizationId;
@override
@JsonKey(name: 'outlet_id')
String? get outletId;
@override
@JsonKey(name: 'name')
String? get name;
@override
@JsonKey(name: 'email')
String? get email;
@override
@JsonKey(name: 'role')
String? get role;
@override
@JsonKey(name: 'permissions')
Map<String, dynamic>? get permissions;
@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 UserDto
/// with the given fields replaced by the non-null parameter values.
@override
@JsonKey(includeFromJson: false, includeToJson: false)
_$$UserDtoImplCopyWith<_$UserDtoImpl> get copyWith =>
throw _privateConstructorUsedError;
}

View File

@ -21,31 +21,3 @@ Map<String, dynamic> _$$AuthDtoImplToJson(_$AuthDtoImpl instance) =>
'expires_at': instance.expiresAt,
'user': instance.user,
};
_$UserDtoImpl _$$UserDtoImplFromJson(Map<String, dynamic> json) =>
_$UserDtoImpl(
id: json['id'] as String?,
organizationId: json['organization_id'] as String?,
outletId: json['outlet_id'] as String?,
name: json['name'] as String?,
email: json['email'] as String?,
role: json['role'] as String?,
permissions: json['permissions'] as Map<String, dynamic>?,
isActive: json['is_active'] as bool?,
createdAt: json['created_at'] as String?,
updatedAt: json['updated_at'] as String?,
);
Map<String, dynamic> _$$UserDtoImplToJson(_$UserDtoImpl instance) =>
<String, dynamic>{
'id': instance.id,
'organization_id': instance.organizationId,
'outlet_id': instance.outletId,
'name': instance.name,
'email': instance.email,
'role': instance.role,
'permissions': instance.permissions,
'is_active': instance.isActive,
'created_at': instance.createdAt,
'updated_at': instance.updatedAt,
};

View File

@ -5,8 +5,8 @@ import 'package:injectable/injectable.dart';
import 'package:shared_preferences/shared_preferences.dart';
import '../../../common/constant/local_storage_key.dart';
import '../../../domain/auth/auth.dart';
import '../auth_dtos.dart';
import '../../../domain/user/user.dart';
import '../../user/user_dtos.dart';
@injectable
class AuthLocalDataProvider {

View File

@ -4,6 +4,7 @@ import 'package:dartz/dartz.dart';
import 'package:injectable/injectable.dart';
import '../../../domain/auth/auth.dart';
import '../../../domain/user/user.dart';
import '../datasources/local_data_provider.dart';
import '../datasources/remote_data_provider.dart';

View File

@ -0,0 +1,83 @@
import 'dart:developer';
import 'package:dartz/dartz.dart';
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/user/user.dart';
import '../user_dtos.dart';
@injectable
class UserRemoteDataProvider {
final ApiClient _apiClient;
static const _logName = 'UserRemoteDataProvider';
UserRemoteDataProvider(this._apiClient);
Future<DC<UserFailure, UserDto>> updateUser({
required String name,
required String userId,
}) async {
try {
final response = await _apiClient.put(
'${ApiPath.user}/$userId',
data: {'name': name, 'is_active': true},
headers: getAuthorizationHeader(),
);
if (response.statusCode == 400) {
return DC.error(UserFailure.unexpectedError());
}
if (response.statusCode != 200) {
return DC.error(
UserFailure.dynamicErrorMessage(response.data['message']),
);
}
final dto = UserDto.fromJson(response.data);
return DC.data(dto);
} on ApiFailure catch (e, s) {
log('updateUser', name: _logName, error: e, stackTrace: s);
return DC.error(UserFailure.serverError(e));
}
}
Future<DC<UserFailure, Unit>> changePassword({
required String newPassword,
required String currentPassword,
required String userId,
}) async {
try {
final response = await _apiClient.put(
'${ApiPath.user}/$userId/password',
data: {
'new_password': newPassword,
'current_password': currentPassword,
},
headers: getAuthorizationHeader(),
);
if (response.statusCode == 400) {
return DC.error(UserFailure.unexpectedError());
}
if (response.statusCode != 200) {
return DC.error(
UserFailure.dynamicErrorMessage(response.data['error']),
);
}
return DC.data(unit);
} on ApiFailure catch (e, s) {
log('changePassword', name: _logName, error: e, stackTrace: s);
return DC.error(UserFailure.serverError(e));
}
}
}

View File

@ -1,4 +1,4 @@
part of '../auth_dtos.dart';
part of '../user_dtos.dart';
@freezed
class UserDto with _$UserDto {

View File

@ -0,0 +1,66 @@
import 'dart:developer';
import 'package:dartz/dartz.dart';
import 'package:injectable/injectable.dart';
import '../../../domain/user/user.dart';
import '../../auth/datasources/local_data_provider.dart';
import '../datasource/remote_data_provider.dart';
@Injectable(as: IUserRepository)
class UserRepository implements IUserRepository {
final UserRemoteDataProvider _dataProvider;
final AuthLocalDataProvider _authLocalDataProvider;
final String _logName = 'UserRepository';
UserRepository(this._dataProvider, this._authLocalDataProvider);
@override
Future<Either<UserFailure, User>> editUser({required String name}) async {
try {
User currentUser = await _authLocalDataProvider.currentUser();
final result = await _dataProvider.updateUser(
name: name,
userId: currentUser.id,
);
if (result.hasError) {
return left(result.error!);
}
final auth = result.data!.toDomain();
await _authLocalDataProvider.saveCurrentUser(result.data!);
return right(auth);
} catch (e, s) {
log('editUserError', name: _logName, error: e, stackTrace: s);
return left(const UserFailure.unexpectedError());
}
}
@override
Future<Either<UserFailure, Unit>> changePassword({
required String newPassword,
required String currentPassword,
}) async {
try {
User currentUser = await _authLocalDataProvider.currentUser();
final result = await _dataProvider.changePassword(
newPassword: newPassword,
currentPassword: currentPassword,
userId: currentUser.id,
);
if (result.hasError) {
return left(result.error!);
}
return right(unit);
} catch (e, s) {
log('changePasswordError', name: _logName, error: e, stackTrace: s);
return left(const UserFailure.unexpectedError());
}
}
}

View File

@ -0,0 +1,8 @@
import 'package:freezed_annotation/freezed_annotation.dart';
import '../../domain/user/user.dart';
part 'user_dtos.freezed.dart';
part 'user_dtos.g.dart';
part 'dto/user_dto.dart';

View File

@ -0,0 +1,414 @@
// 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 'user_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',
);
UserDto _$UserDtoFromJson(Map<String, dynamic> json) {
return _UserDto.fromJson(json);
}
/// @nodoc
mixin _$UserDto {
@JsonKey(name: 'id')
String? get id => throw _privateConstructorUsedError;
@JsonKey(name: 'organization_id')
String? get organizationId => throw _privateConstructorUsedError;
@JsonKey(name: 'outlet_id')
String? get outletId => throw _privateConstructorUsedError;
@JsonKey(name: 'name')
String? get name => throw _privateConstructorUsedError;
@JsonKey(name: 'email')
String? get email => throw _privateConstructorUsedError;
@JsonKey(name: 'role')
String? get role => throw _privateConstructorUsedError;
@JsonKey(name: 'permissions')
Map<String, dynamic>? get permissions => 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 UserDto to a JSON map.
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
/// Create a copy of UserDto
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
$UserDtoCopyWith<UserDto> get copyWith => throw _privateConstructorUsedError;
}
/// @nodoc
abstract class $UserDtoCopyWith<$Res> {
factory $UserDtoCopyWith(UserDto value, $Res Function(UserDto) then) =
_$UserDtoCopyWithImpl<$Res, UserDto>;
@useResult
$Res call({
@JsonKey(name: 'id') String? id,
@JsonKey(name: 'organization_id') String? organizationId,
@JsonKey(name: 'outlet_id') String? outletId,
@JsonKey(name: 'name') String? name,
@JsonKey(name: 'email') String? email,
@JsonKey(name: 'role') String? role,
@JsonKey(name: 'permissions') Map<String, dynamic>? permissions,
@JsonKey(name: 'is_active') bool? isActive,
@JsonKey(name: 'created_at') String? createdAt,
@JsonKey(name: 'updated_at') String? updatedAt,
});
}
/// @nodoc
class _$UserDtoCopyWithImpl<$Res, $Val extends UserDto>
implements $UserDtoCopyWith<$Res> {
_$UserDtoCopyWithImpl(this._value, this._then);
// ignore: unused_field
final $Val _value;
// ignore: unused_field
final $Res Function($Val) _then;
/// Create a copy of UserDto
/// 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? outletId = freezed,
Object? name = freezed,
Object? email = freezed,
Object? role = freezed,
Object? permissions = 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?,
outletId: freezed == outletId
? _value.outletId
: outletId // ignore: cast_nullable_to_non_nullable
as String?,
name: freezed == name
? _value.name
: name // ignore: cast_nullable_to_non_nullable
as String?,
email: freezed == email
? _value.email
: email // ignore: cast_nullable_to_non_nullable
as String?,
role: freezed == role
? _value.role
: role // ignore: cast_nullable_to_non_nullable
as String?,
permissions: freezed == permissions
? _value.permissions
: permissions // ignore: cast_nullable_to_non_nullable
as Map<String, dynamic>?,
isActive: freezed == isActive
? _value.isActive
: isActive // ignore: cast_nullable_to_non_nullable
as bool?,
createdAt: freezed == createdAt
? _value.createdAt
: createdAt // ignore: cast_nullable_to_non_nullable
as String?,
updatedAt: freezed == updatedAt
? _value.updatedAt
: updatedAt // ignore: cast_nullable_to_non_nullable
as String?,
)
as $Val,
);
}
}
/// @nodoc
abstract class _$$UserDtoImplCopyWith<$Res> implements $UserDtoCopyWith<$Res> {
factory _$$UserDtoImplCopyWith(
_$UserDtoImpl value,
$Res Function(_$UserDtoImpl) then,
) = __$$UserDtoImplCopyWithImpl<$Res>;
@override
@useResult
$Res call({
@JsonKey(name: 'id') String? id,
@JsonKey(name: 'organization_id') String? organizationId,
@JsonKey(name: 'outlet_id') String? outletId,
@JsonKey(name: 'name') String? name,
@JsonKey(name: 'email') String? email,
@JsonKey(name: 'role') String? role,
@JsonKey(name: 'permissions') Map<String, dynamic>? permissions,
@JsonKey(name: 'is_active') bool? isActive,
@JsonKey(name: 'created_at') String? createdAt,
@JsonKey(name: 'updated_at') String? updatedAt,
});
}
/// @nodoc
class __$$UserDtoImplCopyWithImpl<$Res>
extends _$UserDtoCopyWithImpl<$Res, _$UserDtoImpl>
implements _$$UserDtoImplCopyWith<$Res> {
__$$UserDtoImplCopyWithImpl(
_$UserDtoImpl _value,
$Res Function(_$UserDtoImpl) _then,
) : super(_value, _then);
/// Create a copy of UserDto
/// 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? outletId = freezed,
Object? name = freezed,
Object? email = freezed,
Object? role = freezed,
Object? permissions = freezed,
Object? isActive = freezed,
Object? createdAt = freezed,
Object? updatedAt = freezed,
}) {
return _then(
_$UserDtoImpl(
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?,
outletId: freezed == outletId
? _value.outletId
: outletId // ignore: cast_nullable_to_non_nullable
as String?,
name: freezed == name
? _value.name
: name // ignore: cast_nullable_to_non_nullable
as String?,
email: freezed == email
? _value.email
: email // ignore: cast_nullable_to_non_nullable
as String?,
role: freezed == role
? _value.role
: role // ignore: cast_nullable_to_non_nullable
as String?,
permissions: freezed == permissions
? _value._permissions
: permissions // ignore: cast_nullable_to_non_nullable
as Map<String, dynamic>?,
isActive: freezed == isActive
? _value.isActive
: isActive // ignore: cast_nullable_to_non_nullable
as bool?,
createdAt: freezed == createdAt
? _value.createdAt
: createdAt // ignore: cast_nullable_to_non_nullable
as String?,
updatedAt: freezed == updatedAt
? _value.updatedAt
: updatedAt // ignore: cast_nullable_to_non_nullable
as String?,
),
);
}
}
/// @nodoc
@JsonSerializable()
class _$UserDtoImpl extends _UserDto {
const _$UserDtoImpl({
@JsonKey(name: 'id') this.id,
@JsonKey(name: 'organization_id') this.organizationId,
@JsonKey(name: 'outlet_id') this.outletId,
@JsonKey(name: 'name') this.name,
@JsonKey(name: 'email') this.email,
@JsonKey(name: 'role') this.role,
@JsonKey(name: 'permissions') final Map<String, dynamic>? permissions,
@JsonKey(name: 'is_active') this.isActive,
@JsonKey(name: 'created_at') this.createdAt,
@JsonKey(name: 'updated_at') this.updatedAt,
}) : _permissions = permissions,
super._();
factory _$UserDtoImpl.fromJson(Map<String, dynamic> json) =>
_$$UserDtoImplFromJson(json);
@override
@JsonKey(name: 'id')
final String? id;
@override
@JsonKey(name: 'organization_id')
final String? organizationId;
@override
@JsonKey(name: 'outlet_id')
final String? outletId;
@override
@JsonKey(name: 'name')
final String? name;
@override
@JsonKey(name: 'email')
final String? email;
@override
@JsonKey(name: 'role')
final String? role;
final Map<String, dynamic>? _permissions;
@override
@JsonKey(name: 'permissions')
Map<String, dynamic>? get permissions {
final value = _permissions;
if (value == null) return null;
if (_permissions is EqualUnmodifiableMapView) return _permissions;
// ignore: implicit_dynamic_type
return EqualUnmodifiableMapView(value);
}
@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 'UserDto(id: $id, organizationId: $organizationId, outletId: $outletId, name: $name, email: $email, role: $role, permissions: $permissions, isActive: $isActive, createdAt: $createdAt, updatedAt: $updatedAt)';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType &&
other is _$UserDtoImpl &&
(identical(other.id, id) || other.id == id) &&
(identical(other.organizationId, organizationId) ||
other.organizationId == organizationId) &&
(identical(other.outletId, outletId) ||
other.outletId == outletId) &&
(identical(other.name, name) || other.name == name) &&
(identical(other.email, email) || other.email == email) &&
(identical(other.role, role) || other.role == role) &&
const DeepCollectionEquality().equals(
other._permissions,
_permissions,
) &&
(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,
outletId,
name,
email,
role,
const DeepCollectionEquality().hash(_permissions),
isActive,
createdAt,
updatedAt,
);
/// Create a copy of UserDto
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@override
@pragma('vm:prefer-inline')
_$$UserDtoImplCopyWith<_$UserDtoImpl> get copyWith =>
__$$UserDtoImplCopyWithImpl<_$UserDtoImpl>(this, _$identity);
@override
Map<String, dynamic> toJson() {
return _$$UserDtoImplToJson(this);
}
}
abstract class _UserDto extends UserDto {
const factory _UserDto({
@JsonKey(name: 'id') final String? id,
@JsonKey(name: 'organization_id') final String? organizationId,
@JsonKey(name: 'outlet_id') final String? outletId,
@JsonKey(name: 'name') final String? name,
@JsonKey(name: 'email') final String? email,
@JsonKey(name: 'role') final String? role,
@JsonKey(name: 'permissions') final Map<String, dynamic>? permissions,
@JsonKey(name: 'is_active') final bool? isActive,
@JsonKey(name: 'created_at') final String? createdAt,
@JsonKey(name: 'updated_at') final String? updatedAt,
}) = _$UserDtoImpl;
const _UserDto._() : super._();
factory _UserDto.fromJson(Map<String, dynamic> json) = _$UserDtoImpl.fromJson;
@override
@JsonKey(name: 'id')
String? get id;
@override
@JsonKey(name: 'organization_id')
String? get organizationId;
@override
@JsonKey(name: 'outlet_id')
String? get outletId;
@override
@JsonKey(name: 'name')
String? get name;
@override
@JsonKey(name: 'email')
String? get email;
@override
@JsonKey(name: 'role')
String? get role;
@override
@JsonKey(name: 'permissions')
Map<String, dynamic>? get permissions;
@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 UserDto
/// with the given fields replaced by the non-null parameter values.
@override
@JsonKey(includeFromJson: false, includeToJson: false)
_$$UserDtoImplCopyWith<_$UserDtoImpl> get copyWith =>
throw _privateConstructorUsedError;
}

View File

@ -0,0 +1,35 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'user_dtos.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
_$UserDtoImpl _$$UserDtoImplFromJson(Map<String, dynamic> json) =>
_$UserDtoImpl(
id: json['id'] as String?,
organizationId: json['organization_id'] as String?,
outletId: json['outlet_id'] as String?,
name: json['name'] as String?,
email: json['email'] as String?,
role: json['role'] as String?,
permissions: json['permissions'] as Map<String, dynamic>?,
isActive: json['is_active'] as bool?,
createdAt: json['created_at'] as String?,
updatedAt: json['updated_at'] as String?,
);
Map<String, dynamic> _$$UserDtoImplToJson(_$UserDtoImpl instance) =>
<String, dynamic>{
'id': instance.id,
'organization_id': instance.organizationId,
'outlet_id': instance.outletId,
'name': instance.name,
'email': instance.email,
'role': instance.role,
'permissions': instance.permissions,
'is_active': instance.isActive,
'created_at': instance.createdAt,
'updated_at': instance.updatedAt,
};

View File

@ -41,6 +41,14 @@ import 'package:apskel_owner_flutter/application/outlet/current_outlet_loader/cu
as _i337;
import 'package:apskel_owner_flutter/application/product/product_loader/product_loader_bloc.dart'
as _i458;
import 'package:apskel_owner_flutter/application/report/inventory_report/inventory_report_bloc.dart'
as _i346;
import 'package:apskel_owner_flutter/application/report/transaction_report/transaction_report_bloc.dart'
as _i605;
import 'package:apskel_owner_flutter/application/user/change_password_form/change_password_form_bloc.dart'
as _i1030;
import 'package:apskel_owner_flutter/application/user/user_edit_form/user_edit_form_bloc.dart'
as _i147;
import 'package:apskel_owner_flutter/common/api/api_client.dart' as _i115;
import 'package:apskel_owner_flutter/common/di/di_auto_route.dart' as _i311;
import 'package:apskel_owner_flutter/common/di/di_connectivity.dart' as _i586;
@ -58,6 +66,7 @@ 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/outlet/outlet.dart' as _i197;
import 'package:apskel_owner_flutter/domain/product/product.dart' as _i419;
import 'package:apskel_owner_flutter/domain/user/user.dart' as _i635;
import 'package:apskel_owner_flutter/env.dart' as _i6;
import 'package:apskel_owner_flutter/infrastructure/analytic/datasource/remote_data_provider.dart'
as _i866;
@ -89,6 +98,10 @@ import 'package:apskel_owner_flutter/infrastructure/product/datasources/remote_d
as _i823;
import 'package:apskel_owner_flutter/infrastructure/product/repositories/product_repository.dart'
as _i121;
import 'package:apskel_owner_flutter/infrastructure/user/datasource/remote_data_provider.dart'
as _i785;
import 'package:apskel_owner_flutter/infrastructure/user/repositories/user_repository.dart'
as _i754;
import 'package:apskel_owner_flutter/presentation/router/app_router.dart'
as _i258;
import 'package:connectivity_plus/connectivity_plus.dart' as _i895;
@ -147,18 +160,21 @@ extension GetItInjectableX on _i174.GetIt {
gh.factory<_i17.AuthRemoteDataProvider>(
() => _i17.AuthRemoteDataProvider(gh<_i115.ApiClient>()),
);
gh.factory<_i785.UserRemoteDataProvider>(
() => _i785.UserRemoteDataProvider(gh<_i115.ApiClient>()),
);
gh.factory<_i823.ProductRemoteDataProvider>(
() => _i823.ProductRemoteDataProvider(gh<_i115.ApiClient>()),
);
gh.factory<_i27.OutletRemoteDataProvider>(
() => _i27.OutletRemoteDataProvider(gh<_i115.ApiClient>()),
);
gh.factory<_i866.AnalyticRemoteDataProvider>(
() => _i866.AnalyticRemoteDataProvider(gh<_i115.ApiClient>()),
);
gh.factory<_i1006.CustomerRemoteDataProvider>(
() => _i1006.CustomerRemoteDataProvider(gh<_i115.ApiClient>()),
);
gh.factory<_i27.OutletRemoteDataProvider>(
() => _i27.OutletRemoteDataProvider(gh<_i115.ApiClient>()),
);
gh.factory<_i48.ICustomerRepository>(
() => _i550.CustomerRepository(gh<_i1006.CustomerRemoteDataProvider>()),
);
@ -171,6 +187,12 @@ extension GetItInjectableX on _i174.GetIt {
gh<_i17.AuthRemoteDataProvider>(),
),
);
gh.factory<_i635.IUserRepository>(
() => _i754.UserRepository(
gh<_i785.UserRemoteDataProvider>(),
gh<_i991.AuthLocalDataProvider>(),
),
);
gh.factory<_i419.IProductRepository>(
() => _i121.ProductRepository(gh<_i823.ProductRemoteDataProvider>()),
);
@ -198,12 +220,12 @@ extension GetItInjectableX on _i174.GetIt {
gh.factory<_i183.CategoryLoaderBloc>(
() => _i183.CategoryLoaderBloc(gh<_i1020.ICategoryRepository>()),
);
gh.factory<_i889.SalesLoaderBloc>(
() => _i889.SalesLoaderBloc(gh<_i477.IAnalyticRepository>()),
);
gh.factory<_i473.HomeBloc>(
() => _i473.HomeBloc(gh<_i477.IAnalyticRepository>()),
);
gh.factory<_i889.SalesLoaderBloc>(
() => _i889.SalesLoaderBloc(gh<_i477.IAnalyticRepository>()),
);
gh.factory<_i337.CurrentOutletLoaderBloc>(
() => _i337.CurrentOutletLoaderBloc(gh<_i197.IOutletRepository>()),
);
@ -239,6 +261,24 @@ extension GetItInjectableX on _i174.GetIt {
gh.factory<_i1058.OrderLoaderBloc>(
() => _i1058.OrderLoaderBloc(gh<_i219.IOrderRepository>()),
);
gh.factory<_i147.UserEditFormBloc>(
() => _i147.UserEditFormBloc(gh<_i635.IUserRepository>()),
);
gh.factory<_i1030.ChangePasswordFormBloc>(
() => _i1030.ChangePasswordFormBloc(gh<_i635.IUserRepository>()),
);
gh.factory<_i605.TransactionReportBloc>(
() => _i605.TransactionReportBloc(
gh<_i477.IAnalyticRepository>(),
gh<_i197.IOutletRepository>(),
),
);
gh.factory<_i346.InventoryReportBloc>(
() => _i346.InventoryReportBloc(
gh<_i477.IAnalyticRepository>(),
gh<_i197.IOutletRepository>(),
),
);
return this;
}
}

View File

@ -7,17 +7,20 @@ class AppElevatedButton extends StatelessWidget {
required this.isLoading,
required this.onPressed,
this.height = 50,
this.width = double.infinity,
});
final String text;
final bool isLoading;
final Function()? onPressed;
final double height;
final double width;
@override
Widget build(BuildContext context) {
return Container(
height: height,
width: width,
decoration: BoxDecoration(
gradient: const LinearGradient(colors: AppColor.primaryGradient),
borderRadius: BorderRadius.circular(AppValue.radius),

View File

@ -9,6 +9,7 @@ class AppTextFormField extends StatelessWidget {
required this.prefixIcon,
this.validator,
this.onChanged,
this.keyboardType = TextInputType.text,
});
final TextEditingController? controller;
@ -17,6 +18,7 @@ class AppTextFormField extends StatelessWidget {
final IconData prefixIcon;
final String? Function(String?)? validator;
final Function(String)? onChanged;
final TextInputType keyboardType;
@override
Widget build(BuildContext context) {
@ -33,7 +35,7 @@ class AppTextFormField extends StatelessWidget {
const SpaceHeight(8),
TextFormField(
controller: controller,
keyboardType: TextInputType.emailAddress,
keyboardType: keyboardType,
cursorColor: AppColor.primary,
onChanged: onChanged,
style: AppStyle.md.copyWith(color: AppColor.textPrimary),

View File

@ -0,0 +1,547 @@
import 'dart:io';
import 'package:flutter/services.dart';
import 'package:pdf/pdf.dart';
import 'package:pdf/widgets.dart' as pw;
import '../../../common/utils/pdf_service.dart';
import '../../../domain/analytic/analytic.dart';
import '../../../domain/outlet/outlet.dart';
class InventoryReport {
static final primaryColor = PdfColor.fromHex("36175e");
static Future<File> previewPdf({
required String searchDateFormatted,
required InventoryAnalytic inventory,
required Outlet outlet,
}) async {
final pdf = pw.Document();
final ByteData dataImage = await rootBundle.load('assets/images/logo.png');
final Uint8List bytes = dataImage.buffer.asUint8List();
final image = pw.MemoryImage(bytes);
pdf.addPage(
pw.MultiPage(
pageFormat: PdfPageFormat.a4,
margin: pw.EdgeInsets.zero,
build: (pw.Context context) {
return [
pw.Container(
padding: pw.EdgeInsets.all(20),
child: pw.Row(
mainAxisAlignment: pw.MainAxisAlignment.spaceBetween,
crossAxisAlignment: pw.CrossAxisAlignment.start,
children: [
// Bagian kiri - Logo dan Info Perusahaan
pw.Row(
crossAxisAlignment: pw.CrossAxisAlignment.center,
children: [
// Icon/Logo placeholder (bisa diganti dengan gambar logo)
pw.Container(
width: 40,
height: 40,
child: pw.Image(image),
),
pw.SizedBox(width: 15),
pw.Column(
crossAxisAlignment: pw.CrossAxisAlignment.start,
children: [
pw.Text(
'Apskel',
style: pw.TextStyle(
fontSize: 28,
fontWeight: pw.FontWeight.bold,
color: primaryColor,
),
),
pw.SizedBox(height: 4),
pw.Text(
outlet.name,
style: pw.TextStyle(
fontSize: 16,
color: PdfColors.grey700,
),
),
pw.SizedBox(height: 2),
pw.Text(
outlet.address,
style: pw.TextStyle(
fontSize: 12,
color: PdfColors.grey600,
),
),
],
),
],
),
// Bagian kanan - Info Laporan
pw.Column(
crossAxisAlignment: pw.CrossAxisAlignment.end,
children: [
pw.Text(
'Laporan Transaksi',
style: pw.TextStyle(
fontSize: 24,
fontWeight: pw.FontWeight.bold,
color: PdfColors.grey800,
),
),
pw.SizedBox(height: 8),
pw.Text(
searchDateFormatted,
style: pw.TextStyle(
fontSize: 14,
color: PdfColors.grey600,
),
),
pw.SizedBox(height: 4),
pw.Text(
'Laporan',
style: pw.TextStyle(
fontSize: 12,
color: PdfColors.grey500,
),
),
],
),
],
),
),
pw.Container(
width: double.infinity,
height: 3,
color: primaryColor,
),
// Summary
pw.Container(
padding: pw.EdgeInsets.all(20),
child: pw.Column(
crossAxisAlignment: pw.CrossAxisAlignment.start,
children: [
_buildSectionWidget('1. Ringkasan'),
pw.SizedBox(height: 30),
pw.Row(
crossAxisAlignment: pw.CrossAxisAlignment.start,
children: [
pw.Expanded(
flex: 1,
child: pw.Column(
crossAxisAlignment: pw.CrossAxisAlignment.start,
children: [
_buildSummaryItem(
'Total Item',
(inventory.summary.totalProducts).toString(),
),
_buildSummaryItem(
'Total Item Masuk',
(inventory.products.fold<num>(
0,
(sum, item) => sum + (item.totalIn),
)).toString(),
),
_buildSummaryItem(
'Total Item Keluar',
(inventory.products.fold<num>(
0,
(sum, item) => sum + (item.totalOut),
)).toString(),
),
],
),
),
pw.SizedBox(width: 20),
pw.Expanded(
flex: 1,
child: pw.Column(
crossAxisAlignment: pw.CrossAxisAlignment.start,
children: [
_buildSummaryItem(
'Total Ingredient',
(inventory.summary.totalIngredients).toString(),
),
_buildSummaryItem(
'Total Ingredient Masuk',
(inventory.ingredients.fold<num>(
0,
(sum, item) => sum + (item.totalIn),
)).toString(),
),
_buildSummaryItem(
'Total Ingredient Keluar',
(inventory.ingredients.fold<num>(
0,
(sum, item) => sum + (item.totalOut),
)).toString(),
),
],
),
),
],
),
],
),
),
// Summary Item
pw.Container(
padding: pw.EdgeInsets.all(20),
child: pw.Column(
children: [
pw.Column(
crossAxisAlignment: pw.CrossAxisAlignment.start,
children: [
_buildSectionWidget('2. Item'),
pw.SizedBox(height: 30),
pw.Container(
decoration: pw.BoxDecoration(
color: primaryColor, // Purple color
borderRadius: pw.BorderRadius.only(
topLeft: pw.Radius.circular(8),
topRight: pw.Radius.circular(8),
),
),
child: pw.Table(
columnWidths: const {
0: pw.FlexColumnWidth(2.5), // Produk
1: pw.FlexColumnWidth(2), // Kategori
2: pw.FlexColumnWidth(1), // Stock
3: pw.FlexColumnWidth(2), // Masuk
4: pw.FlexColumnWidth(2), // Keluar
},
children: [
pw.TableRow(
children: [
_buildHeaderCell('Nama'),
_buildHeaderCell('Kategori'),
_buildHeaderCell('Stock'),
_buildHeaderCell('Masuk'),
_buildHeaderCell('Keluar'),
],
),
],
),
),
pw.Container(
decoration: pw.BoxDecoration(color: PdfColors.white),
child: pw.Table(
columnWidths: {
0: pw.FlexColumnWidth(2.5), // Produk
1: pw.FlexColumnWidth(2), // Kategori
2: pw.FlexColumnWidth(1), // Stock
3: pw.FlexColumnWidth(2), // Masuk
4: pw.FlexColumnWidth(2), // Keluar
},
children: inventory.products
.map(
(item) => _buildProductDataRow(
item,
inventory.products.indexOf(item) % 2 == 0,
),
)
.toList(),
),
),
pw.Container(
decoration: pw.BoxDecoration(
color: primaryColor, // Purple color
borderRadius: pw.BorderRadius.only(
bottomLeft: pw.Radius.circular(8),
bottomRight: pw.Radius.circular(8),
),
),
child: pw.Table(
columnWidths: const {
0: pw.FlexColumnWidth(2.5), // Produk
1: pw.FlexColumnWidth(2), // Kategori
2: pw.FlexColumnWidth(1), // Stock
3: pw.FlexColumnWidth(2), // Masuk
4: pw.FlexColumnWidth(2), // Keluar
},
children: [
pw.TableRow(
children: [
_buildTotalCell('TOTAL'),
_buildTotalCell(''),
_buildTotalCell(
(inventory.products.fold<num>(
0,
(sum, item) => sum + (item.quantity),
)).toString(),
),
_buildTotalCell(
(inventory.products.fold<num>(
0,
(sum, item) => sum + (item.totalIn),
)).toString(),
),
_buildTotalCell(
(inventory.products.fold<num>(
0,
(sum, item) => sum + (item.totalOut),
)).toString(),
),
],
),
],
),
),
],
),
],
),
),
// Summary Ingredient
pw.Container(
padding: pw.EdgeInsets.all(20),
child: pw.Column(
children: [
pw.Column(
crossAxisAlignment: pw.CrossAxisAlignment.start,
children: [
_buildSectionWidget('3. Ingredient'),
pw.SizedBox(height: 30),
pw.Container(
decoration: pw.BoxDecoration(
color: primaryColor, // Purple color
borderRadius: pw.BorderRadius.only(
topLeft: pw.Radius.circular(8),
topRight: pw.Radius.circular(8),
),
),
child: pw.Table(
columnWidths: const {
0: pw.FlexColumnWidth(2.5), // Name
1: pw.FlexColumnWidth(1), // Stock
2: pw.FlexColumnWidth(2), // Masuk
3: pw.FlexColumnWidth(2), // Keluar
},
children: [
pw.TableRow(
children: [
_buildHeaderCell('Nama'),
_buildHeaderCell('Stock'),
_buildHeaderCell('Masuk'),
_buildHeaderCell('Keluar'),
],
),
],
),
),
pw.Container(
decoration: pw.BoxDecoration(color: PdfColors.white),
child: pw.Table(
columnWidths: {
0: pw.FlexColumnWidth(2.5), // Name
1: pw.FlexColumnWidth(1), // Stock
2: pw.FlexColumnWidth(2), // Masuk
3: pw.FlexColumnWidth(2), // Keluar
},
children: inventory.ingredients
.map(
(item) => _buildIngredientsDataRow(
item,
inventory.ingredients.indexOf(item) % 2 == 0,
),
)
.toList(),
),
),
pw.Container(
decoration: pw.BoxDecoration(
color: primaryColor, // Purple color
borderRadius: pw.BorderRadius.only(
bottomLeft: pw.Radius.circular(8),
bottomRight: pw.Radius.circular(8),
),
),
child: pw.Table(
columnWidths: const {
0: pw.FlexColumnWidth(2.5), // Name
1: pw.FlexColumnWidth(1), // Stock
2: pw.FlexColumnWidth(2), // Masuk
3: pw.FlexColumnWidth(2), // Keluar
},
children: [
pw.TableRow(
children: [
_buildTotalCell('TOTAL'),
_buildTotalCell(
(inventory.ingredients.fold<num>(
0,
(sum, item) => sum + (item.quantity),
)).toString(),
),
_buildTotalCell(
(inventory.ingredients.fold<num>(
0,
(sum, item) => sum + (item.totalIn),
)).toString(),
),
_buildTotalCell(
(inventory.ingredients.fold<num>(
0,
(sum, item) => sum + (item.totalOut),
)).toString(),
),
],
),
],
),
),
],
),
],
),
),
];
},
),
);
return HelperPdfService.saveDocument(
name:
'Apskel POS | Inventory Report | ${DateTime.now().millisecondsSinceEpoch}.pdf',
pdf: pdf,
);
}
static pw.Widget _buildSectionWidget(String title) {
return pw.Text(
title,
style: pw.TextStyle(
fontSize: 20,
fontWeight: pw.FontWeight.bold,
color: primaryColor,
),
);
}
static pw.Widget _buildSummaryItem(
String label,
String value, {
pw.TextStyle? valueStyle,
pw.TextStyle? labelStyle,
}) {
return pw.Container(
padding: pw.EdgeInsets.only(bottom: 8),
margin: pw.EdgeInsets.only(bottom: 16),
decoration: pw.BoxDecoration(
border: pw.Border(bottom: pw.BorderSide(color: PdfColors.grey300)),
),
child: pw.Row(
mainAxisAlignment: pw.MainAxisAlignment.spaceBetween,
children: [
pw.Text(label, style: labelStyle),
pw.Text(
value,
style: valueStyle ?? pw.TextStyle(fontWeight: pw.FontWeight.bold),
),
],
),
);
}
static pw.Widget _buildHeaderCell(String text) {
return pw.Container(
padding: pw.EdgeInsets.symmetric(horizontal: 12, vertical: 16),
child: pw.Text(
text,
style: pw.TextStyle(
color: PdfColors.white,
fontWeight: pw.FontWeight.bold,
fontSize: 12,
),
textAlign: pw.TextAlign.center,
),
);
}
static pw.Widget _buildDataCell(
String text, {
pw.Alignment alignment = pw.Alignment.center,
PdfColor? textColor,
}) {
return pw.Container(
padding: pw.EdgeInsets.symmetric(horizontal: 12, vertical: 16),
alignment: alignment,
child: pw.Text(
text,
style: pw.TextStyle(
fontSize: 12,
color: textColor ?? PdfColors.black,
fontWeight: pw.FontWeight.normal,
),
textAlign: alignment == pw.Alignment.centerLeft
? pw.TextAlign.left
: pw.TextAlign.center,
),
);
}
static pw.Widget _buildTotalCell(String text) {
return pw.Container(
padding: pw.EdgeInsets.symmetric(horizontal: 12, vertical: 16),
child: pw.Text(
text,
style: pw.TextStyle(
color: PdfColors.white,
fontWeight: pw.FontWeight.bold,
fontSize: 12,
),
textAlign: pw.TextAlign.center,
),
);
}
static pw.TableRow _buildProductDataRow(
InventoryProduct product,
bool isEven,
) {
return pw.TableRow(
decoration: pw.BoxDecoration(
color: product.isZeroStock
? PdfColors.red100
: product.isLowStock
? PdfColors.yellow100
: isEven
? PdfColors.grey50
: PdfColors.white,
),
children: [
_buildDataCell(product.productName, alignment: pw.Alignment.centerLeft),
_buildDataCell(
product.categoryName,
alignment: pw.Alignment.centerLeft,
),
_buildDataCell(product.quantity.toString()),
_buildDataCell(product.totalIn.toString()),
_buildDataCell(product.totalOut.toString()),
],
);
}
static pw.TableRow _buildIngredientsDataRow(
InventoryIngredient item,
bool isEven,
) {
return pw.TableRow(
decoration: pw.BoxDecoration(
color: item.isZeroStock
? PdfColors.red100
: item.isLowStock
? PdfColors.yellow100
: isEven
? PdfColors.grey50
: PdfColors.white,
),
children: [
_buildDataCell(item.ingredientName, alignment: pw.Alignment.centerLeft),
_buildDataCell(item.quantity.toString()),
_buildDataCell(item.totalIn.toString()),
_buildDataCell(item.totalOut.toString()),
],
);
}
}

View File

@ -0,0 +1,956 @@
import 'dart:io';
import 'package:flutter/services.dart';
import 'package:pdf/pdf.dart';
import 'package:pdf/widgets.dart' as pw;
import '../../../common/extension/extension.dart';
import '../../../common/utils/pdf_service.dart';
import '../../../domain/analytic/analytic.dart';
import '../../../domain/outlet/outlet.dart';
class TransactionReport {
static final primaryColor = PdfColor.fromHex("36175e");
static Future<File> previewPdf({
required Outlet outlet,
required String searchDateFormatted,
required CategoryAnalytic categoryAnalyticData,
required ProfitLossAnalytic profitLossData,
required PaymentMethodAnalytic paymentMethodAnalyticData,
required ProductAnalytic productAnalyticData,
}) async {
final pdf = pw.Document();
final ByteData dataImage = await rootBundle.load('assets/images/logo.png');
final Uint8List bytes = dataImage.buffer.asUint8List();
final profitLossProductSummary = {
'totalRevenue': profitLossData.productData.fold<num>(
0,
(sum, item) => sum + (item.revenue),
),
'totalCost': profitLossData.productData.fold<num>(
0,
(sum, item) => sum + (item.cost),
),
'totalGrossProfit': profitLossData.productData.fold<num>(
0,
(sum, item) => sum + (item.grossProfit),
),
'totalQuantity': profitLossData.productData.fold<num>(
0,
(sum, item) => sum + (item.quantitySold),
),
};
final categorySummary = {
'totalRevenue': categoryAnalyticData.data.fold<num>(
0,
(sum, item) => sum + (item.totalRevenue),
),
'orderCount': categoryAnalyticData.data.fold<num>(
0,
(sum, item) => sum + (item.orderCount),
),
'productCount': categoryAnalyticData.data.fold<num>(
0,
(sum, item) => sum + (item.productCount),
),
'totalQuantity': categoryAnalyticData.data.fold<num>(
0,
(sum, item) => sum + (item.totalQuantity),
),
};
final productItemSummary = {
'totalRevenue': productAnalyticData.data.fold<num>(
0,
(sum, item) => sum + (item.revenue),
),
'orderCount': productAnalyticData.data.fold<num>(
0,
(sum, item) => sum + (item.orderCount),
),
'totalQuantitySold': productAnalyticData.data.fold<num>(
0,
(sum, item) => sum + (item.quantitySold),
),
};
// Membuat objek Image dari gambar
final image = pw.MemoryImage(bytes);
pdf.addPage(
pw.MultiPage(
pageFormat: PdfPageFormat.a4,
margin: pw.EdgeInsets.zero,
build: (pw.Context context) {
return [
pw.Container(
padding: pw.EdgeInsets.all(20),
child: pw.Row(
mainAxisAlignment: pw.MainAxisAlignment.spaceBetween,
crossAxisAlignment: pw.CrossAxisAlignment.start,
children: [
// Bagian kiri - Logo dan Info Perusahaan
pw.Row(
crossAxisAlignment: pw.CrossAxisAlignment.center,
children: [
// Icon/Logo placeholder (bisa diganti dengan gambar logo)
pw.Container(
width: 40,
height: 40,
child: pw.Image(image),
),
pw.SizedBox(width: 15),
pw.Column(
crossAxisAlignment: pw.CrossAxisAlignment.start,
children: [
pw.Text(
'Apskel',
style: pw.TextStyle(
fontSize: 28,
fontWeight: pw.FontWeight.bold,
color: primaryColor,
),
),
pw.SizedBox(height: 4),
pw.Text(
outlet.name,
style: pw.TextStyle(
fontSize: 16,
color: PdfColors.grey700,
),
),
pw.SizedBox(height: 2),
pw.Text(
outlet.address,
style: pw.TextStyle(
fontSize: 12,
color: PdfColors.grey600,
),
),
],
),
],
),
// Bagian kanan - Info Laporan
pw.Column(
crossAxisAlignment: pw.CrossAxisAlignment.end,
children: [
pw.Text(
'Laporan Transaksi',
style: pw.TextStyle(
fontSize: 24,
fontWeight: pw.FontWeight.bold,
color: PdfColors.grey800,
),
),
pw.SizedBox(height: 8),
pw.Text(
searchDateFormatted,
style: pw.TextStyle(
fontSize: 14,
color: PdfColors.grey600,
),
),
pw.SizedBox(height: 4),
pw.Text(
'Laporan',
style: pw.TextStyle(
fontSize: 12,
color: PdfColors.grey500,
),
),
],
),
],
),
),
pw.Container(
width: double.infinity,
height: 3,
color: primaryColor,
),
// Summary
pw.Container(
padding: pw.EdgeInsets.all(20),
child: pw.Column(
crossAxisAlignment: pw.CrossAxisAlignment.start,
children: [
_buildSectionWidget('1. Ringkasan'),
pw.SizedBox(height: 30),
pw.Row(
crossAxisAlignment: pw.CrossAxisAlignment.start,
children: [
pw.Expanded(
flex: 1,
child: pw.Column(
crossAxisAlignment: pw.CrossAxisAlignment.start,
children: [
_buildSummaryItem(
'Total Penjualan (termasuk rasik)',
(profitLossData.summary.totalRevenue)
.toString()
.currencyFormatRpV2,
),
_buildSummaryItem(
'Total Terjual',
(profitLossData.summary.totalOrders).toString(),
),
_buildSummaryItem(
'HPP',
'${safeCurrency(profitLossData.summary.totalCost)} | ${safePercentage(profitLossData.summary.totalCost, profitLossData.summary.totalRevenue)}',
),
_buildSummaryItem(
'Laba Kotor',
'${safeCurrency(profitLossData.summary.grossProfit)} | ${safeRound(profitLossData.summary.grossProfitMargin)}%',
valueStyle: pw.TextStyle(
color: PdfColors.green800,
fontWeight: pw.FontWeight.bold,
fontSize: 16,
),
labelStyle: pw.TextStyle(
color: PdfColors.green800,
fontWeight: pw.FontWeight.bold,
fontSize: 16,
),
),
],
),
),
pw.SizedBox(width: 20),
pw.Expanded(
flex: 1,
child: pw.Column(
crossAxisAlignment: pw.CrossAxisAlignment.start,
children: [
_buildSummaryItem(
'Biaya Lain lain',
'${safeCurrency(profitLossData.summary.totalTax)} | ${safePercentage(profitLossData.summary.totalTax, profitLossData.summary.totalRevenue)}',
),
_buildSummaryItem(
'Laba/Rugi',
'${safeCurrency(profitLossData.summary.netProfit)} | ${safeRound(profitLossData.summary.netProfitMargin)}%',
valueStyle: pw.TextStyle(
color: PdfColors.blue800,
fontWeight: pw.FontWeight.bold,
fontSize: 16,
),
labelStyle: pw.TextStyle(
color: PdfColors.blue800,
fontWeight: pw.FontWeight.bold,
fontSize: 16,
),
),
],
),
),
],
),
pw.SizedBox(height: 16),
pw.Text(
"Laba Rugi Perproduk",
style: pw.TextStyle(
fontSize: 16,
fontWeight: pw.FontWeight.bold,
color: primaryColor,
),
),
pw.SizedBox(height: 20),
pw.Column(
children: [
pw.Container(
decoration: pw.BoxDecoration(
color: primaryColor, // Purple color
borderRadius: pw.BorderRadius.only(
topLeft: pw.Radius.circular(8),
topRight: pw.Radius.circular(8),
),
),
child: pw.Table(
columnWidths: const {
0: pw.FlexColumnWidth(2.5), // Produk
1: pw.FlexColumnWidth(1), // Qty
2: pw.FlexColumnWidth(2.5), // Pendapatan
3: pw.FlexColumnWidth(2), // HPP
4: pw.FlexColumnWidth(2), // Laba Kotor
5: pw.FlexColumnWidth(2), // Margin (%)
},
children: [
pw.TableRow(
children: [
_buildHeaderCell('Produk'),
_buildHeaderCell('Qty'),
_buildHeaderCell('Pendapatan'),
_buildHeaderCell('HPP'),
_buildHeaderCell('Laba Kotor'),
_buildHeaderCell('Margin (%)'),
],
),
],
),
),
pw.Container(
decoration: pw.BoxDecoration(color: PdfColors.white),
child: pw.Table(
columnWidths: {
0: pw.FlexColumnWidth(2.5), // Produk
1: pw.FlexColumnWidth(1), // Qty
2: pw.FlexColumnWidth(2.5), // Pendapatan
3: pw.FlexColumnWidth(2), // HPP
4: pw.FlexColumnWidth(2), // Laba Kotor
5: pw.FlexColumnWidth(2), // Margin (%)
},
children: profitLossData.productData
.map(
(profitLoss) => _buildPerProductDataRow(
product: profitLoss.productName,
qty: profitLoss.quantitySold.toString(),
pendapatan: profitLoss.revenue
.toString()
.currencyFormatRpV2,
hpp: profitLoss.cost
.toString()
.currencyFormatRpV2,
labaKotor: profitLoss.grossProfit
.toString()
.currencyFormatRpV2,
margin:
'${safeRound(profitLoss.grossProfitMargin)}%',
isEven:
profitLossData.productData.indexOf(
profitLoss,
) %
2 ==
0,
),
)
.toList(),
),
),
pw.Container(
decoration: pw.BoxDecoration(
color: primaryColor, // Purple color
borderRadius: pw.BorderRadius.only(
bottomLeft: pw.Radius.circular(8),
bottomRight: pw.Radius.circular(8),
),
),
child: pw.Table(
columnWidths: const {
0: pw.FlexColumnWidth(2.5), // Produk
1: pw.FlexColumnWidth(1), // Qty
2: pw.FlexColumnWidth(2.5), // Pendapatan
3: pw.FlexColumnWidth(2), // HPP
4: pw.FlexColumnWidth(2), // Laba Kotor
5: pw.FlexColumnWidth(2), // Margin (%)
},
children: [
pw.TableRow(
children: [
_buildTotalCell('TOTAL'),
_buildTotalCell(
profitLossProductSummary['totalQuantity']
.toString(),
),
_buildTotalCell(
profitLossProductSummary['totalRevenue']
.toString()
.currencyFormatRpV2,
),
_buildTotalCell(
profitLossProductSummary['totalCost']
.toString()
.currencyFormatRpV2,
),
_buildTotalCell(
profitLossProductSummary['totalGrossProfit']
.toString()
.currencyFormatRpV2,
),
_buildTotalCell(''),
],
),
],
),
),
],
),
],
),
),
// Summary Payment Method
pw.Container(
padding: pw.EdgeInsets.all(20),
child: pw.Column(
children: [
pw.Column(
crossAxisAlignment: pw.CrossAxisAlignment.start,
children: [
_buildSectionWidget('2. Ringkasan Metode Pembayaran'),
pw.SizedBox(height: 30),
pw.Container(
decoration: pw.BoxDecoration(
color: primaryColor, // Purple color
borderRadius: pw.BorderRadius.only(
topLeft: pw.Radius.circular(8),
topRight: pw.Radius.circular(8),
),
),
child: pw.Table(
columnWidths: const {
0: pw.FlexColumnWidth(2.5), // Nama
1: pw.FlexColumnWidth(1), // Tipe
2: pw.FlexColumnWidth(2.5), // Jumlah Order
3: pw.FlexColumnWidth(2), // Total Amount
4: pw.FlexColumnWidth(2), // Presentase
},
children: [
pw.TableRow(
children: [
_buildHeaderCell('Nama'),
_buildHeaderCell('Tipe'),
_buildHeaderCell('Jumlah Order'),
_buildHeaderCell('Total Amount'),
_buildHeaderCell('Presentase'),
],
),
],
),
),
pw.Container(
decoration: pw.BoxDecoration(color: PdfColors.white),
child: pw.Table(
columnWidths: {
0: pw.FlexColumnWidth(2.5), // Nama
1: pw.FlexColumnWidth(1), // Tipe
2: pw.FlexColumnWidth(2.5), // Jumlah Order
3: pw.FlexColumnWidth(2), // Total Amount
4: pw.FlexColumnWidth(2), // Presentase
},
children: paymentMethodAnalyticData.data
.map(
(payment) => _buildPaymentMethodDataRow(
name: payment.paymentMethodName,
tipe: payment.paymentMethodType.toTitleCase,
jumlahOrder: payment.orderCount.toString(),
totalAmount: payment.totalAmount
.toString()
.currencyFormatRpV2,
presentase:
'${safeRound(payment.percentage)}%',
isEven:
paymentMethodAnalyticData.data.indexOf(
payment,
) %
2 ==
0,
),
)
.toList(),
),
),
pw.Container(
decoration: pw.BoxDecoration(
color: primaryColor, // Purple color
borderRadius: pw.BorderRadius.only(
bottomLeft: pw.Radius.circular(8),
bottomRight: pw.Radius.circular(8),
),
),
child: pw.Table(
columnWidths: const {
0: pw.FlexColumnWidth(2.5), // Produk
1: pw.FlexColumnWidth(1), // Qty
2: pw.FlexColumnWidth(2.5), // Pendapatan
3: pw.FlexColumnWidth(2), // HPP
4: pw.FlexColumnWidth(2), // Laba Kotor
5: pw.FlexColumnWidth(2), // Margin (%)
},
children: [
pw.TableRow(
children: [
_buildTotalCell('TOTAL'),
_buildTotalCell(''),
_buildTotalCell(
(paymentMethodAnalyticData
.summary
.totalOrders)
.toString(),
),
_buildTotalCell(
(paymentMethodAnalyticData
.summary
.totalAmount)
.toString()
.currencyFormatRpV2,
),
_buildTotalCell(''),
],
),
],
),
),
],
),
],
),
),
// Summary Category
pw.Container(
padding: pw.EdgeInsets.all(20),
child: pw.Column(
crossAxisAlignment: pw.CrossAxisAlignment.start,
children: [
_buildSectionWidget('3. Ringkasan Kategori'),
pw.SizedBox(height: 30),
pw.Column(
children: [
pw.Container(
decoration: pw.BoxDecoration(
color: primaryColor, // Purple color
borderRadius: pw.BorderRadius.only(
topLeft: pw.Radius.circular(8),
topRight: pw.Radius.circular(8),
),
),
child: pw.Table(
columnWidths: const {
0: pw.FlexColumnWidth(2.5), // Nama
1: pw.FlexColumnWidth(2), // Total Product
2: pw.FlexColumnWidth(1), // qty
3: pw.FlexColumnWidth(2), // Jumlah Order
4: pw.FlexColumnWidth(2.5), // Presentase
},
children: [
pw.TableRow(
children: [
_buildHeaderCell('Nama'),
_buildHeaderCell('Total Produk'),
_buildHeaderCell('Qty'),
_buildHeaderCell('Jumlah Order'),
_buildHeaderCell('Pendapatan'),
],
),
],
),
),
pw.Container(
decoration: pw.BoxDecoration(color: PdfColors.white),
child: pw.Table(
columnWidths: {
0: pw.FlexColumnWidth(2.5), // Nama
1: pw.FlexColumnWidth(2), // Total Product
2: pw.FlexColumnWidth(1), // qty
3: pw.FlexColumnWidth(2), // Jumlah Order
4: pw.FlexColumnWidth(2.5), // Presentase
},
children: categoryAnalyticData.data
.map(
(category) => _buildCategoryDataRow(
name: category.categoryName,
totalProduct: category.productCount
.toString(),
qty: category.totalQuantity.toString(),
jumlahOrder: category.orderCount.toString(),
pendapatan: category.totalRevenue
.toString()
.currencyFormatRpV2,
isEven:
categoryAnalyticData.data.indexOf(
category,
) %
2 ==
0,
),
)
.toList(),
),
),
pw.Container(
decoration: pw.BoxDecoration(
color: primaryColor, // Purple color
borderRadius: pw.BorderRadius.only(
bottomLeft: pw.Radius.circular(8),
bottomRight: pw.Radius.circular(8),
),
),
child: pw.Table(
columnWidths: const {
0: pw.FlexColumnWidth(2.5), // Nama
1: pw.FlexColumnWidth(2), // Total Product
2: pw.FlexColumnWidth(1), // qty
3: pw.FlexColumnWidth(2), // Jumlah Order
4: pw.FlexColumnWidth(2.5), // Presentase
},
children: [
pw.TableRow(
children: [
_buildTotalCell('TOTAL'),
_buildTotalCell(
categorySummary['productCount'].toString(),
),
_buildTotalCell(
categorySummary['totalQuantity'].toString(),
),
_buildTotalCell(
categorySummary['orderCount'].toString(),
),
_buildTotalCell(
categorySummary['totalRevenue']
.toString()
.currencyFormatRpV2,
),
],
),
],
),
),
],
),
],
),
),
// Summary Item
pw.Container(
padding: pw.EdgeInsets.all(20),
child: pw.Column(
children: [
pw.Column(
crossAxisAlignment: pw.CrossAxisAlignment.start,
children: [
_buildSectionWidget('4. Ringkasan Item'),
pw.SizedBox(height: 30),
pw.Container(
decoration: pw.BoxDecoration(
color: primaryColor, // Purple color
borderRadius: pw.BorderRadius.only(
topLeft: pw.Radius.circular(8),
topRight: pw.Radius.circular(8),
),
),
child: pw.Table(
columnWidths: const {
0: pw.FlexColumnWidth(2.5), // Produk
1: pw.FlexColumnWidth(2), // Kategori
2: pw.FlexColumnWidth(1), // qty
3: pw.FlexColumnWidth(2), // Order
4: pw.FlexColumnWidth(2), // Pendapatan
5: pw.FlexColumnWidth(2), // Average
},
children: [
pw.TableRow(
children: [
_buildHeaderCell('Produk'),
_buildHeaderCell('Kategori'),
_buildHeaderCell('Qty'),
_buildHeaderCell('Order'),
_buildHeaderCell('Pendapatan'),
_buildHeaderCell('Rata Rata'),
],
),
],
),
),
pw.Container(
decoration: pw.BoxDecoration(color: PdfColors.white),
child: pw.Table(
columnWidths: {
0: pw.FlexColumnWidth(2.5), // Produk
1: pw.FlexColumnWidth(2), // Kategori
2: pw.FlexColumnWidth(1), // qty
3: pw.FlexColumnWidth(2), // Order
4: pw.FlexColumnWidth(2), // Pendapatan
5: pw.FlexColumnWidth(2), // Average
},
children: productAnalyticData.data
.map(
(item) => _buildItemDataRow(
product: item.productName,
category: item.categoryName,
qty: item.quantitySold.toString(),
order: item.orderCount.toString(),
pendapatan: item.revenue
.toString()
.currencyFormatRpV2,
average: safeCurrency(
item.averagePrice.round(),
),
isEven:
productAnalyticData.data.indexOf(item) %
2 ==
0,
),
)
.toList(),
),
),
pw.Container(
decoration: pw.BoxDecoration(
color: primaryColor, // Purple color
borderRadius: pw.BorderRadius.only(
bottomLeft: pw.Radius.circular(8),
bottomRight: pw.Radius.circular(8),
),
),
child: pw.Table(
columnWidths: const {
0: pw.FlexColumnWidth(2.5), // Produk
1: pw.FlexColumnWidth(2), // Kategori
2: pw.FlexColumnWidth(1), // qty
3: pw.FlexColumnWidth(2), // Order
4: pw.FlexColumnWidth(2), // Pendapatan
5: pw.FlexColumnWidth(2), // Average
},
children: [
pw.TableRow(
children: [
_buildTotalCell('TOTAL'),
_buildTotalCell(''),
_buildTotalCell(
productItemSummary['totalQuantitySold']
.toString(),
),
_buildTotalCell(
productItemSummary['orderCount'].toString(),
),
_buildTotalCell(
productItemSummary['totalRevenue']
.toString()
.currencyFormatRpV2,
),
_buildTotalCell(''),
],
),
],
),
),
],
),
],
),
),
];
},
),
);
return HelperPdfService.saveDocument(
name: 'Laporan Transaksi | $searchDateFormatted.pdf',
pdf: pdf,
);
}
static String safePercentage(num numerator, num denominator) {
if (denominator == 0 ||
numerator.isInfinite ||
numerator.isNaN ||
denominator.isInfinite ||
denominator.isNaN) {
return '0%';
}
final result = (numerator / denominator) * 100;
if (result.isInfinite || result.isNaN) {
return '0%';
}
return '${result.round()}%';
}
static String safeRound(num value) {
if (value.isInfinite || value.isNaN) {
return '0';
}
return value.round().toString();
}
static String safeCurrency(num value) {
if (value.isInfinite || value.isNaN) {
return '0'.currencyFormatRpV2;
}
return value.toString().currencyFormatRpV2;
}
static pw.Widget _buildSectionWidget(String title) {
return pw.Text(
title,
style: pw.TextStyle(
fontSize: 20,
fontWeight: pw.FontWeight.bold,
color: primaryColor,
),
);
}
static pw.Widget _buildSummaryItem(
String label,
String value, {
pw.TextStyle? valueStyle,
pw.TextStyle? labelStyle,
}) {
return pw.Container(
padding: pw.EdgeInsets.only(bottom: 8),
margin: pw.EdgeInsets.only(bottom: 16),
decoration: pw.BoxDecoration(
border: pw.Border(bottom: pw.BorderSide(color: PdfColors.grey300)),
),
child: pw.Row(
mainAxisAlignment: pw.MainAxisAlignment.spaceBetween,
children: [
pw.Text(label, style: labelStyle),
pw.Text(
value,
style: valueStyle ?? pw.TextStyle(fontWeight: pw.FontWeight.bold),
),
],
),
);
}
static pw.Widget _buildHeaderCell(String text) {
return pw.Container(
padding: pw.EdgeInsets.symmetric(horizontal: 12, vertical: 16),
child: pw.Text(
text,
style: pw.TextStyle(
color: PdfColors.white,
fontWeight: pw.FontWeight.bold,
fontSize: 12,
),
textAlign: pw.TextAlign.center,
),
);
}
static pw.Widget _buildDataCell(
String text, {
pw.Alignment alignment = pw.Alignment.center,
PdfColor? textColor,
}) {
return pw.Container(
padding: pw.EdgeInsets.symmetric(horizontal: 12, vertical: 16),
alignment: alignment,
child: pw.Text(
text,
style: pw.TextStyle(
fontSize: 12,
color: textColor ?? PdfColors.black,
fontWeight: pw.FontWeight.normal,
),
textAlign: alignment == pw.Alignment.centerLeft
? pw.TextAlign.left
: pw.TextAlign.center,
),
);
}
static pw.Widget _buildTotalCell(String text) {
return pw.Container(
padding: pw.EdgeInsets.symmetric(horizontal: 12, vertical: 16),
child: pw.Text(
text,
style: pw.TextStyle(
color: PdfColors.white,
fontWeight: pw.FontWeight.bold,
fontSize: 12,
),
textAlign: pw.TextAlign.center,
),
);
}
static pw.TableRow _buildPerProductDataRow({
required String product,
required String qty,
required String pendapatan,
required String hpp,
required String labaKotor,
required String margin,
required bool isEven,
}) {
return pw.TableRow(
decoration: pw.BoxDecoration(
color: isEven ? PdfColors.grey50 : PdfColors.white,
),
children: [
_buildDataCell(product, alignment: pw.Alignment.centerLeft),
_buildDataCell(qty),
_buildDataCell(pendapatan),
_buildDataCell(hpp, textColor: PdfColors.red600),
_buildDataCell(labaKotor, textColor: PdfColors.green600),
_buildDataCell(margin),
],
);
}
static pw.TableRow _buildPaymentMethodDataRow({
required String name,
required String tipe,
required String jumlahOrder,
required String totalAmount,
required String presentase,
required bool isEven,
}) {
return pw.TableRow(
decoration: pw.BoxDecoration(
color: isEven ? PdfColors.grey50 : PdfColors.white,
),
children: [
_buildDataCell(name, alignment: pw.Alignment.centerLeft),
_buildDataCell(tipe),
_buildDataCell(jumlahOrder),
_buildDataCell(totalAmount),
_buildDataCell(presentase),
],
);
}
static pw.TableRow _buildCategoryDataRow({
required String name,
required String totalProduct,
required String qty,
required String jumlahOrder,
required String pendapatan,
required bool isEven,
}) {
return pw.TableRow(
decoration: pw.BoxDecoration(
color: isEven ? PdfColors.grey50 : PdfColors.white,
),
children: [
_buildDataCell(name, alignment: pw.Alignment.centerLeft),
_buildDataCell(totalProduct),
_buildDataCell(qty),
_buildDataCell(jumlahOrder),
_buildDataCell(pendapatan),
],
);
}
static pw.TableRow _buildItemDataRow({
required String product,
required String category,
required String qty,
required String order,
required String pendapatan,
required String average,
required bool isEven,
}) {
return pw.TableRow(
decoration: pw.BoxDecoration(
color: isEven ? PdfColors.grey50 : PdfColors.white,
),
children: [
_buildDataCell(product, alignment: pw.Alignment.centerLeft),
_buildDataCell(category, alignment: pw.Alignment.centerLeft),
_buildDataCell(qty),
_buildDataCell(order),
_buildDataCell(pendapatan),
_buildDataCell(average),
],
);
}
}

View File

@ -3,6 +3,7 @@ import 'package:flutter/material.dart';
import '../../../common/theme/theme.dart';
import '../../../domain/auth/auth.dart';
import '../../../domain/user/user.dart';
class AppFlushbar {
static void showSuccess(BuildContext context, String message) {
@ -51,4 +52,15 @@ class AppFlushbar {
unexpectedError: (value) => 'Error has eccoured',
),
);
static void showUserFailureToast(BuildContext context, UserFailure failure) =>
showError(
context,
failure.map(
serverError: (value) => value.failure.toStringFormatted(context),
dynamicErrorMessage: (value) => value.erroMessage,
unexpectedError: (value) => 'Error has eccoured',
empty: (value) => 'Data not found',
),
);
}

View File

@ -0,0 +1,330 @@
import 'package:flutter/material.dart';
import 'package:auto_route/auto_route.dart';
import 'package:package_info_plus/package_info_plus.dart';
import 'package:device_info_plus/device_info_plus.dart';
import '../../../common/theme/theme.dart';
@RoutePage()
class AboutAppPage extends StatefulWidget {
const AboutAppPage({super.key});
@override
State<AboutAppPage> createState() => _AboutAppPageState();
}
class _AboutAppPageState extends State<AboutAppPage>
with TickerProviderStateMixin {
PackageInfo? packageInfo;
String deviceInfo = '';
late AnimationController _fadeController;
late AnimationController _slideController;
late Animation<double> _fadeAnimation;
late Animation<Offset> _slideAnimation;
@override
void initState() {
super.initState();
_initAnimations();
_loadAppInfo();
}
void _initAnimations() {
_fadeController = AnimationController(
duration: const Duration(milliseconds: 800),
vsync: this,
);
_slideController = AnimationController(
duration: const Duration(milliseconds: 1000),
vsync: this,
);
_fadeAnimation = Tween<double>(begin: 0.0, end: 1.0).animate(
CurvedAnimation(parent: _fadeController, curve: Curves.easeInOut),
);
_slideAnimation =
Tween<Offset>(begin: const Offset(0, 0.3), end: Offset.zero).animate(
CurvedAnimation(parent: _slideController, curve: Curves.elasticOut),
);
_fadeController.forward();
Future.delayed(const Duration(milliseconds: 300), () {
_slideController.forward();
});
}
Future<void> _loadAppInfo() async {
try {
final info = await PackageInfo.fromPlatform();
final deviceInfoPlugin = DeviceInfoPlugin();
String device = '';
if (Theme.of(context).platform == TargetPlatform.android) {
final androidInfo = await deviceInfoPlugin.androidInfo;
device = '${androidInfo.brand} ${androidInfo.model}';
} else if (Theme.of(context).platform == TargetPlatform.iOS) {
final iosInfo = await deviceInfoPlugin.iosInfo;
device = '${iosInfo.name} ${iosInfo.model}';
}
setState(() {
packageInfo = info;
deviceInfo = device;
});
} catch (e) {
print('Error loading app info: $e');
}
}
@override
void dispose() {
_fadeController.dispose();
_slideController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: CustomScrollView(
physics: const BouncingScrollPhysics(),
slivers: [_buildSliverAppBar(), _buildContent()],
),
);
}
Widget _buildSliverAppBar() {
return SliverAppBar(
expandedHeight: 280.0,
pinned: true,
elevation: 0,
backgroundColor: AppColor.primary,
flexibleSpace: FlexibleSpaceBar(
title: AnimatedBuilder(
animation: _fadeAnimation,
builder: (context, child) {
return Opacity(
opacity: _fadeAnimation.value,
child: Text(
'Tentang Aplikasi',
style: AppStyle.lg.copyWith(
color: AppColor.white,
fontWeight: FontWeight.bold,
),
),
);
},
),
background: Container(
decoration: const BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: AppColor.primaryGradient,
),
),
child: Stack(
children: [
// Background pattern
Positioned.fill(child: CustomPaint(painter: _PatternPainter())),
// App icon and version
Center(
child: FadeTransition(
opacity: _fadeAnimation,
child: SlideTransition(
position: _slideAnimation,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
width: 100,
height: 100,
decoration: BoxDecoration(
color: AppColor.white,
borderRadius: BorderRadius.circular(25),
boxShadow: [
BoxShadow(
color: AppColor.black.withOpacity(0.2),
blurRadius: 20,
offset: const Offset(0, 10),
),
],
),
child: Icon(
Icons.mobile_friendly,
size: 50,
color: AppColor.primary,
),
),
const SizedBox(height: 16),
Text(
packageInfo?.appName ?? 'My App',
style: AppStyle.h4.copyWith(
color: AppColor.white,
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 8),
Container(
padding: const EdgeInsets.symmetric(
horizontal: 12,
vertical: 6,
),
decoration: BoxDecoration(
color: AppColor.white.withOpacity(0.2),
borderRadius: BorderRadius.circular(20),
),
child: Text(
'v${packageInfo?.version ?? '1.0.0'}',
style: AppStyle.sm.copyWith(
color: AppColor.white,
fontWeight: FontWeight.w600,
),
),
),
],
),
),
),
),
],
),
),
),
leading: IconButton(
icon: const Icon(Icons.arrow_back_ios, color: AppColor.white),
onPressed: () => context.router.back(),
),
);
}
Widget _buildContent() {
return SliverToBoxAdapter(
child: FadeTransition(
opacity: _fadeAnimation,
child: Container(
color: AppColor.background,
child: Column(
children: [_buildAppInfoSection(), const SizedBox(height: 40)],
),
),
),
);
}
Widget _buildAppInfoSection() {
return Container(
margin: const EdgeInsets.all(20),
padding: const EdgeInsets.all(24),
decoration: BoxDecoration(
color: AppColor.white,
borderRadius: BorderRadius.circular(20),
boxShadow: [
BoxShadow(
color: AppColor.primary.withOpacity(0.1),
blurRadius: 20,
offset: const Offset(0, 8),
),
],
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Container(
padding: const EdgeInsets.all(12),
decoration: BoxDecoration(
color: AppColor.primary.withOpacity(0.1),
borderRadius: BorderRadius.circular(12),
),
child: Icon(
Icons.info_outline,
color: AppColor.primary,
size: 24,
),
),
const SizedBox(width: 16),
Text(
'Informasi Aplikasi',
style: AppStyle.h6.copyWith(
fontWeight: FontWeight.bold,
color: AppColor.primary,
),
),
],
),
const SizedBox(height: 20),
_buildInfoRow('Nama Aplikasi', packageInfo?.appName ?? 'Loading...'),
_buildInfoRow('Versi', packageInfo?.version ?? 'Loading...'),
_buildInfoRow(
'Build Number',
packageInfo?.buildNumber ?? 'Loading...',
),
_buildInfoRow(
'Package Name',
packageInfo?.packageName ?? 'Loading...',
),
_buildInfoRow(
'Device',
deviceInfo.isEmpty ? 'Loading...' : deviceInfo,
),
],
),
);
}
Widget _buildInfoRow(String label, String value) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 8),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(
width: 120,
child: Text(
label,
style: AppStyle.md.copyWith(
fontWeight: FontWeight.w600,
color: AppColor.textSecondary,
),
),
),
const SizedBox(width: 16),
Expanded(
child: Text(
value,
style: AppStyle.md.copyWith(color: AppColor.textPrimary),
),
),
],
),
);
}
}
class _PatternPainter extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
final paint = Paint()
..color = AppColor.white.withOpacity(0.1)
..strokeWidth = 1
..style = PaintingStyle.stroke;
// Create geometric pattern
for (int i = 0; i < 20; i++) {
for (int j = 0; j < 20; j++) {
final x = (size.width / 20) * i;
final y = (size.height / 20) * j;
if ((i + j) % 3 == 0) {
canvas.drawCircle(Offset(x, y), 3, paint);
}
}
}
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) => false;
}

View File

@ -1,16 +1,46 @@
import 'dart:developer';
import 'package:flutter/material.dart';
import 'package:auto_route/auto_route.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_spinkit/flutter_spinkit.dart';
import '../../../application/report/inventory_report/inventory_report_bloc.dart';
import '../../../application/report/transaction_report/transaction_report_bloc.dart';
import '../../../common/extension/extension.dart';
import '../../../common/theme/theme.dart';
import '../../../common/utils/pdf_service.dart';
import '../../../common/utils/permission.dart';
import '../../../injection.dart';
import '../../components/appbar/appbar.dart';
import '../../components/field/date_range_picker_field.dart';
import '../../components/report/inventory_report.dart';
import '../../components/report/transaction_report.dart';
import '../../components/toast/flushbar.dart';
@RoutePage()
class DownloadReportPage extends StatefulWidget {
class DownloadReportPage extends StatefulWidget implements AutoRouteWrapper {
const DownloadReportPage({super.key});
@override
State<DownloadReportPage> createState() => _DownloadReportPageState();
@override
Widget wrappedRoute(BuildContext context) => MultiBlocProvider(
providers: [
BlocProvider(
create: (context) =>
getIt<InventoryReportBloc>()
..add(InventoryReportEvent.fetchedOutlet()),
),
BlocProvider(
create: (context) =>
getIt<TransactionReportBloc>()
..add(TransactionReportEvent.fetchedOutlet()),
),
],
child: this,
);
}
class _DownloadReportPageState extends State<DownloadReportPage>
@ -26,10 +56,10 @@ class _DownloadReportPageState extends State<DownloadReportPage>
DateTime? _transactionEndDate;
DateTime? _inventoryStartDate;
DateTime? _inventoryEndDate;
DateTime? _salesStartDate;
DateTime? _salesEndDate;
DateTime? _customerStartDate;
DateTime? _customerEndDate;
// DateTime? _salesStartDate;
// DateTime? _salesEndDate;
// DateTime? _customerStartDate;
// DateTime? _customerEndDate;
@override
void initState() {
@ -70,36 +100,6 @@ class _DownloadReportPageState extends State<DownloadReportPage>
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(
@ -128,7 +128,12 @@ class _DownloadReportPageState extends State<DownloadReportPage>
child: Column(
children: [
// Transaction Report Card
_ReportOptionCard(
BlocBuilder<
TransactionReportBloc,
TransactionReportState
>(
builder: (context, state) {
return _ReportOptionCard(
title: 'Transaction Report',
subtitle:
'Export all transaction data with detailed analytics',
@ -139,24 +144,67 @@ class _DownloadReportPageState extends State<DownloadReportPage>
],
startDate: _transactionStartDate,
endDate: _transactionEndDate,
isLoading: state.isFetching,
onDateRangeChanged: (start, end) {
setState(() {
_transactionStartDate = start;
_transactionEndDate = end;
});
},
onDownload: () => _downloadReport(
'Transaction Report',
_transactionStartDate,
_transactionEndDate,
if (start != null || end != null) {
context.read<TransactionReportBloc>().add(
TransactionReportEvent.fetchedTransaction(
start!,
end!,
),
);
}
},
onDownload: () async {
try {
final status = await PermessionHelper()
.checkPermission();
if (status) {
final pdfFile =
await TransactionReport.previewPdf(
searchDateFormatted:
"${_transactionStartDate?.toServerDate} - ${_transactionEndDate?.toServerDate}",
outlet: state.outlet,
categoryAnalyticData:
state.categoryAnalytic,
profitLossData:
state.profitLossAnalytic,
paymentMethodAnalyticData:
state.paymentMethodAnalytic,
productAnalyticData:
state.productAnalytic,
);
log("pdfFile: $pdfFile");
await HelperPdfService.openFile(pdfFile);
} else {
AppFlushbar.showError(
context,
'Storage permission is required to save PDF',
);
}
} catch (e) {
log("Error generating PDF: $e");
AppFlushbar.showError(
context,
'Failed to generate PDF: $e',
);
}
},
delay: 200,
);
},
),
const SizedBox(height: 20),
// Inventory Report Card
_ReportOptionCard(
BlocBuilder<InventoryReportBloc, InventoryReportState>(
builder: (context, state) {
return _ReportOptionCard(
title: 'Inventory Report',
subtitle:
'Export inventory and stock data with trends',
@ -167,68 +215,102 @@ class _DownloadReportPageState extends State<DownloadReportPage>
],
startDate: _inventoryStartDate,
endDate: _inventoryEndDate,
isLoading: state.isFetching,
onDateRangeChanged: (start, end) {
setState(() {
_inventoryStartDate = start;
_inventoryEndDate = end;
});
},
onDownload: () => _downloadReport(
'Inventory Report',
_inventoryStartDate,
_inventoryEndDate,
if (start != null || end != null) {
context.read<InventoryReportBloc>().add(
InventoryReportEvent.fetchedInventory(
start!,
end!,
),
);
}
},
onDownload: () async {
try {
final status = await PermessionHelper()
.checkPermission();
if (status) {
final pdfFile =
await InventoryReport.previewPdf(
searchDateFormatted:
"${_inventoryStartDate?.toServerDate} - ${_inventoryEndDate?.toServerDate}",
inventory: state.inventoryAnalytic,
outlet: state.outlet,
);
log("pdfFile: $pdfFile");
await HelperPdfService.openFile(pdfFile);
} else {
AppFlushbar.showError(
context,
'Storage permission is required to save PDF',
);
}
} catch (e) {
log("Error generating PDF: $e");
AppFlushbar.showError(
context,
'Failed to generate PDF: $e',
);
}
},
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,
),
// _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),
// 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,
),
// // 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,
// ),
],
),
),
@ -253,6 +335,7 @@ class _ReportOptionCard extends StatefulWidget {
final DateTime? endDate;
final Function(DateTime? startDate, DateTime? endDate) onDateRangeChanged;
final VoidCallback onDownload;
final bool isLoading;
final int delay;
const _ReportOptionCard({
@ -265,6 +348,7 @@ class _ReportOptionCard extends StatefulWidget {
required this.onDateRangeChanged,
required this.onDownload,
required this.delay,
required this.isLoading,
});
@override
@ -431,7 +515,25 @@ class _ReportOptionCardState extends State<_ReportOptionCard>
),
elevation: 0,
),
child: Row(
child: widget.isLoading
? Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SpinKitCircle(
color: widget.gradient.first,
size: 24,
),
const SizedBox(width: 8),
Text(
'Loading',
style: AppStyle.md.copyWith(
color: widget.gradient.first,
fontWeight: FontWeight.bold,
),
),
],
)
: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(

View File

@ -7,7 +7,7 @@ import '../../../../common/constant/app_constant.dart';
import '../../../../common/extension/extension.dart';
import '../../../../common/painter/wave_painter.dart';
import '../../../../common/theme/theme.dart';
import '../../../../domain/auth/auth.dart';
import '../../../../domain/user/user.dart';
import '../../../components/spacer/spacer.dart';
class HomeHeader extends StatefulWidget {

View File

@ -0,0 +1,106 @@
import 'package:auto_route/auto_route.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import '../../../../../application/user/change_password_form/change_password_form_bloc.dart';
import '../../../../../common/theme/theme.dart';
import '../../../../../injection.dart';
import '../../../../components/appbar/appbar.dart';
import '../../../../components/button/button.dart';
import '../../../../components/spacer/spacer.dart';
import '../../../../components/toast/flushbar.dart';
import 'widgets/current_password.dart';
import 'widgets/new_password.dart';
@RoutePage()
class ProfileChangePasswordPage extends StatefulWidget
implements AutoRouteWrapper {
const ProfileChangePasswordPage({super.key});
@override
State<ProfileChangePasswordPage> createState() =>
_ProfileChangePasswordPageState();
@override
Widget wrappedRoute(BuildContext context) =>
BlocProvider(create: (_) => getIt<ChangePasswordFormBloc>(), child: this);
}
class _ProfileChangePasswordPageState extends State<ProfileChangePasswordPage> {
@override
Widget build(BuildContext context) {
return BlocListener<ChangePasswordFormBloc, ChangePasswordFormState>(
listenWhen: (p, c) =>
p.failureOrChangePasswordOption != c.failureOrChangePasswordOption,
listener: (context, state) {
state.failureOrChangePasswordOption.fold(
() => null,
(either) => either.fold(
(f) => AppFlushbar.showUserFailureToast(context, f),
(user) {
if (context.mounted) {
AppFlushbar.showSuccess(context, 'Password changed');
Future.delayed(const Duration(seconds: 2), () {
context.router.back();
});
}
},
),
);
},
child: 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: 'Change Password'),
),
SliverToBoxAdapter(
child:
BlocBuilder<ChangePasswordFormBloc, ChangePasswordFormState>(
builder: (context, state) {
return Container(
margin: EdgeInsets.all(AppValue.margin),
padding: EdgeInsets.all(AppValue.padding),
decoration: BoxDecoration(
color: AppColor.white,
borderRadius: BorderRadius.circular(AppValue.radius),
),
child: Form(
autovalidateMode: state.showErrorMessages
? AutovalidateMode.always
: AutovalidateMode.disabled,
child: Column(
children: [
ChangePasswordCurrentPassword(),
SpaceHeight(16),
ChangePasswordNewPassword(),
SpaceHeight(24),
AppElevatedButton(
text: 'Save',
isLoading: state.isSubmitting,
onPressed: () {
context.read<ChangePasswordFormBloc>().add(
ChangePasswordFormEvent.submitted(),
);
},
),
],
),
),
);
},
),
),
],
),
),
);
}
}

View File

@ -0,0 +1,32 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:line_icons/line_icons.dart';
import '../../../../../../application/user/change_password_form/change_password_form_bloc.dart';
import '../../../../../components/field/field.dart';
class ChangePasswordCurrentPassword extends StatelessWidget {
const ChangePasswordCurrentPassword({super.key});
@override
Widget build(BuildContext context) {
return AppPasswordTextFormField(
title: 'Current Password',
prefixIcon: LineIcons.lock,
hintText: 'Please enter your current password',
onChanged: (value) => context.read<ChangePasswordFormBloc>().add(
ChangePasswordFormEvent.currentPasswordChanged(value),
),
validator: (value) {
if (context
.read<ChangePasswordFormBloc>()
.state
.currentPassword
.isEmpty) {
return 'Please enter your current password';
}
return null;
},
);
}
}

View File

@ -0,0 +1,33 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:line_icons/line_icons.dart';
import '../../../../../../application/user/change_password_form/change_password_form_bloc.dart';
import '../../../../../components/field/field.dart';
class ChangePasswordNewPassword extends StatelessWidget {
const ChangePasswordNewPassword({super.key});
@override
Widget build(BuildContext context) {
return AppPasswordTextFormField(
title: 'New Password',
prefixIcon: LineIcons.lock,
hintText: 'Please enter your new password',
onChanged: (value) => context.read<ChangePasswordFormBloc>().add(
ChangePasswordFormEvent.newPasswordChanged(value),
),
validator: (value) {
if (context.read<ChangePasswordFormBloc>().state.newPassword.isEmpty) {
return 'Please enter your new password';
}
if (context.read<ChangePasswordFormBloc>().state.newPassword ==
context.read<ChangePasswordFormBloc>().state.currentPassword) {
return 'New password cannot be same as current password';
}
return null;
},
);
}
}

View File

@ -0,0 +1,108 @@
import 'package:auto_route/auto_route.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import '../../../../../application/auth/auth_bloc.dart';
import '../../../../../application/user/user_edit_form/user_edit_form_bloc.dart';
import '../../../../../common/theme/theme.dart';
import '../../../../../domain/user/user.dart';
import '../../../../../injection.dart';
import '../../../../components/appbar/appbar.dart';
import '../../../../components/button/button.dart';
import '../../../../components/spacer/spacer.dart';
import '../../../../components/toast/flushbar.dart';
import 'widgets/name_field.dart';
@RoutePage()
class ProfileEditPage extends StatefulWidget implements AutoRouteWrapper {
final User user;
const ProfileEditPage({super.key, required this.user});
@override
State<ProfileEditPage> createState() => _ProfileEditPageState();
@override
Widget wrappedRoute(BuildContext context) =>
BlocProvider(create: (_) => getIt<UserEditFormBloc>(), child: this);
}
class _ProfileEditPageState extends State<ProfileEditPage> {
TextEditingController nameController = TextEditingController();
@override
void initState() {
super.initState();
nameController = TextEditingController(text: widget.user.name);
}
@override
Widget build(BuildContext context) {
return BlocListener<UserEditFormBloc, UserEditFormState>(
listenWhen: (p, c) => p.failureOrUserOption != c.failureOrUserOption,
listener: (context, state) {
state.failureOrUserOption.fold(
() => null,
(either) => either.fold(
(f) => AppFlushbar.showUserFailureToast(context, f),
(user) {
if (context.mounted) {
context.read<AuthBloc>().add(AuthEvent.fetchCurrentUser());
context.router.back();
}
},
),
);
},
child: 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: 'Profile Edit'),
),
SliverToBoxAdapter(
child: BlocBuilder<UserEditFormBloc, UserEditFormState>(
builder: (context, state) {
return Container(
margin: EdgeInsets.all(AppValue.margin),
padding: EdgeInsets.all(AppValue.padding),
decoration: BoxDecoration(
color: AppColor.white,
borderRadius: BorderRadius.circular(AppValue.radius),
),
child: Form(
autovalidateMode: state.showErrorMessages
? AutovalidateMode.always
: AutovalidateMode.disabled,
child: Column(
children: [
ProfileEditNameField(controller: nameController),
SpaceHeight(24),
AppElevatedButton(
text: 'Save',
isLoading: state.isSubmitting,
onPressed: () {
context.read<UserEditFormBloc>().add(
UserEditFormEvent.submitted(),
);
},
),
],
),
),
);
},
),
),
],
),
),
);
}
}

View File

@ -0,0 +1,33 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:line_icons/line_icons.dart';
import '../../../../../../application/user/user_edit_form/user_edit_form_bloc.dart';
import '../../../../../components/field/field.dart';
class ProfileEditNameField extends StatelessWidget {
final TextEditingController controller;
const ProfileEditNameField({super.key, required this.controller});
@override
Widget build(BuildContext context) {
return AppTextFormField(
title: 'Name',
prefixIcon: LineIcons.user,
hintText: 'Please enter your name',
controller: controller,
onChanged: (value) {
context.read<UserEditFormBloc>().add(
UserEditFormEvent.nameChanged(value),
);
},
validator: (value) {
if (context.read<UserEditFormBloc>().state.name.isEmpty) {
return 'Please enter your name';
}
return null;
},
);
}
}

View File

@ -98,7 +98,9 @@ class ProfilePage extends StatelessWidget implements AutoRouteWrapper {
),
),
ActionIconButton(
onTap: () {},
onTap: () => context.router.push(
ProfileEditRoute(user: state.user),
),
icon: LineIcons.userEdit,
),
],

View File

@ -1,9 +1,11 @@
import 'package:auto_route/auto_route.dart';
import 'package:flutter/material.dart';
import 'package:line_icons/line_icons.dart';
import '../../../../common/extension/extension.dart';
import '../../../../common/theme/theme.dart';
import '../../../../domain/auth/auth.dart';
import '../../../../domain/user/user.dart';
import '../../../router/app_router.gr.dart';
import 'divider.dart';
import 'profile_tile.dart';
@ -45,9 +47,7 @@ class ProfileAccountInfo extends StatelessWidget {
icon: LineIcons.envelope,
title: 'Email',
subtitle: user.email,
onTap: () {
// Edit email
},
showArrow: false,
),
ProfileDivider(),
@ -64,7 +64,14 @@ class ProfileAccountInfo extends StatelessWidget {
icon: LineIcons.userEdit,
title: 'Ubah Profil',
subtitle: 'Ubah profil kamu',
showArrow: false,
onTap: () => context.router.push(ProfileEditRoute(user: user)),
),
ProfileDivider(),
ProfileTile(
icon: LineIcons.lock,
title: 'Change Password',
subtitle: 'Change your password',
onTap: () => context.router.push(ProfileChangePasswordRoute()),
),
],
),

View File

@ -3,7 +3,6 @@ import 'package:flutter/material.dart';
import '../../../../common/theme/theme.dart';
import '../../../router/app_router.gr.dart';
import 'divider.dart';
import 'profile_tile.dart';
class ProfileAppSetting extends StatefulWidget {
@ -79,17 +78,6 @@ class _ProfileAppSettingState extends State<ProfileAppSetting> {
subtitle: 'English (US)',
onTap: () => context.router.push(LanguageRoute()),
),
ProfileDivider(),
ProfileTile(
icon: Icons.security_outlined,
title: 'Security & Privacy',
subtitle: 'Manage your security settings',
onTap: () {
// Navigate to security settings
},
),
],
),
);

View File

@ -4,7 +4,7 @@ import 'dart:math' as math;
import '../../../../common/extension/extension.dart';
import '../../../../common/painter/wave_painter.dart';
import '../../../../common/theme/theme.dart';
import '../../../../domain/auth/auth.dart';
import '../../../../domain/user/user.dart';
import '../../../components/spacer/spacer.dart';
class ProfileHeader extends StatefulWidget {

View File

@ -1,6 +1,8 @@
import 'package:auto_route/auto_route.dart';
import 'package:flutter/material.dart';
import '../../../../common/theme/theme.dart';
import '../../../router/app_router.gr.dart';
import 'divider.dart';
import 'profile_tile.dart';
@ -41,31 +43,26 @@ class ProfileSupport extends StatelessWidget {
icon: Icons.help_outline,
title: 'Help Center',
subtitle: 'Get help and support',
onTap: () {
// Navigate to help center
},
onTap: () => context.router.push(ComingSoonRoute()),
),
ProfileDivider(),
ProfileTile(
icon: Icons.feedback_outlined,
title: 'Send Feedback',
subtitle: 'Help us improve the app',
onTap: () {
// Open feedback form
},
),
// ProfileDivider(),
// ProfileTile(
// icon: Icons.feedback_outlined,
// title: 'Send Feedback',
// subtitle: 'Help us improve the app',
// onTap: () {
// // Open feedback form
// },
// ),
ProfileDivider(),
ProfileTile(
icon: Icons.info_outline,
title: 'About',
subtitle: 'App version and information',
onTap: () {
// Show about dialog
},
onTap: () => context.router.push(AboutAppRoute()),
),
],
),

View File

@ -59,6 +59,13 @@ class AppRouter extends RootStackRouter {
// Download Report
AutoRoute(page: DownloadReportRoute.page),
// Profile
AutoRoute(page: ProfileEditRoute.page),
AutoRoute(page: ProfileChangePasswordRoute.page),
// About App
AutoRoute(page: AboutAppRoute.page),
// Error
AutoRoute(page: ErrorRoute.page),

View File

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

View File

@ -7,9 +7,17 @@
#include "generated_plugin_registrant.h"
#include <file_selector_linux/file_selector_plugin.h>
#include <open_file_linux/open_file_linux_plugin.h>
#include <url_launcher_linux/url_launcher_plugin.h>
void fl_register_plugins(FlPluginRegistry* registry) {
g_autoptr(FlPluginRegistrar) file_selector_linux_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "FileSelectorPlugin");
file_selector_plugin_register_with_registrar(file_selector_linux_registrar);
g_autoptr(FlPluginRegistrar) open_file_linux_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "OpenFileLinuxPlugin");
open_file_linux_plugin_register_with_registrar(open_file_linux_registrar);
g_autoptr(FlPluginRegistrar) url_launcher_linux_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "UrlLauncherPlugin");
url_launcher_plugin_register_with_registrar(url_launcher_linux_registrar);
}

View File

@ -4,6 +4,8 @@
list(APPEND FLUTTER_PLUGIN_LIST
file_selector_linux
open_file_linux
url_launcher_linux
)
list(APPEND FLUTTER_FFI_PLUGIN_LIST

View File

@ -6,17 +6,23 @@ import FlutterMacOS
import Foundation
import connectivity_plus
import device_info_plus
import file_selector_macos
import open_file_mac
import package_info_plus
import path_provider_foundation
import shared_preferences_foundation
import sqflite_darwin
import url_launcher_macos
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
ConnectivityPlusPlugin.register(with: registry.registrar(forPlugin: "ConnectivityPlusPlugin"))
DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin"))
FileSelectorPlugin.register(with: registry.registrar(forPlugin: "FileSelectorPlugin"))
OpenFilePlugin.register(with: registry.registrar(forPlugin: "OpenFilePlugin"))
FPPPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FPPPackageInfoPlusPlugin"))
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin"))
UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin"))
}

View File

@ -81,6 +81,22 @@ packages:
url: "https://pub.dev"
source: hosted
version: "8.0.4"
barcode:
dependency: transitive
description:
name: barcode
sha256: "7b6729c37e3b7f34233e2318d866e8c48ddb46c1f7ad01ff7bb2a8de1da2b9f4"
url: "https://pub.dev"
source: hosted
version: "2.2.9"
bidi:
dependency: transitive
description:
name: bidi
sha256: "77f475165e94b261745cf1032c751e2032b8ed92ccb2bf5716036db79320637d"
url: "https://pub.dev"
source: hosted
version: "2.0.13"
bloc:
dependency: transitive
description:
@ -337,6 +353,22 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.7.11"
device_info_plus:
dependency: "direct main"
description:
name: device_info_plus
sha256: "98f28b42168cc509abc92f88518882fd58061ea372d7999aecc424345c7bff6a"
url: "https://pub.dev"
source: hosted
version: "11.5.0"
device_info_plus_platform_interface:
dependency: transitive
description:
name: device_info_plus_platform_interface
sha256: e1ea89119e34903dca74b883d0dd78eb762814f97fb6c76f35e9ff74d261a18f
url: "https://pub.dev"
source: hosted
version: "7.0.3"
dio:
dependency: "direct main"
description:
@ -853,6 +885,70 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.1.0"
open_file:
dependency: "direct main"
description:
name: open_file
sha256: d17e2bddf5b278cb2ae18393d0496aa4f162142ba97d1a9e0c30d476adf99c0e
url: "https://pub.dev"
source: hosted
version: "3.5.10"
open_file_android:
dependency: transitive
description:
name: open_file_android
sha256: "58141fcaece2f453a9684509a7275f231ac0e3d6ceb9a5e6de310a7dff9084aa"
url: "https://pub.dev"
source: hosted
version: "1.0.6"
open_file_ios:
dependency: transitive
description:
name: open_file_ios
sha256: "02996f01e5f6863832068e97f8f3a5ef9b613516db6897f373b43b79849e4d07"
url: "https://pub.dev"
source: hosted
version: "1.0.3"
open_file_linux:
dependency: transitive
description:
name: open_file_linux
sha256: d189f799eecbb139c97f8bc7d303f9e720954fa4e0fa1b0b7294767e5f2d7550
url: "https://pub.dev"
source: hosted
version: "0.0.5"
open_file_mac:
dependency: transitive
description:
name: open_file_mac
sha256: "1440b1e37ceb0642208cfeb2c659c6cda27b25187a90635c9d1acb7d0584d324"
url: "https://pub.dev"
source: hosted
version: "1.0.3"
open_file_platform_interface:
dependency: transitive
description:
name: open_file_platform_interface
sha256: "101b424ca359632699a7e1213e83d025722ab668b9fd1412338221bf9b0e5757"
url: "https://pub.dev"
source: hosted
version: "1.0.3"
open_file_web:
dependency: transitive
description:
name: open_file_web
sha256: e3dbc9584856283dcb30aef5720558b90f88036360bd078e494ab80a80130c4f
url: "https://pub.dev"
source: hosted
version: "0.0.4"
open_file_windows:
dependency: transitive
description:
name: open_file_windows
sha256: d26c31ddf935a94a1a3aa43a23f4fff8a5ff4eea395fe7a8cb819cf55431c875
url: "https://pub.dev"
source: hosted
version: "0.0.3"
package_config:
dependency: transitive
description:
@ -941,6 +1037,62 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.3.0"
pdf:
dependency: "direct main"
description:
name: pdf
sha256: "28eacad99bffcce2e05bba24e50153890ad0255294f4dd78a17075a2ba5c8416"
url: "https://pub.dev"
source: hosted
version: "3.11.3"
permission_handler:
dependency: "direct main"
description:
name: permission_handler
sha256: bc917da36261b00137bbc8896bf1482169cd76f866282368948f032c8c1caae1
url: "https://pub.dev"
source: hosted
version: "12.0.1"
permission_handler_android:
dependency: transitive
description:
name: permission_handler_android
sha256: "1e3bc410ca1bf84662104b100eb126e066cb55791b7451307f9708d4007350e6"
url: "https://pub.dev"
source: hosted
version: "13.0.1"
permission_handler_apple:
dependency: transitive
description:
name: permission_handler_apple
sha256: f000131e755c54cf4d84a5d8bd6e4149e262cc31c5a8b1d698de1ac85fa41023
url: "https://pub.dev"
source: hosted
version: "9.4.7"
permission_handler_html:
dependency: transitive
description:
name: permission_handler_html
sha256: "38f000e83355abb3392140f6bc3030660cfaef189e1f87824facb76300b4ff24"
url: "https://pub.dev"
source: hosted
version: "0.1.3+5"
permission_handler_platform_interface:
dependency: transitive
description:
name: permission_handler_platform_interface
sha256: eb99b295153abce5d683cac8c02e22faab63e50679b937fa1bf67d58bb282878
url: "https://pub.dev"
source: hosted
version: "4.3.0"
permission_handler_windows:
dependency: transitive
description:
name: permission_handler_windows
sha256: "1a790728016f79a41216d88672dbc5df30e686e811ad4e698bfc51f76ad91f1e"
url: "https://pub.dev"
source: hosted
version: "0.2.1"
petitparser:
dependency: transitive
description:
@ -1005,6 +1157,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.5.0"
qr:
dependency: transitive
description:
name: qr
sha256: "5a1d2586170e172b8a8c8470bbbffd5eb0cd38a66c0d77155ea138d3af3a4445"
url: "https://pub.dev"
source: hosted
version: "3.0.2"
recase:
dependency: transitive
description:
@ -1290,6 +1450,70 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.4.0"
url_launcher:
dependency: "direct main"
description:
name: url_launcher
sha256: f6a7e5c4835bb4e3026a04793a4199ca2d14c739ec378fdfe23fc8075d0439f8
url: "https://pub.dev"
source: hosted
version: "6.3.2"
url_launcher_android:
dependency: transitive
description:
name: url_launcher_android
sha256: "0aedad096a85b49df2e4725fa32118f9fa580f3b14af7a2d2221896a02cd5656"
url: "https://pub.dev"
source: hosted
version: "6.3.17"
url_launcher_ios:
dependency: transitive
description:
name: url_launcher_ios
sha256: d80b3f567a617cb923546034cc94bfe44eb15f989fe670b37f26abdb9d939cb7
url: "https://pub.dev"
source: hosted
version: "6.3.4"
url_launcher_linux:
dependency: transitive
description:
name: url_launcher_linux
sha256: "4e9ba368772369e3e08f231d2301b4ef72b9ff87c31192ef471b380ef29a4935"
url: "https://pub.dev"
source: hosted
version: "3.2.1"
url_launcher_macos:
dependency: transitive
description:
name: url_launcher_macos
sha256: c043a77d6600ac9c38300567f33ef12b0ef4f4783a2c1f00231d2b1941fea13f
url: "https://pub.dev"
source: hosted
version: "3.2.3"
url_launcher_platform_interface:
dependency: transitive
description:
name: url_launcher_platform_interface
sha256: "552f8a1e663569be95a8190206a38187b531910283c3e982193e4f2733f01029"
url: "https://pub.dev"
source: hosted
version: "2.3.2"
url_launcher_web:
dependency: transitive
description:
name: url_launcher_web
sha256: "4bd2b7b4dc4d4d0b94e5babfffbca8eac1a126c7f3d6ecbc1a11013faa3abba2"
url: "https://pub.dev"
source: hosted
version: "2.4.1"
url_launcher_windows:
dependency: transitive
description:
name: url_launcher_windows
sha256: "3284b6d2ac454cf34f114e1d3319866fdd1e19cdc329999057e44ffe936cfa77"
url: "https://pub.dev"
source: hosted
version: "3.1.4"
uuid:
dependency: transitive
description:
@ -1378,6 +1602,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "5.14.0"
win32_registry:
dependency: transitive
description:
name: win32_registry
sha256: "6f1b564492d0147b330dd794fee8f512cec4977957f310f9951b5f9d83618dae"
url: "https://pub.dev"
source: hosted
version: "2.1.0"
xdg_directories:
dependency: transitive
description:

View File

@ -43,6 +43,11 @@ dependencies:
shimmer: ^3.0.0
cached_network_image: ^3.4.1
syncfusion_flutter_datepicker: ^30.2.5
url_launcher: ^6.3.2
device_info_plus: ^11.5.0
pdf: ^3.11.3
open_file: ^3.5.10
permission_handler: ^12.0.1
dev_dependencies:
flutter_test:

View File

@ -8,10 +8,16 @@
#include <connectivity_plus/connectivity_plus_windows_plugin.h>
#include <file_selector_windows/file_selector_windows.h>
#include <permission_handler_windows/permission_handler_windows_plugin.h>
#include <url_launcher_windows/url_launcher_windows.h>
void RegisterPlugins(flutter::PluginRegistry* registry) {
ConnectivityPlusWindowsPluginRegisterWithRegistrar(
registry->GetRegistrarForPlugin("ConnectivityPlusWindowsPlugin"));
FileSelectorWindowsRegisterWithRegistrar(
registry->GetRegistrarForPlugin("FileSelectorWindows"));
PermissionHandlerWindowsPluginRegisterWithRegistrar(
registry->GetRegistrarForPlugin("PermissionHandlerWindowsPlugin"));
UrlLauncherWindowsRegisterWithRegistrar(
registry->GetRegistrarForPlugin("UrlLauncherWindows"));
}

View File

@ -5,6 +5,8 @@
list(APPEND FLUTTER_PLUGIN_LIST
connectivity_plus
file_selector_windows
permission_handler_windows
url_launcher_windows
)
list(APPEND FLUTTER_FFI_PLUGIN_LIST