feat: update profit shareing
Build & Deploy iOS to TestFlight / build-and-deploy (push) Canceled after 0s

This commit is contained in:
efrilm
2026-10-04 22:31:01 +07:00
parent 288d0d75a0
commit 243b7e02aa
23 changed files with 1349 additions and 451 deletions
@@ -4,15 +4,19 @@ import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:shimmer/shimmer.dart';
import '../../../application/analytic/profit_sharing_loader/profit_sharing_loader_bloc.dart';
import '../../../common/extension/extension.dart';
import '../../../common/theme/theme.dart';
import '../../../domain/analytic/analytic.dart';
import '../../../injection.dart';
import '../../components/field/date_range_picker_field.dart';
import '../../components/spacer/spacer.dart';
import '../../components/toast/flushbar.dart';
import '../../router/app_router.gr.dart';
import 'widgets/profit_sharing_allocation.dart';
import 'widgets/profit_sharing_categories.dart';
import 'widgets/profit_sharing_header.dart';
import 'widgets/profit_sharing_periods.dart';
import 'widgets/profit_sharing_sdl.dart';
@RoutePage()
class ProfitSharingPage extends StatefulWidget implements AutoRouteWrapper {
@@ -124,20 +128,23 @@ class _ProfitSharingPageState extends State<ProfitSharingPage>
opacity: _fadeAnimation,
child: ProfitSharingCategories(
categories: state.profitSharing.categories,
onCategoryTap: (category) => context.router.push(
ProfitSharingDetailRoute(
parentCategoryId: category.parentCategoryId,
parentCategoryName: category.parentCategoryName,
dateFrom: state.dateFrom,
dateTo: state.dateTo,
),
),
onCategoryTap: (category) =>
_openDetail(context, state, category),
),
),
),
const SliverToBoxAdapter(child: SpaceHeight(16)),
SliverToBoxAdapter(
child: FadeTransition(
opacity: _fadeAnimation,
child: _buildSdlSection(context, state),
),
),
const SliverToBoxAdapter(child: SpaceHeight(16)),
SliverToBoxAdapter(
child: FadeTransition(
opacity: _fadeAnimation,
@@ -174,6 +181,58 @@ class _ProfitSharingPageState extends State<ProfitSharingPage>
);
}
/// Detail kembali dengan `true` kalau kategori induknya sudah non-team;
/// list dimuat ulang supaya kategori itu hilang.
Future<void> _openDetail(
BuildContext context,
ProfitSharingLoaderState state,
ProfitSharingCategory category,
) async {
final isNotTeam = await context.router.push<bool>(
ProfitSharingDetailRoute(
parentCategoryId: category.parentCategoryId,
parentCategoryName: category.parentCategoryName,
dateFrom: state.dateFrom,
dateTo: state.dateTo,
),
);
if (isNotTeam != true || !context.mounted) return;
AppFlushbar.showError(context, context.lang.profit_sharing_not_team);
context.read<ProfitSharingLoaderBloc>().add(
const ProfitSharingLoaderEvent.fetched(),
);
}
Widget _buildSdlSection(
BuildContext context,
ProfitSharingLoaderState state,
) {
final total = state.profitSharing.budget.total;
final categories = [...state.profitSharing.categories]
..sort((a, b) => b.sdl.compareTo(a.sdl));
return ProfitSharingSdlSection(
sdl: total.sdl,
revenue: total.revenue,
// Fee owner beda tiap kategori induk, jadi yang ditampilkan persen
// efektifnya; persentase bawaan hanya dipakai saat belum ada omzet.
percent: total.hasRevenue
? total.sdlPercentage
: state.profitSharing.budget.percentages.owner,
breakdownTitle: context.lang.sdl_per_parent_category,
items: [
for (final category in categories)
ProfitSharingSdlItem(
label: category.parentCategoryName,
sdl: category.sdl,
revenue: category.totalRevenue,
feePercent: category.ownerFeePercent,
),
],
);
}
Widget _buildShimmer() {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 16),