feat: 다국어 지원 및 다중 통화 환율 변환 기능 확대
- ExchangeRateService에 JPY, CNY 환율 지원 추가 - 구독 서비스별 다국어 표시 이름 지원 - 분석 화면 차트 및 UI/UX 개선 - 설정 화면 전면 리팩토링 - SMS 스캔 기능 사용성 개선 - 전체 앱 다국어 번역 확대 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -1,12 +1,15 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import '../../models/subscription_model.dart';
|
||||
import '../../services/currency_util.dart';
|
||||
import '../../providers/locale_provider.dart';
|
||||
import '../../utils/haptic_feedback_helper.dart';
|
||||
import '../../theme/app_colors.dart';
|
||||
import '../glassmorphism_card.dart';
|
||||
import '../themed_text.dart';
|
||||
import '../../l10n/app_localizations.dart';
|
||||
|
||||
/// 총 지출 요약을 보여주는 카드 위젯
|
||||
class TotalExpenseSummaryCard extends StatelessWidget {
|
||||
@@ -23,6 +26,7 @@ class TotalExpenseSummaryCard extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final locale = context.watch<LocaleProvider>().locale.languageCode;
|
||||
return SliverToBoxAdapter(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||
@@ -52,7 +56,7 @@ class TotalExpenseSummaryCard extends StatelessWidget {
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
ThemedText.headline(
|
||||
text: '총 지출 요약',
|
||||
text: AppLocalizations.of(context).totalExpenseSummary,
|
||||
style: const TextStyle(
|
||||
fontSize: 18,
|
||||
),
|
||||
@@ -63,14 +67,14 @@ class TotalExpenseSummaryCard extends StatelessWidget {
|
||||
padding: EdgeInsets.zero,
|
||||
constraints: const BoxConstraints(),
|
||||
onPressed: () async {
|
||||
final totalExpenseText = CurrencyUtil.formatTotalAmount(totalExpense);
|
||||
final totalExpenseText = CurrencyUtil.formatTotalAmountWithLocale(totalExpense, locale);
|
||||
await Clipboard.setData(
|
||||
ClipboardData(text: totalExpenseText));
|
||||
HapticFeedbackHelper.lightImpact();
|
||||
if (!context.mounted) return;
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text('총 지출액이 복사되었습니다: $totalExpenseText'),
|
||||
content: Text(AppLocalizations.of(context).totalExpenseCopied(totalExpenseText)),
|
||||
duration: const Duration(seconds: 2),
|
||||
behavior: SnackBarBehavior.floating,
|
||||
shape: RoundedRectangleBorder(
|
||||
@@ -89,7 +93,7 @@ class TotalExpenseSummaryCard extends StatelessWidget {
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
ThemedText.subtitle(
|
||||
text: '월 단위 총액',
|
||||
text: AppLocalizations.of(context).monthlyTotalAmount,
|
||||
style: const TextStyle(
|
||||
fontSize: 14,
|
||||
),
|
||||
@@ -103,7 +107,7 @@ class TotalExpenseSummaryCard extends StatelessWidget {
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
ThemedText.caption(
|
||||
text: '총 지출',
|
||||
text: AppLocalizations.of(context).totalExpense,
|
||||
style: const TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.bold,
|
||||
@@ -111,7 +115,7 @@ class TotalExpenseSummaryCard extends StatelessWidget {
|
||||
),
|
||||
const SizedBox(height: 4),
|
||||
ThemedText(
|
||||
CurrencyUtil.formatTotalAmount(totalExpense),
|
||||
CurrencyUtil.formatTotalAmountWithLocale(totalExpense, locale),
|
||||
style: const TextStyle(
|
||||
fontSize: 26,
|
||||
fontWeight: FontWeight.bold,
|
||||
@@ -148,7 +152,7 @@ class TotalExpenseSummaryCard extends StatelessWidget {
|
||||
CrossAxisAlignment.start,
|
||||
children: [
|
||||
ThemedText.caption(
|
||||
text: '총 서비스',
|
||||
text: AppLocalizations.of(context).totalServices,
|
||||
style: const TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.bold,
|
||||
@@ -156,7 +160,7 @@ class TotalExpenseSummaryCard extends StatelessWidget {
|
||||
),
|
||||
const SizedBox(height: 2),
|
||||
ThemedText(
|
||||
'${subscriptions.length}개',
|
||||
AppLocalizations.of(context).subscriptionCount(subscriptions.length),
|
||||
style: const TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.bold,
|
||||
@@ -190,7 +194,7 @@ class TotalExpenseSummaryCard extends StatelessWidget {
|
||||
CrossAxisAlignment.start,
|
||||
children: [
|
||||
ThemedText.caption(
|
||||
text: '평균 요금',
|
||||
text: AppLocalizations.of(context).averageCost,
|
||||
style: const TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.bold,
|
||||
@@ -198,10 +202,11 @@ class TotalExpenseSummaryCard extends StatelessWidget {
|
||||
),
|
||||
const SizedBox(height: 2),
|
||||
ThemedText(
|
||||
CurrencyUtil.formatTotalAmount(
|
||||
CurrencyUtil.formatTotalAmountWithLocale(
|
||||
subscriptions.isEmpty
|
||||
? 0
|
||||
: totalExpense / subscriptions.length),
|
||||
: totalExpense / subscriptions.length,
|
||||
locale),
|
||||
style: const TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.bold,
|
||||
|
||||
Reference in New Issue
Block a user