Major UI/UX and architecture improvements
- Implemented new navigation system with NavigationProvider and route management - Added adaptive theme system with ThemeProvider for better theme handling - Introduced glassmorphism design elements (app bars, scaffolds, cards) - Added advanced animations (spring animations, page transitions, staggered lists) - Implemented performance optimizations (memory manager, lazy loading) - Refactored Analysis screen into modular components - Added floating navigation bar with haptic feedback - Improved subscription cards with swipe actions - Enhanced skeleton loading with better animations - Added cached network image support - Improved overall app architecture and code organization 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -243,4 +243,83 @@ class SubscriptionProvider extends ChangeNotifier {
|
||||
await refreshSubscriptions();
|
||||
}
|
||||
}
|
||||
|
||||
/// 총 월간 지출을 계산합니다.
|
||||
Future<double> calculateTotalExpense() async {
|
||||
// 이미 존재하는 totalMonthlyExpense getter를 사용
|
||||
return totalMonthlyExpense;
|
||||
}
|
||||
|
||||
/// 최근 6개월의 월별 지출 데이터를 반환합니다.
|
||||
Future<List<Map<String, dynamic>>> getMonthlyExpenseData() async {
|
||||
final now = DateTime.now();
|
||||
final List<Map<String, dynamic>> monthlyData = [];
|
||||
|
||||
// 최근 6개월 데이터 생성
|
||||
for (int i = 5; i >= 0; i--) {
|
||||
final month = DateTime(now.year, now.month - i, 1);
|
||||
double monthTotal = 0.0;
|
||||
|
||||
// 해당 월에 활성화된 구독 계산
|
||||
for (final subscription in _subscriptions) {
|
||||
// 구독이 해당 월에 활성화되어 있었는지 확인
|
||||
final subscriptionStartDate = subscription.nextBillingDate.subtract(
|
||||
Duration(days: _getBillingCycleDays(subscription.billingCycle)),
|
||||
);
|
||||
|
||||
if (subscriptionStartDate.isBefore(DateTime(month.year, month.month + 1, 1)) &&
|
||||
subscription.nextBillingDate.isAfter(month)) {
|
||||
// 해당 월의 비용 계산 (이벤트 가격 고려)
|
||||
if (subscription.isEventActive &&
|
||||
subscription.eventStartDate != null &&
|
||||
subscription.eventEndDate != null &&
|
||||
month.isAfter(subscription.eventStartDate!) &&
|
||||
month.isBefore(subscription.eventEndDate!)) {
|
||||
monthTotal += subscription.eventPrice ?? subscription.monthlyCost;
|
||||
} else {
|
||||
monthTotal += subscription.monthlyCost;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
monthlyData.add({
|
||||
'month': month,
|
||||
'totalExpense': monthTotal,
|
||||
'monthName': _getMonthLabel(month),
|
||||
});
|
||||
}
|
||||
|
||||
return monthlyData;
|
||||
}
|
||||
|
||||
/// 이벤트로 인한 총 절약액을 계산합니다.
|
||||
double calculateTotalSavings() {
|
||||
// 이미 존재하는 totalEventSavings getter를 사용
|
||||
return totalEventSavings;
|
||||
}
|
||||
|
||||
/// 결제 주기를 일 단위로 변환합니다.
|
||||
int _getBillingCycleDays(String billingCycle) {
|
||||
switch (billingCycle) {
|
||||
case 'monthly':
|
||||
return 30;
|
||||
case 'yearly':
|
||||
return 365;
|
||||
case 'weekly':
|
||||
return 7;
|
||||
case 'quarterly':
|
||||
return 90;
|
||||
default:
|
||||
return 30;
|
||||
}
|
||||
}
|
||||
|
||||
/// 월 라벨을 생성합니다.
|
||||
String _getMonthLabel(DateTime month) {
|
||||
final months = [
|
||||
'1월', '2월', '3월', '4월', '5월', '6월',
|
||||
'7월', '8월', '9월', '10월', '11월', '12월'
|
||||
];
|
||||
return months[month.month - 1];
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user