feat: payment method report
This commit is contained in:
+15
-8
@@ -1,6 +1,6 @@
|
||||
import 'package:enaklo_pos/data/datasources/analytic_remote_datasource.dart';
|
||||
import 'package:enaklo_pos/data/models/response/payment_method_analytic_response_model.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:enaklo_pos/data/datasources/order_remote_datasource.dart';
|
||||
import 'package:enaklo_pos/data/models/response/payment_method_response_model.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
part 'payment_method_report_event.dart';
|
||||
@@ -9,16 +9,23 @@ part 'payment_method_report_bloc.freezed.dart';
|
||||
|
||||
class PaymentMethodReportBloc
|
||||
extends Bloc<PaymentMethodReportEvent, PaymentMethodReportState> {
|
||||
final OrderRemoteDatasource datasource;
|
||||
final AnalyticRemoteDatasource datasource;
|
||||
PaymentMethodReportBloc(this.datasource) : super(const _Initial()) {
|
||||
on<_GetPaymentMethodReport>((event, emit) async {
|
||||
emit(const _Loading());
|
||||
final result = await datasource.getPaymentMethodByRangeDate(
|
||||
event.startDate,
|
||||
event.endDate,
|
||||
final result = await datasource.getPaymentMethod(
|
||||
dateFrom: event.startDate,
|
||||
dateTo: event.endDate,
|
||||
);
|
||||
|
||||
result.fold((l) => emit(_Error(l)), (r) => emit(_Loaded(r.data!)));
|
||||
result.fold(
|
||||
(l) => emit(_Error(l)),
|
||||
(r) => emit(
|
||||
_Loaded(
|
||||
r.data,
|
||||
),
|
||||
),
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+44
-40
@@ -16,22 +16,24 @@ final _privateConstructorUsedError = UnsupportedError(
|
||||
|
||||
/// @nodoc
|
||||
mixin _$PaymentMethodReportEvent {
|
||||
String get startDate => throw _privateConstructorUsedError;
|
||||
String get endDate => throw _privateConstructorUsedError;
|
||||
DateTime get startDate => throw _privateConstructorUsedError;
|
||||
DateTime get endDate => throw _privateConstructorUsedError;
|
||||
@optionalTypeArgs
|
||||
TResult when<TResult extends Object?>({
|
||||
required TResult Function(String startDate, String endDate)
|
||||
required TResult Function(DateTime startDate, DateTime endDate)
|
||||
getPaymentMethodReport,
|
||||
}) =>
|
||||
throw _privateConstructorUsedError;
|
||||
@optionalTypeArgs
|
||||
TResult? whenOrNull<TResult extends Object?>({
|
||||
TResult? Function(String startDate, String endDate)? getPaymentMethodReport,
|
||||
TResult? Function(DateTime startDate, DateTime endDate)?
|
||||
getPaymentMethodReport,
|
||||
}) =>
|
||||
throw _privateConstructorUsedError;
|
||||
@optionalTypeArgs
|
||||
TResult maybeWhen<TResult extends Object?>({
|
||||
TResult Function(String startDate, String endDate)? getPaymentMethodReport,
|
||||
TResult Function(DateTime startDate, DateTime endDate)?
|
||||
getPaymentMethodReport,
|
||||
required TResult orElse(),
|
||||
}) =>
|
||||
throw _privateConstructorUsedError;
|
||||
@@ -66,7 +68,7 @@ abstract class $PaymentMethodReportEventCopyWith<$Res> {
|
||||
$Res Function(PaymentMethodReportEvent) then) =
|
||||
_$PaymentMethodReportEventCopyWithImpl<$Res, PaymentMethodReportEvent>;
|
||||
@useResult
|
||||
$Res call({String startDate, String endDate});
|
||||
$Res call({DateTime startDate, DateTime endDate});
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
@@ -92,11 +94,11 @@ class _$PaymentMethodReportEventCopyWithImpl<$Res,
|
||||
startDate: null == startDate
|
||||
? _value.startDate
|
||||
: startDate // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
as DateTime,
|
||||
endDate: null == endDate
|
||||
? _value.endDate
|
||||
: endDate // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
as DateTime,
|
||||
) as $Val);
|
||||
}
|
||||
}
|
||||
@@ -110,7 +112,7 @@ abstract class _$$GetPaymentMethodReportImplCopyWith<$Res>
|
||||
__$$GetPaymentMethodReportImplCopyWithImpl<$Res>;
|
||||
@override
|
||||
@useResult
|
||||
$Res call({String startDate, String endDate});
|
||||
$Res call({DateTime startDate, DateTime endDate});
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
@@ -135,11 +137,11 @@ class __$$GetPaymentMethodReportImplCopyWithImpl<$Res>
|
||||
startDate: null == startDate
|
||||
? _value.startDate
|
||||
: startDate // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
as DateTime,
|
||||
endDate: null == endDate
|
||||
? _value.endDate
|
||||
: endDate // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
as DateTime,
|
||||
));
|
||||
}
|
||||
}
|
||||
@@ -151,9 +153,9 @@ class _$GetPaymentMethodReportImpl implements _GetPaymentMethodReport {
|
||||
{required this.startDate, required this.endDate});
|
||||
|
||||
@override
|
||||
final String startDate;
|
||||
final DateTime startDate;
|
||||
@override
|
||||
final String endDate;
|
||||
final DateTime endDate;
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
@@ -185,7 +187,7 @@ class _$GetPaymentMethodReportImpl implements _GetPaymentMethodReport {
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult when<TResult extends Object?>({
|
||||
required TResult Function(String startDate, String endDate)
|
||||
required TResult Function(DateTime startDate, DateTime endDate)
|
||||
getPaymentMethodReport,
|
||||
}) {
|
||||
return getPaymentMethodReport(startDate, endDate);
|
||||
@@ -194,7 +196,8 @@ class _$GetPaymentMethodReportImpl implements _GetPaymentMethodReport {
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult? whenOrNull<TResult extends Object?>({
|
||||
TResult? Function(String startDate, String endDate)? getPaymentMethodReport,
|
||||
TResult? Function(DateTime startDate, DateTime endDate)?
|
||||
getPaymentMethodReport,
|
||||
}) {
|
||||
return getPaymentMethodReport?.call(startDate, endDate);
|
||||
}
|
||||
@@ -202,7 +205,8 @@ class _$GetPaymentMethodReportImpl implements _GetPaymentMethodReport {
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult maybeWhen<TResult extends Object?>({
|
||||
TResult Function(String startDate, String endDate)? getPaymentMethodReport,
|
||||
TResult Function(DateTime startDate, DateTime endDate)?
|
||||
getPaymentMethodReport,
|
||||
required TResult orElse(),
|
||||
}) {
|
||||
if (getPaymentMethodReport != null) {
|
||||
@@ -243,13 +247,13 @@ class _$GetPaymentMethodReportImpl implements _GetPaymentMethodReport {
|
||||
|
||||
abstract class _GetPaymentMethodReport implements PaymentMethodReportEvent {
|
||||
const factory _GetPaymentMethodReport(
|
||||
{required final String startDate,
|
||||
required final String endDate}) = _$GetPaymentMethodReportImpl;
|
||||
{required final DateTime startDate,
|
||||
required final DateTime endDate}) = _$GetPaymentMethodReportImpl;
|
||||
|
||||
@override
|
||||
String get startDate;
|
||||
DateTime get startDate;
|
||||
@override
|
||||
String get endDate;
|
||||
DateTime get endDate;
|
||||
|
||||
/// Create a copy of PaymentMethodReportEvent
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@@ -265,7 +269,7 @@ mixin _$PaymentMethodReportState {
|
||||
TResult when<TResult extends Object?>({
|
||||
required TResult Function() initial,
|
||||
required TResult Function() loading,
|
||||
required TResult Function(PaymentMethodData data) loaded,
|
||||
required TResult Function(PaymentMethodAnalyticData data) loaded,
|
||||
required TResult Function(String message) error,
|
||||
}) =>
|
||||
throw _privateConstructorUsedError;
|
||||
@@ -273,7 +277,7 @@ mixin _$PaymentMethodReportState {
|
||||
TResult? whenOrNull<TResult extends Object?>({
|
||||
TResult? Function()? initial,
|
||||
TResult? Function()? loading,
|
||||
TResult? Function(PaymentMethodData data)? loaded,
|
||||
TResult? Function(PaymentMethodAnalyticData data)? loaded,
|
||||
TResult? Function(String message)? error,
|
||||
}) =>
|
||||
throw _privateConstructorUsedError;
|
||||
@@ -281,7 +285,7 @@ mixin _$PaymentMethodReportState {
|
||||
TResult maybeWhen<TResult extends Object?>({
|
||||
TResult Function()? initial,
|
||||
TResult Function()? loading,
|
||||
TResult Function(PaymentMethodData data)? loaded,
|
||||
TResult Function(PaymentMethodAnalyticData data)? loaded,
|
||||
TResult Function(String message)? error,
|
||||
required TResult orElse(),
|
||||
}) =>
|
||||
@@ -378,7 +382,7 @@ class _$InitialImpl implements _Initial {
|
||||
TResult when<TResult extends Object?>({
|
||||
required TResult Function() initial,
|
||||
required TResult Function() loading,
|
||||
required TResult Function(PaymentMethodData data) loaded,
|
||||
required TResult Function(PaymentMethodAnalyticData data) loaded,
|
||||
required TResult Function(String message) error,
|
||||
}) {
|
||||
return initial();
|
||||
@@ -389,7 +393,7 @@ class _$InitialImpl implements _Initial {
|
||||
TResult? whenOrNull<TResult extends Object?>({
|
||||
TResult? Function()? initial,
|
||||
TResult? Function()? loading,
|
||||
TResult? Function(PaymentMethodData data)? loaded,
|
||||
TResult? Function(PaymentMethodAnalyticData data)? loaded,
|
||||
TResult? Function(String message)? error,
|
||||
}) {
|
||||
return initial?.call();
|
||||
@@ -400,7 +404,7 @@ class _$InitialImpl implements _Initial {
|
||||
TResult maybeWhen<TResult extends Object?>({
|
||||
TResult Function()? initial,
|
||||
TResult Function()? loading,
|
||||
TResult Function(PaymentMethodData data)? loaded,
|
||||
TResult Function(PaymentMethodAnalyticData data)? loaded,
|
||||
TResult Function(String message)? error,
|
||||
required TResult orElse(),
|
||||
}) {
|
||||
@@ -495,7 +499,7 @@ class _$LoadingImpl implements _Loading {
|
||||
TResult when<TResult extends Object?>({
|
||||
required TResult Function() initial,
|
||||
required TResult Function() loading,
|
||||
required TResult Function(PaymentMethodData data) loaded,
|
||||
required TResult Function(PaymentMethodAnalyticData data) loaded,
|
||||
required TResult Function(String message) error,
|
||||
}) {
|
||||
return loading();
|
||||
@@ -506,7 +510,7 @@ class _$LoadingImpl implements _Loading {
|
||||
TResult? whenOrNull<TResult extends Object?>({
|
||||
TResult? Function()? initial,
|
||||
TResult? Function()? loading,
|
||||
TResult? Function(PaymentMethodData data)? loaded,
|
||||
TResult? Function(PaymentMethodAnalyticData data)? loaded,
|
||||
TResult? Function(String message)? error,
|
||||
}) {
|
||||
return loading?.call();
|
||||
@@ -517,7 +521,7 @@ class _$LoadingImpl implements _Loading {
|
||||
TResult maybeWhen<TResult extends Object?>({
|
||||
TResult Function()? initial,
|
||||
TResult Function()? loading,
|
||||
TResult Function(PaymentMethodData data)? loaded,
|
||||
TResult Function(PaymentMethodAnalyticData data)? loaded,
|
||||
TResult Function(String message)? error,
|
||||
required TResult orElse(),
|
||||
}) {
|
||||
@@ -575,7 +579,7 @@ abstract class _$$LoadedImplCopyWith<$Res> {
|
||||
_$LoadedImpl value, $Res Function(_$LoadedImpl) then) =
|
||||
__$$LoadedImplCopyWithImpl<$Res>;
|
||||
@useResult
|
||||
$Res call({PaymentMethodData data});
|
||||
$Res call({PaymentMethodAnalyticData data});
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
@@ -597,7 +601,7 @@ class __$$LoadedImplCopyWithImpl<$Res>
|
||||
null == data
|
||||
? _value.data
|
||||
: data // ignore: cast_nullable_to_non_nullable
|
||||
as PaymentMethodData,
|
||||
as PaymentMethodAnalyticData,
|
||||
));
|
||||
}
|
||||
}
|
||||
@@ -608,7 +612,7 @@ class _$LoadedImpl implements _Loaded {
|
||||
const _$LoadedImpl(this.data);
|
||||
|
||||
@override
|
||||
final PaymentMethodData data;
|
||||
final PaymentMethodAnalyticData data;
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
@@ -639,7 +643,7 @@ class _$LoadedImpl implements _Loaded {
|
||||
TResult when<TResult extends Object?>({
|
||||
required TResult Function() initial,
|
||||
required TResult Function() loading,
|
||||
required TResult Function(PaymentMethodData data) loaded,
|
||||
required TResult Function(PaymentMethodAnalyticData data) loaded,
|
||||
required TResult Function(String message) error,
|
||||
}) {
|
||||
return loaded(data);
|
||||
@@ -650,7 +654,7 @@ class _$LoadedImpl implements _Loaded {
|
||||
TResult? whenOrNull<TResult extends Object?>({
|
||||
TResult? Function()? initial,
|
||||
TResult? Function()? loading,
|
||||
TResult? Function(PaymentMethodData data)? loaded,
|
||||
TResult? Function(PaymentMethodAnalyticData data)? loaded,
|
||||
TResult? Function(String message)? error,
|
||||
}) {
|
||||
return loaded?.call(data);
|
||||
@@ -661,7 +665,7 @@ class _$LoadedImpl implements _Loaded {
|
||||
TResult maybeWhen<TResult extends Object?>({
|
||||
TResult Function()? initial,
|
||||
TResult Function()? loading,
|
||||
TResult Function(PaymentMethodData data)? loaded,
|
||||
TResult Function(PaymentMethodAnalyticData data)? loaded,
|
||||
TResult Function(String message)? error,
|
||||
required TResult orElse(),
|
||||
}) {
|
||||
@@ -710,9 +714,9 @@ class _$LoadedImpl implements _Loaded {
|
||||
}
|
||||
|
||||
abstract class _Loaded implements PaymentMethodReportState {
|
||||
const factory _Loaded(final PaymentMethodData data) = _$LoadedImpl;
|
||||
const factory _Loaded(final PaymentMethodAnalyticData data) = _$LoadedImpl;
|
||||
|
||||
PaymentMethodData get data;
|
||||
PaymentMethodAnalyticData get data;
|
||||
|
||||
/// Create a copy of PaymentMethodReportState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@@ -791,7 +795,7 @@ class _$ErrorImpl implements _Error {
|
||||
TResult when<TResult extends Object?>({
|
||||
required TResult Function() initial,
|
||||
required TResult Function() loading,
|
||||
required TResult Function(PaymentMethodData data) loaded,
|
||||
required TResult Function(PaymentMethodAnalyticData data) loaded,
|
||||
required TResult Function(String message) error,
|
||||
}) {
|
||||
return error(message);
|
||||
@@ -802,7 +806,7 @@ class _$ErrorImpl implements _Error {
|
||||
TResult? whenOrNull<TResult extends Object?>({
|
||||
TResult? Function()? initial,
|
||||
TResult? Function()? loading,
|
||||
TResult? Function(PaymentMethodData data)? loaded,
|
||||
TResult? Function(PaymentMethodAnalyticData data)? loaded,
|
||||
TResult? Function(String message)? error,
|
||||
}) {
|
||||
return error?.call(message);
|
||||
@@ -813,7 +817,7 @@ class _$ErrorImpl implements _Error {
|
||||
TResult maybeWhen<TResult extends Object?>({
|
||||
TResult Function()? initial,
|
||||
TResult Function()? loading,
|
||||
TResult Function(PaymentMethodData data)? loaded,
|
||||
TResult Function(PaymentMethodAnalyticData data)? loaded,
|
||||
TResult Function(String message)? error,
|
||||
required TResult orElse(),
|
||||
}) {
|
||||
|
||||
+3
-3
@@ -3,7 +3,7 @@ part of 'payment_method_report_bloc.dart';
|
||||
@freezed
|
||||
class PaymentMethodReportEvent with _$PaymentMethodReportEvent {
|
||||
const factory PaymentMethodReportEvent.getPaymentMethodReport({
|
||||
required String startDate,
|
||||
required String endDate,
|
||||
required DateTime startDate,
|
||||
required DateTime endDate,
|
||||
}) = _GetPaymentMethodReport;
|
||||
}
|
||||
}
|
||||
|
||||
+3
-2
@@ -4,6 +4,7 @@ part of 'payment_method_report_bloc.dart';
|
||||
class PaymentMethodReportState with _$PaymentMethodReportState {
|
||||
const factory PaymentMethodReportState.initial() = _Initial;
|
||||
const factory PaymentMethodReportState.loading() = _Loading;
|
||||
const factory PaymentMethodReportState.loaded(PaymentMethodData data) = _Loaded;
|
||||
const factory PaymentMethodReportState.loaded(
|
||||
PaymentMethodAnalyticData data) = _Loaded;
|
||||
const factory PaymentMethodReportState.error(String message) = _Error;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -202,12 +202,9 @@ class _ReportPageState extends State<ReportPage> {
|
||||
context.read<PaymentMethodReportBloc>().add(
|
||||
PaymentMethodReportEvent
|
||||
.getPaymentMethodReport(
|
||||
startDate:
|
||||
DateFormatter.formatDateTime(
|
||||
fromDate),
|
||||
endDate:
|
||||
DateFormatter.formatDateTime(
|
||||
toDate)),
|
||||
startDate: fromDate,
|
||||
endDate: toDate,
|
||||
),
|
||||
);
|
||||
},
|
||||
isActive: selectedMenu == 4,
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import 'package:enaklo_pos/core/extensions/int_ext.dart';
|
||||
import 'package:enaklo_pos/data/models/response/payment_method_analytic_response_model.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:enaklo_pos/core/constants/colors.dart';
|
||||
import 'package:enaklo_pos/core/extensions/string_ext.dart';
|
||||
import 'package:enaklo_pos/data/models/response/payment_method_response_model.dart';
|
||||
|
||||
import '../../../core/components/spaces.dart';
|
||||
|
||||
class PaymentMethodReportWidget extends StatelessWidget {
|
||||
final PaymentMethodData paymentMethodData;
|
||||
final PaymentMethodAnalyticData paymentMethodData;
|
||||
final String title;
|
||||
final String searchDateFormatted;
|
||||
final List<Widget> headerWidgets;
|
||||
@@ -23,127 +23,343 @@ class PaymentMethodReportWidget extends StatelessWidget {
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
backgroundColor: AppColors.white,
|
||||
body: Column(
|
||||
children: [
|
||||
// HEADER
|
||||
Container(
|
||||
padding: const EdgeInsets.all(24.0),
|
||||
decoration: const BoxDecoration(
|
||||
color: AppColors.white,
|
||||
border: Border(
|
||||
bottom: BorderSide(
|
||||
color: AppColors.stroke,
|
||||
width: 1,
|
||||
),
|
||||
),
|
||||
body: Container(
|
||||
padding: const EdgeInsets.all(20),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
border: Border(
|
||||
left: BorderSide(
|
||||
color: Colors.grey.shade200,
|
||||
width: 1,
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Column(
|
||||
),
|
||||
),
|
||||
child: SingleChildScrollView(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
// Header Section
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
title,
|
||||
style: TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Colors.grey.shade800,
|
||||
),
|
||||
),
|
||||
Container(
|
||||
padding:
|
||||
const EdgeInsets.symmetric(horizontal: 12, vertical: 6),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.blue.shade50,
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
border: Border.all(
|
||||
color: Colors.blue.shade200,
|
||||
width: 1,
|
||||
),
|
||||
),
|
||||
child: Text(
|
||||
searchDateFormatted,
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Colors.blue.shade700,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SpaceHeight(24), // Summary Cards
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Container(
|
||||
padding: const EdgeInsets.all(16),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.green.shade50,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
border: Border.all(
|
||||
color: Colors.green.shade200,
|
||||
width: 1,
|
||||
),
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'Pendapatan Total',
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Colors.green.shade700,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Text(
|
||||
paymentMethodData
|
||||
.summary.totalAmount.currencyFormatRpV2,
|
||||
style: TextStyle(
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Colors.green.shade800,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
Expanded(
|
||||
child: Container(
|
||||
padding: const EdgeInsets.all(16),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.orange.shade50,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
border: Border.all(
|
||||
color: Colors.orange.shade200,
|
||||
width: 1,
|
||||
),
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'Jumlah Pesanan',
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Colors.orange.shade700,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Text(
|
||||
paymentMethodData.summary.totalOrders.toString(),
|
||||
style: TextStyle(
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Colors.orange.shade800,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SpaceHeight(16),
|
||||
// Average Order Value Card
|
||||
Container(
|
||||
width: double.infinity,
|
||||
padding: const EdgeInsets.all(16),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.purple.shade50,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
border: Border.all(
|
||||
color: Colors.purple.shade200,
|
||||
width: 1,
|
||||
),
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
title,
|
||||
style: const TextStyle(
|
||||
fontSize: 24,
|
||||
fontWeight: FontWeight.w600,
|
||||
'Nilai Pesanan Rata-rata',
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Colors.purple.shade700,
|
||||
),
|
||||
),
|
||||
const SpaceHeight(8.0),
|
||||
const SizedBox(height: 8),
|
||||
Text(
|
||||
searchDateFormatted,
|
||||
style: const TextStyle(
|
||||
fontSize: 16,
|
||||
color: AppColors.grey,
|
||||
paymentMethodData.summary.averageOrderValue
|
||||
.round()
|
||||
.currencyFormatRpV2,
|
||||
style: TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Colors.purple.shade800,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
Row(
|
||||
),
|
||||
const SpaceHeight(24),
|
||||
|
||||
// Payment Methods Section
|
||||
Text(
|
||||
'Rincian Metode Pembayaran',
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Colors.grey.shade800,
|
||||
),
|
||||
),
|
||||
|
||||
const SpaceHeight(16),
|
||||
|
||||
// Payment Method Item
|
||||
...List.generate(paymentMethodData.data.length, (index) {
|
||||
final item = paymentMethodData.data[index];
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(bottom: 16),
|
||||
child: Column(
|
||||
children: [
|
||||
Container(
|
||||
padding: const EdgeInsets.all(16),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.grey.shade50,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
border: Border.all(
|
||||
color: Colors.grey.shade200,
|
||||
width: 1,
|
||||
),
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
// Payment Method Icon
|
||||
Container(
|
||||
width: 40,
|
||||
height: 40,
|
||||
decoration: BoxDecoration(
|
||||
color: AppColors.primary,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
border: Border.all(
|
||||
color: AppColors.primary,
|
||||
width: 1,
|
||||
),
|
||||
),
|
||||
child: Icon(
|
||||
Icons.money,
|
||||
color: AppColors.white,
|
||||
size: 20,
|
||||
),
|
||||
),
|
||||
|
||||
const SizedBox(width: 16),
|
||||
|
||||
// Payment Method Details
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
item.paymentMethodName,
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Colors.grey.shade800,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
"${item.percentage}%",
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: AppColors.primary,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
const SizedBox(height: 8),
|
||||
|
||||
Row(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
item.totalAmount.currencyFormatRpV2,
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Colors.grey.shade600,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
'${item.orderCount} Pesanan',
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Colors.grey.shade600,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
const SizedBox(height: 8),
|
||||
|
||||
// Progress Bar
|
||||
Container(
|
||||
width: double.infinity,
|
||||
height: 6,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.grey.shade200,
|
||||
borderRadius: BorderRadius.circular(3),
|
||||
),
|
||||
child: FractionallySizedBox(
|
||||
alignment: Alignment.centerLeft,
|
||||
widthFactor:
|
||||
(item.percentage / 100), // 100%
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: AppColors.primary,
|
||||
borderRadius:
|
||||
BorderRadius.circular(3),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}),
|
||||
|
||||
Container(
|
||||
padding: const EdgeInsets.all(12),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.blue.shade50,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
border: Border.all(
|
||||
color: Colors.blue.shade200,
|
||||
width: 1,
|
||||
),
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
Container(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 16.0,
|
||||
vertical: 8.0,
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
color: AppColors.primary,
|
||||
borderRadius: BorderRadius.circular(8.0),
|
||||
),
|
||||
Icon(
|
||||
Icons.info_outline,
|
||||
color: Colors.blue.shade600,
|
||||
size: 16,
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
Expanded(
|
||||
child: Text(
|
||||
'Total: ${paymentMethodData.total?.currencyFormatRpV2 ?? 'Rp 0'}',
|
||||
style: const TextStyle(
|
||||
color: AppColors.white,
|
||||
fontWeight: FontWeight.w600,
|
||||
'All payments processed successfully with 100% cash transactions',
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: Colors.blue.shade700,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
// CONTENT
|
||||
Expanded(
|
||||
child: SingleChildScrollView(
|
||||
child: Column(
|
||||
children: [
|
||||
// TABLE HEADER
|
||||
Row(
|
||||
children: headerWidgets,
|
||||
),
|
||||
|
||||
// TABLE BODY
|
||||
...paymentMethodData.paymentMethods?.map((item) {
|
||||
return Container(
|
||||
decoration: const BoxDecoration(
|
||||
border: Border(
|
||||
bottom: BorderSide(
|
||||
color: AppColors.stroke,
|
||||
width: 1,
|
||||
),
|
||||
),
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
_getBodyItemWidget(
|
||||
item.paymentMethod ?? '-',
|
||||
180,
|
||||
),
|
||||
_getBodyItemWidget(
|
||||
item.totalAmount?.currencyFormatRpV2 ?? 'Rp 0',
|
||||
180,
|
||||
),
|
||||
_getBodyItemWidget(
|
||||
item.transactionCount?.toString() ?? '0',
|
||||
180,
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}).toList() ??
|
||||
[],
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _getBodyItemWidget(String label, double width) {
|
||||
return Container(
|
||||
width: width,
|
||||
height: 56,
|
||||
alignment: Alignment.centerLeft,
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16.0),
|
||||
child: Text(
|
||||
label,
|
||||
style: const TextStyle(
|
||||
fontSize: 14,
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user