feat: lang

This commit is contained in:
efrilm
2025-08-20 13:52:49 +07:00
parent f07d07b3a8
commit 5a83bc4049
53 changed files with 3386 additions and 721 deletions
@@ -126,7 +126,7 @@ class _FinancePageState extends State<FinancePage>
pinned: true,
backgroundColor: AppColor.primary,
elevation: 0,
flexibleSpace: CustomAppBar(title: 'Keuangan'),
flexibleSpace: CustomAppBar(title: context.lang.finance),
),
// Header dengan filter periode
@@ -221,7 +221,7 @@ class _FinancePageState extends State<FinancePage>
children: [
Expanded(
child: FinanceSummaryCard(
title: 'Total Pendapatan',
title: context.lang.total_revenue,
amount: summary.totalRevenue.currencyFormatRp,
icon: LineIcons.arrowUp,
color: AppColor.success,
@@ -231,7 +231,7 @@ class _FinancePageState extends State<FinancePage>
const SizedBox(width: 12),
Expanded(
child: FinanceSummaryCard(
title: 'Total Pengeluaran',
title: context.lang.total_expenditures,
amount: summary.totalCost.currencyFormatRp,
icon: LineIcons.arrowDown,
color: AppColor.error,
@@ -245,7 +245,7 @@ class _FinancePageState extends State<FinancePage>
children: [
Expanded(
child: FinanceSummaryCard(
title: 'Keuntungan Bersih',
title: context.lang.net_profit,
amount: summary.netProfit.currencyFormatRp,
icon: LineIcons.lineChart,
color: AppColor.info,
@@ -255,7 +255,7 @@ class _FinancePageState extends State<FinancePage>
const SizedBox(width: 12),
Expanded(
child: FinanceSummaryCard(
title: 'Margin Profit',
title: context.lang.margin_profit,
amount: '${summary.profitabilityRatio.round()}%',
icon: LineIcons.percent,
color: AppColor.warning,
@@ -304,14 +304,14 @@ class _FinancePageState extends State<FinancePage>
),
const SizedBox(width: 12),
Text(
'Analisis Produk',
context.lang.product_analytic,
style: AppStyle.lg.copyWith(fontWeight: FontWeight.bold),
),
const Spacer(),
TextButton(
onPressed: () {},
child: Text(
'Lihat Semua',
context.lang.view_all,
style: AppStyle.sm.copyWith(color: AppColor.primary),
),
),
@@ -3,6 +3,7 @@ import 'package:flutter/material.dart';
import 'package:line_icons/line_icons.dart';
import 'package:intl/intl.dart';
import '../../../../common/extension/extension.dart';
import '../../../../common/theme/theme.dart';
import '../../../../domain/analytic/analytic.dart';
@@ -57,7 +58,7 @@ class FinanceCashFlow extends StatelessWidget {
),
const SizedBox(width: 12),
Text(
'Analisis Cash Flow',
context.lang.cash_flow_analysis,
style: AppStyle.lg.copyWith(fontWeight: FontWeight.bold),
),
],
@@ -78,7 +79,7 @@ class FinanceCashFlow extends StatelessWidget {
children: [
Expanded(
child: _buildCashFlowIndicator(
'Cash In',
context.lang.cash_in,
_formatCurrency(totalCashIn),
LineIcons.arrowUp,
AppColor.success,
@@ -87,7 +88,7 @@ class FinanceCashFlow extends StatelessWidget {
const SizedBox(width: 16),
Expanded(
child: _buildCashFlowIndicator(
'Cash Out',
context.lang.cash_out,
_formatCurrency(totalCashOut),
LineIcons.arrowDown,
AppColor.error,
@@ -96,7 +97,7 @@ class FinanceCashFlow extends StatelessWidget {
const SizedBox(width: 16),
Expanded(
child: _buildCashFlowIndicator(
'Net Flow',
context.lang.net_flow,
_formatCurrency(netFlow),
LineIcons.equals,
AppColor.info,
@@ -119,7 +120,7 @@ class FinanceCashFlow extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Grafik Cash Flow ${dailyData.length} Hari Terakhir',
context.lang.cash_flow_chart(dailyData.length),
style: AppStyle.sm.copyWith(
color: AppColor.textSecondary,
fontWeight: FontWeight.w600,
@@ -136,11 +137,11 @@ class FinanceCashFlow extends StatelessWidget {
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
_buildChartLegend('Cash In', AppColor.success),
_buildChartLegend(context.lang.cash_in, AppColor.success),
const SizedBox(width: 20),
_buildChartLegend('Cash Out', AppColor.error),
_buildChartLegend(context.lang.cash_out, AppColor.error),
const SizedBox(width: 20),
_buildChartLegend('Net Flow', AppColor.info),
_buildChartLegend(context.lang.net_flow, AppColor.info),
],
),
],
@@ -51,7 +51,7 @@ class FinanceCategory extends StatelessWidget {
),
const SizedBox(width: 12),
Text(
'Kategori Penjualan',
context.lang.sales_category,
style: AppStyle.lg.copyWith(fontWeight: FontWeight.bold),
),
],
@@ -60,10 +60,11 @@ class FinanceCategory extends StatelessWidget {
// Show empty state if no categories
if (categories.isEmpty)
_buildEmptyState()
_buildEmptyState(context)
else
...sortedCategories.asMap().entries.map(
(entry) => _buildCategoryItem(
context,
entry.value,
_calculatePercentage(entry.value.totalRevenue, totalRevenue),
_getCategoryColor(entry.key),
@@ -75,6 +76,7 @@ class FinanceCategory extends StatelessWidget {
}
Widget _buildCategoryItem(
BuildContext context,
CategoryAnalyticItem category,
double percentage,
Color color,
@@ -111,7 +113,7 @@ class FinanceCategory extends StatelessWidget {
),
const SizedBox(height: 2),
Text(
'${category.productCount} produk${category.orderCount} pesanan',
'${category.productCount} ${context.lang.product}${category.orderCount} ${context.lang.orders}',
style: AppStyle.xs.copyWith(
color: AppColor.textSecondary,
),
@@ -134,7 +136,7 @@ class FinanceCategory extends StatelessWidget {
),
),
Text(
'${NumberFormat('#,###', 'id_ID').format(category.totalQuantity)} unit',
'${NumberFormat('#,###', 'id_ID').format(category.totalQuantity)} ${context.lang.unit}',
style: AppStyle.xs.copyWith(color: AppColor.textSecondary),
),
],
@@ -161,10 +163,10 @@ class FinanceCategory extends StatelessWidget {
);
}
Widget _buildEmptyState() {
Widget _buildEmptyState(BuildContext context) {
return EmptyWidget(
title: 'Belum ada data kategori',
message: 'Data kategori penjualan akan muncul di sini',
title: context.lang.category_no_data,
message: context.lang.category_no_data_desc,
);
}
@@ -81,21 +81,21 @@ class ProfitLossProduct extends StatelessWidget {
children: [
Expanded(
child: _buildMetricColumn(
'Pendapatan',
context.lang.revenue,
product.revenue.currencyFormatRp,
AppColor.success,
),
),
Expanded(
child: _buildMetricColumn(
'Biaya',
context.lang.cost,
product.cost.currencyFormatRp,
AppColor.error,
),
),
Expanded(
child: _buildMetricColumn(
'Laba Kotor',
context.lang.gross_profit,
product.grossProfit.currencyFormatRp,
AppColor.info,
),
@@ -109,14 +109,14 @@ class ProfitLossProduct extends StatelessWidget {
children: [
Expanded(
child: _buildMetricColumn(
'Harga Rata-rata',
context.lang.average_price,
product.averagePrice.currencyFormatRp,
AppColor.textSecondary,
),
),
Expanded(
child: _buildMetricColumn(
'Laba per Unit',
context.lang.profit_per_unit,
product.profitPerUnit.currencyFormatRp,
AppColor.primary,
),
@@ -46,7 +46,7 @@ class FinanceProfitLoss extends StatelessWidget {
),
const SizedBox(width: 12),
Text(
'Detail Profit & Loss',
context.lang.profit_loss_detail,
style: AppStyle.lg.copyWith(fontWeight: FontWeight.bold),
),
],
@@ -55,7 +55,7 @@ class FinanceProfitLoss extends StatelessWidget {
// Total Revenue (Penjualan Kotor)
_buildPLItem(
'Penjualan Kotor',
context.lang.gross_sales,
data.totalRevenue.currencyFormatRp,
AppColor.success,
true,
@@ -63,7 +63,7 @@ class FinanceProfitLoss extends StatelessWidget {
// Discount (Diskon & Retur)
_buildPLItem(
'Diskon & Retur',
'${context.lang.discount} & ${context.lang.return_text}',
'- ${data.totalDiscount.currencyFormatRp}',
AppColor.error,
false,
@@ -73,7 +73,7 @@ class FinanceProfitLoss extends StatelessWidget {
// Net Sales (Penjualan Bersih = Total Revenue - Discount)
_buildPLItem(
'Penjualan Bersih',
context.lang.net_sales,
(data.totalRevenue - data.totalDiscount).currencyFormatRp,
AppColor.textPrimary,
true,
@@ -84,7 +84,7 @@ class FinanceProfitLoss extends StatelessWidget {
// Cost of Goods Sold (HPP)
_buildPLItem(
'HPP (Harga Pokok Penjualan)',
'${context.lang.cogs} (${context.lang.cost_of_goods_sold})',
'- ${data.totalCost.currencyFormatRp}',
AppColor.error,
false,
@@ -94,7 +94,7 @@ class FinanceProfitLoss extends StatelessWidget {
// Gross Profit (Laba Kotor)
_buildPLItem(
'Laba Kotor',
context.lang.gross_profit,
data.grossProfit.currencyFormatRp,
AppColor.success,
true,
@@ -107,7 +107,7 @@ class FinanceProfitLoss extends StatelessWidget {
// Operational Cost (Biaya Operasional) - calculated as difference
_buildPLItem(
'Biaya Operasional',
context.lang.operating_costs,
'- ${_calculateOperationalCost().currencyFormatRp}',
AppColor.error,
false,
@@ -117,7 +117,7 @@ class FinanceProfitLoss extends StatelessWidget {
// Net Profit (Laba Bersih)
_buildPLItem(
'Laba Bersih',
context.lang.net_profit,
data.netProfit.currencyFormatRp,
AppColor.primary,
true,