feat: outlet information page

This commit is contained in:
efrilm
2025-08-19 11:08:33 +07:00
parent de11c1243c
commit 590bb3329c
21 changed files with 2652 additions and 104 deletions
@@ -0,0 +1,39 @@
import 'dart:developer';
import 'package:data_channel/data_channel.dart';
import 'package:injectable/injectable.dart';
import '../../../common/api/api_client.dart';
import '../../../common/api/api_failure.dart';
import '../../../common/function/app_function.dart';
import '../../../common/url/api_path.dart';
import '../../../domain/outlet/outlet.dart';
import '../outlet_dtos.dart';
@injectable
class OutletRemoteDataProvider {
final ApiClient _apiClient;
final String _logName = 'OutletRemoteDataProvider';
OutletRemoteDataProvider(this._apiClient);
Future<DC<OutletFailure, OutletDto>> fetchById({required outletId}) async {
try {
final response = await _apiClient.get(
'${ApiPath.outlet}/detail/$outletId',
headers: getAuthorizationHeader(),
);
if (response.data['data'] == null) {
return DC.error(OutletFailure.empty());
}
final dto = OutletDto.fromJson(response.data['data']);
return DC.data(dto);
} on ApiFailure catch (e, s) {
log('fetchOutletByIdError', name: _logName, error: e, stackTrace: s);
return DC.error(OutletFailure.serverError(e));
}
}
}
@@ -0,0 +1,44 @@
part of '../outlet_dtos.dart';
@freezed
class OutletDto with _$OutletDto {
const OutletDto._();
const factory OutletDto({
@JsonKey(name: 'id') String? id,
@JsonKey(name: 'organization_id') String? organizationId,
@JsonKey(name: 'name') String? name,
@JsonKey(name: 'address') String? address,
@JsonKey(name: 'phone_number') String? phoneNumber,
@JsonKey(name: 'business_type') String? businessType,
@JsonKey(name: 'currency') String? currency,
@JsonKey(name: 'tax_rate') int? taxRate,
@JsonKey(name: 'is_active') bool? isActive,
@JsonKey(name: 'created_at') String? createdAt,
@JsonKey(name: 'updated_at') String? updatedAt,
}) = _OutletDto;
factory OutletDto.fromJson(Map<String, dynamic> json) =>
_$OutletDtoFromJson(json);
/// Mapper ke domain
Outlet toDomain() {
return Outlet(
id: id ?? '',
organizationId: organizationId ?? '',
name: name ?? '',
address: address ?? '',
phoneNumber: phoneNumber ?? '',
businessType: businessType ?? '',
currency: currency ?? '',
taxRate: taxRate ?? 0,
isActive: isActive ?? false,
createdAt: createdAt != null
? DateTime.tryParse(createdAt!) ?? DateTime(1970)
: DateTime(1970),
updatedAt: updatedAt != null
? DateTime.tryParse(updatedAt!) ?? DateTime(1970)
: DateTime(1970),
);
}
}
@@ -0,0 +1,8 @@
import 'package:freezed_annotation/freezed_annotation.dart';
import '../../domain/outlet/outlet.dart';
part 'outlet_dtos.freezed.dart';
part 'outlet_dtos.g.dart';
part 'dto/outlet_dto.dart';
@@ -0,0 +1,431 @@
// coverage:ignore-file
// GENERATED CODE - DO NOT MODIFY BY HAND
// ignore_for_file: type=lint
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark
part of 'outlet_dtos.dart';
// **************************************************************************
// FreezedGenerator
// **************************************************************************
T _$identity<T>(T value) => value;
final _privateConstructorUsedError = UnsupportedError(
'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models',
);
OutletDto _$OutletDtoFromJson(Map<String, dynamic> json) {
return _OutletDto.fromJson(json);
}
/// @nodoc
mixin _$OutletDto {
@JsonKey(name: 'id')
String? get id => throw _privateConstructorUsedError;
@JsonKey(name: 'organization_id')
String? get organizationId => throw _privateConstructorUsedError;
@JsonKey(name: 'name')
String? get name => throw _privateConstructorUsedError;
@JsonKey(name: 'address')
String? get address => throw _privateConstructorUsedError;
@JsonKey(name: 'phone_number')
String? get phoneNumber => throw _privateConstructorUsedError;
@JsonKey(name: 'business_type')
String? get businessType => throw _privateConstructorUsedError;
@JsonKey(name: 'currency')
String? get currency => throw _privateConstructorUsedError;
@JsonKey(name: 'tax_rate')
int? get taxRate => throw _privateConstructorUsedError;
@JsonKey(name: 'is_active')
bool? get isActive => throw _privateConstructorUsedError;
@JsonKey(name: 'created_at')
String? get createdAt => throw _privateConstructorUsedError;
@JsonKey(name: 'updated_at')
String? get updatedAt => throw _privateConstructorUsedError;
/// Serializes this OutletDto to a JSON map.
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
/// Create a copy of OutletDto
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
$OutletDtoCopyWith<OutletDto> get copyWith =>
throw _privateConstructorUsedError;
}
/// @nodoc
abstract class $OutletDtoCopyWith<$Res> {
factory $OutletDtoCopyWith(OutletDto value, $Res Function(OutletDto) then) =
_$OutletDtoCopyWithImpl<$Res, OutletDto>;
@useResult
$Res call({
@JsonKey(name: 'id') String? id,
@JsonKey(name: 'organization_id') String? organizationId,
@JsonKey(name: 'name') String? name,
@JsonKey(name: 'address') String? address,
@JsonKey(name: 'phone_number') String? phoneNumber,
@JsonKey(name: 'business_type') String? businessType,
@JsonKey(name: 'currency') String? currency,
@JsonKey(name: 'tax_rate') int? taxRate,
@JsonKey(name: 'is_active') bool? isActive,
@JsonKey(name: 'created_at') String? createdAt,
@JsonKey(name: 'updated_at') String? updatedAt,
});
}
/// @nodoc
class _$OutletDtoCopyWithImpl<$Res, $Val extends OutletDto>
implements $OutletDtoCopyWith<$Res> {
_$OutletDtoCopyWithImpl(this._value, this._then);
// ignore: unused_field
final $Val _value;
// ignore: unused_field
final $Res Function($Val) _then;
/// Create a copy of OutletDto
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({
Object? id = freezed,
Object? organizationId = freezed,
Object? name = freezed,
Object? address = freezed,
Object? phoneNumber = freezed,
Object? businessType = freezed,
Object? currency = freezed,
Object? taxRate = freezed,
Object? isActive = freezed,
Object? createdAt = freezed,
Object? updatedAt = freezed,
}) {
return _then(
_value.copyWith(
id: freezed == id
? _value.id
: id // ignore: cast_nullable_to_non_nullable
as String?,
organizationId: freezed == organizationId
? _value.organizationId
: organizationId // ignore: cast_nullable_to_non_nullable
as String?,
name: freezed == name
? _value.name
: name // ignore: cast_nullable_to_non_nullable
as String?,
address: freezed == address
? _value.address
: address // ignore: cast_nullable_to_non_nullable
as String?,
phoneNumber: freezed == phoneNumber
? _value.phoneNumber
: phoneNumber // ignore: cast_nullable_to_non_nullable
as String?,
businessType: freezed == businessType
? _value.businessType
: businessType // ignore: cast_nullable_to_non_nullable
as String?,
currency: freezed == currency
? _value.currency
: currency // ignore: cast_nullable_to_non_nullable
as String?,
taxRate: freezed == taxRate
? _value.taxRate
: taxRate // ignore: cast_nullable_to_non_nullable
as int?,
isActive: freezed == isActive
? _value.isActive
: isActive // ignore: cast_nullable_to_non_nullable
as bool?,
createdAt: freezed == createdAt
? _value.createdAt
: createdAt // ignore: cast_nullable_to_non_nullable
as String?,
updatedAt: freezed == updatedAt
? _value.updatedAt
: updatedAt // ignore: cast_nullable_to_non_nullable
as String?,
)
as $Val,
);
}
}
/// @nodoc
abstract class _$$OutletDtoImplCopyWith<$Res>
implements $OutletDtoCopyWith<$Res> {
factory _$$OutletDtoImplCopyWith(
_$OutletDtoImpl value,
$Res Function(_$OutletDtoImpl) then,
) = __$$OutletDtoImplCopyWithImpl<$Res>;
@override
@useResult
$Res call({
@JsonKey(name: 'id') String? id,
@JsonKey(name: 'organization_id') String? organizationId,
@JsonKey(name: 'name') String? name,
@JsonKey(name: 'address') String? address,
@JsonKey(name: 'phone_number') String? phoneNumber,
@JsonKey(name: 'business_type') String? businessType,
@JsonKey(name: 'currency') String? currency,
@JsonKey(name: 'tax_rate') int? taxRate,
@JsonKey(name: 'is_active') bool? isActive,
@JsonKey(name: 'created_at') String? createdAt,
@JsonKey(name: 'updated_at') String? updatedAt,
});
}
/// @nodoc
class __$$OutletDtoImplCopyWithImpl<$Res>
extends _$OutletDtoCopyWithImpl<$Res, _$OutletDtoImpl>
implements _$$OutletDtoImplCopyWith<$Res> {
__$$OutletDtoImplCopyWithImpl(
_$OutletDtoImpl _value,
$Res Function(_$OutletDtoImpl) _then,
) : super(_value, _then);
/// Create a copy of OutletDto
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({
Object? id = freezed,
Object? organizationId = freezed,
Object? name = freezed,
Object? address = freezed,
Object? phoneNumber = freezed,
Object? businessType = freezed,
Object? currency = freezed,
Object? taxRate = freezed,
Object? isActive = freezed,
Object? createdAt = freezed,
Object? updatedAt = freezed,
}) {
return _then(
_$OutletDtoImpl(
id: freezed == id
? _value.id
: id // ignore: cast_nullable_to_non_nullable
as String?,
organizationId: freezed == organizationId
? _value.organizationId
: organizationId // ignore: cast_nullable_to_non_nullable
as String?,
name: freezed == name
? _value.name
: name // ignore: cast_nullable_to_non_nullable
as String?,
address: freezed == address
? _value.address
: address // ignore: cast_nullable_to_non_nullable
as String?,
phoneNumber: freezed == phoneNumber
? _value.phoneNumber
: phoneNumber // ignore: cast_nullable_to_non_nullable
as String?,
businessType: freezed == businessType
? _value.businessType
: businessType // ignore: cast_nullable_to_non_nullable
as String?,
currency: freezed == currency
? _value.currency
: currency // ignore: cast_nullable_to_non_nullable
as String?,
taxRate: freezed == taxRate
? _value.taxRate
: taxRate // ignore: cast_nullable_to_non_nullable
as int?,
isActive: freezed == isActive
? _value.isActive
: isActive // ignore: cast_nullable_to_non_nullable
as bool?,
createdAt: freezed == createdAt
? _value.createdAt
: createdAt // ignore: cast_nullable_to_non_nullable
as String?,
updatedAt: freezed == updatedAt
? _value.updatedAt
: updatedAt // ignore: cast_nullable_to_non_nullable
as String?,
),
);
}
}
/// @nodoc
@JsonSerializable()
class _$OutletDtoImpl extends _OutletDto {
const _$OutletDtoImpl({
@JsonKey(name: 'id') this.id,
@JsonKey(name: 'organization_id') this.organizationId,
@JsonKey(name: 'name') this.name,
@JsonKey(name: 'address') this.address,
@JsonKey(name: 'phone_number') this.phoneNumber,
@JsonKey(name: 'business_type') this.businessType,
@JsonKey(name: 'currency') this.currency,
@JsonKey(name: 'tax_rate') this.taxRate,
@JsonKey(name: 'is_active') this.isActive,
@JsonKey(name: 'created_at') this.createdAt,
@JsonKey(name: 'updated_at') this.updatedAt,
}) : super._();
factory _$OutletDtoImpl.fromJson(Map<String, dynamic> json) =>
_$$OutletDtoImplFromJson(json);
@override
@JsonKey(name: 'id')
final String? id;
@override
@JsonKey(name: 'organization_id')
final String? organizationId;
@override
@JsonKey(name: 'name')
final String? name;
@override
@JsonKey(name: 'address')
final String? address;
@override
@JsonKey(name: 'phone_number')
final String? phoneNumber;
@override
@JsonKey(name: 'business_type')
final String? businessType;
@override
@JsonKey(name: 'currency')
final String? currency;
@override
@JsonKey(name: 'tax_rate')
final int? taxRate;
@override
@JsonKey(name: 'is_active')
final bool? isActive;
@override
@JsonKey(name: 'created_at')
final String? createdAt;
@override
@JsonKey(name: 'updated_at')
final String? updatedAt;
@override
String toString() {
return 'OutletDto(id: $id, organizationId: $organizationId, name: $name, address: $address, phoneNumber: $phoneNumber, businessType: $businessType, currency: $currency, taxRate: $taxRate, isActive: $isActive, createdAt: $createdAt, updatedAt: $updatedAt)';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType &&
other is _$OutletDtoImpl &&
(identical(other.id, id) || other.id == id) &&
(identical(other.organizationId, organizationId) ||
other.organizationId == organizationId) &&
(identical(other.name, name) || other.name == name) &&
(identical(other.address, address) || other.address == address) &&
(identical(other.phoneNumber, phoneNumber) ||
other.phoneNumber == phoneNumber) &&
(identical(other.businessType, businessType) ||
other.businessType == businessType) &&
(identical(other.currency, currency) ||
other.currency == currency) &&
(identical(other.taxRate, taxRate) || other.taxRate == taxRate) &&
(identical(other.isActive, isActive) ||
other.isActive == isActive) &&
(identical(other.createdAt, createdAt) ||
other.createdAt == createdAt) &&
(identical(other.updatedAt, updatedAt) ||
other.updatedAt == updatedAt));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(
runtimeType,
id,
organizationId,
name,
address,
phoneNumber,
businessType,
currency,
taxRate,
isActive,
createdAt,
updatedAt,
);
/// Create a copy of OutletDto
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@override
@pragma('vm:prefer-inline')
_$$OutletDtoImplCopyWith<_$OutletDtoImpl> get copyWith =>
__$$OutletDtoImplCopyWithImpl<_$OutletDtoImpl>(this, _$identity);
@override
Map<String, dynamic> toJson() {
return _$$OutletDtoImplToJson(this);
}
}
abstract class _OutletDto extends OutletDto {
const factory _OutletDto({
@JsonKey(name: 'id') final String? id,
@JsonKey(name: 'organization_id') final String? organizationId,
@JsonKey(name: 'name') final String? name,
@JsonKey(name: 'address') final String? address,
@JsonKey(name: 'phone_number') final String? phoneNumber,
@JsonKey(name: 'business_type') final String? businessType,
@JsonKey(name: 'currency') final String? currency,
@JsonKey(name: 'tax_rate') final int? taxRate,
@JsonKey(name: 'is_active') final bool? isActive,
@JsonKey(name: 'created_at') final String? createdAt,
@JsonKey(name: 'updated_at') final String? updatedAt,
}) = _$OutletDtoImpl;
const _OutletDto._() : super._();
factory _OutletDto.fromJson(Map<String, dynamic> json) =
_$OutletDtoImpl.fromJson;
@override
@JsonKey(name: 'id')
String? get id;
@override
@JsonKey(name: 'organization_id')
String? get organizationId;
@override
@JsonKey(name: 'name')
String? get name;
@override
@JsonKey(name: 'address')
String? get address;
@override
@JsonKey(name: 'phone_number')
String? get phoneNumber;
@override
@JsonKey(name: 'business_type')
String? get businessType;
@override
@JsonKey(name: 'currency')
String? get currency;
@override
@JsonKey(name: 'tax_rate')
int? get taxRate;
@override
@JsonKey(name: 'is_active')
bool? get isActive;
@override
@JsonKey(name: 'created_at')
String? get createdAt;
@override
@JsonKey(name: 'updated_at')
String? get updatedAt;
/// Create a copy of OutletDto
/// with the given fields replaced by the non-null parameter values.
@override
@JsonKey(includeFromJson: false, includeToJson: false)
_$$OutletDtoImplCopyWith<_$OutletDtoImpl> get copyWith =>
throw _privateConstructorUsedError;
}
@@ -0,0 +1,37 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'outlet_dtos.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
_$OutletDtoImpl _$$OutletDtoImplFromJson(Map<String, dynamic> json) =>
_$OutletDtoImpl(
id: json['id'] as String?,
organizationId: json['organization_id'] as String?,
name: json['name'] as String?,
address: json['address'] as String?,
phoneNumber: json['phone_number'] as String?,
businessType: json['business_type'] as String?,
currency: json['currency'] as String?,
taxRate: (json['tax_rate'] as num?)?.toInt(),
isActive: json['is_active'] as bool?,
createdAt: json['created_at'] as String?,
updatedAt: json['updated_at'] as String?,
);
Map<String, dynamic> _$$OutletDtoImplToJson(_$OutletDtoImpl instance) =>
<String, dynamic>{
'id': instance.id,
'organization_id': instance.organizationId,
'name': instance.name,
'address': instance.address,
'phone_number': instance.phoneNumber,
'business_type': instance.businessType,
'currency': instance.currency,
'tax_rate': instance.taxRate,
'is_active': instance.isActive,
'created_at': instance.createdAt,
'updated_at': instance.updatedAt,
};
@@ -0,0 +1,36 @@
import 'dart:developer';
import 'package:dartz/dartz.dart';
import 'package:injectable/injectable.dart';
import '../../../domain/outlet/outlet.dart';
import '../../auth/datasources/local_data_provider.dart';
import '../datasource/remote_data_provider.dart';
@Injectable(as: IOutletRepository)
class OutletRepository implements IOutletRepository {
final OutletRemoteDataProvider _dataProvider;
final AuthLocalDataProvider _authLocalDataProvider;
final String _logName = 'OutletRepository';
OutletRepository(this._dataProvider, this._authLocalDataProvider);
@override
Future<Either<OutletFailure, Outlet>> currentOutlet() async {
try {
final authData = await _authLocalDataProvider.currentUser();
final result = await _dataProvider.fetchById(outletId: authData.outletId);
if (result.hasError) {
return left(result.error!);
}
final auth = result.data!.toDomain();
return right(auth);
} catch (e, s) {
log('currentOutletError', name: _logName, error: e, stackTrace: s);
return left(const OutletFailure.unexpectedError());
}
}
}