196 lines
5.3 KiB
Dart
196 lines
5.3 KiB
Dart
import 'package:flutter/material.dart';
|
|
|
|
import '../../../../common/extension/extension.dart';
|
|
import '../../../../common/theme/theme.dart';
|
|
import '../../../../domain/analytic/analytic.dart';
|
|
import '../../../components/spacer/spacer.dart';
|
|
|
|
/// Warna tetap untuk tiap pos bagi hasil supaya konsisten di semua bagian.
|
|
class ProfitSharingColor {
|
|
static const Color purchase = Color(0xFF2196F3);
|
|
static const Color owner = Color(0xFF4CAF50);
|
|
static const Color team = Color(0xFFFF9800);
|
|
}
|
|
|
|
class ProfitSharingAllocation extends StatelessWidget {
|
|
final ProfitSharingBudget budget;
|
|
|
|
const ProfitSharingAllocation({super.key, required this.budget});
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final total = budget.total;
|
|
final percentages = budget.percentages;
|
|
|
|
return Container(
|
|
margin: const EdgeInsets.symmetric(horizontal: 16),
|
|
padding: const EdgeInsets.all(20),
|
|
decoration: BoxDecoration(
|
|
color: AppColor.white,
|
|
borderRadius: BorderRadius.circular(16),
|
|
boxShadow: [
|
|
BoxShadow(
|
|
color: AppColor.textLight.withOpacity(0.08),
|
|
spreadRadius: 1,
|
|
blurRadius: 10,
|
|
offset: const Offset(0, 2),
|
|
),
|
|
],
|
|
),
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Text(
|
|
context.lang.profit_sharing_allocation,
|
|
style: AppStyle.lg.copyWith(
|
|
fontWeight: FontWeight.w700,
|
|
color: AppColor.textPrimary,
|
|
),
|
|
),
|
|
|
|
const SpaceHeight(16),
|
|
|
|
ProfitSharingBar(
|
|
purchase: percentages.purchase,
|
|
owner: percentages.owner,
|
|
team: percentages.team,
|
|
),
|
|
|
|
const SpaceHeight(20),
|
|
|
|
_row(
|
|
context: context,
|
|
color: ProfitSharingColor.purchase,
|
|
label: context.lang.share_purchase,
|
|
percentage: percentages.purchase,
|
|
amount: total.limitPurchase,
|
|
),
|
|
const Divider(height: 24, color: AppColor.borderLight),
|
|
_row(
|
|
context: context,
|
|
color: ProfitSharingColor.owner,
|
|
label: context.lang.share_owner,
|
|
percentage: percentages.owner,
|
|
amount: total.limitOwner,
|
|
),
|
|
const Divider(height: 24, color: AppColor.borderLight),
|
|
_row(
|
|
context: context,
|
|
color: ProfitSharingColor.team,
|
|
label: context.lang.share_team,
|
|
percentage: percentages.team,
|
|
amount: total.limitTeam,
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
|
|
Widget _row({
|
|
required BuildContext context,
|
|
required Color color,
|
|
required String label,
|
|
required double percentage,
|
|
required int amount,
|
|
}) {
|
|
return Row(
|
|
children: [
|
|
Container(
|
|
width: 10,
|
|
height: 10,
|
|
decoration: BoxDecoration(color: color, shape: BoxShape.circle),
|
|
),
|
|
const SpaceWidth(10),
|
|
Text(
|
|
label,
|
|
style: AppStyle.md.copyWith(
|
|
color: AppColor.textPrimary,
|
|
fontWeight: FontWeight.w600,
|
|
),
|
|
),
|
|
const SpaceWidth(8),
|
|
Container(
|
|
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 2),
|
|
decoration: BoxDecoration(
|
|
color: color.withOpacity(0.12),
|
|
borderRadius: BorderRadius.circular(6),
|
|
),
|
|
child: Text(
|
|
'${percentage.toStringAsFixed(percentage % 1 == 0 ? 0 : 1)}%',
|
|
style: AppStyle.xs.copyWith(
|
|
color: color,
|
|
fontWeight: FontWeight.w700,
|
|
),
|
|
),
|
|
),
|
|
const Spacer(),
|
|
Flexible(
|
|
child: Text(
|
|
amount.currencyFormatRp,
|
|
textAlign: TextAlign.right,
|
|
style: AppStyle.md.copyWith(
|
|
color: AppColor.textPrimary,
|
|
fontWeight: FontWeight.w700,
|
|
),
|
|
overflow: TextOverflow.ellipsis,
|
|
),
|
|
),
|
|
],
|
|
);
|
|
}
|
|
}
|
|
|
|
/// Bar proporsi belanja / owner / tim.
|
|
class ProfitSharingBar extends StatelessWidget {
|
|
final double purchase;
|
|
final double owner;
|
|
final double team;
|
|
final double height;
|
|
|
|
const ProfitSharingBar({
|
|
super.key,
|
|
required this.purchase,
|
|
required this.owner,
|
|
required this.team,
|
|
this.height = 12,
|
|
});
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final total = purchase + owner + team;
|
|
if (total <= 0) {
|
|
return Container(
|
|
height: height,
|
|
decoration: BoxDecoration(
|
|
color: AppColor.borderLight,
|
|
borderRadius: BorderRadius.circular(height),
|
|
),
|
|
);
|
|
}
|
|
|
|
return ClipRRect(
|
|
borderRadius: BorderRadius.circular(height),
|
|
child: SizedBox(
|
|
height: height,
|
|
child: Row(
|
|
children: [
|
|
_segment(purchase, ProfitSharingColor.purchase),
|
|
_segment(owner, ProfitSharingColor.owner),
|
|
_segment(team, ProfitSharingColor.team),
|
|
].whereType<Widget>().toList(),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
/// Segmen dilewati saat porsinya 0 supaya Expanded tidak dipakai dengan flex 0.
|
|
Widget? _segment(double value, Color color) {
|
|
final flex = (value * 100).round();
|
|
if (flex <= 0) return null;
|
|
return Expanded(
|
|
flex: flex,
|
|
child: Container(color: color),
|
|
);
|
|
}
|
|
}
|