11using CommunityToolkit . Mvvm . ComponentModel ;
22using CommunityToolkit . Mvvm . Input ;
33using FinTrackForWindows . Dtos . AccountDtos ;
4+ using FinTrackForWindows . Dtos . TransactionDtos ;
45using FinTrackForWindows . Enums ;
56using FinTrackForWindows . Models . Account ;
67using FinTrackForWindows . Services . Api ;
8+ using LiveChartsCore ;
9+ using LiveChartsCore . Defaults ;
10+ using LiveChartsCore . SkiaSharpView ;
11+ using LiveChartsCore . SkiaSharpView . Painting ;
12+ using LiveChartsCore . SkiaSharpView . VisualElements ;
713using Microsoft . Extensions . Logging ;
14+ using SkiaSharp ;
815using System . Collections . ObjectModel ;
16+ using System . Linq ;
17+ using System . Threading . Tasks ;
918
1019namespace FinTrackForWindows . ViewModels
1120{
1221 public partial class AccountViewModel : ObservableObject
1322 {
1423 [ ObservableProperty ]
15- private ObservableCollection < AccountModel > accounts ;
24+ private ObservableCollection < AccountModel > accounts = new ( ) ;
1625
1726 [ ObservableProperty ]
1827 [ NotifyPropertyChangedFor ( nameof ( FormTitle ) ) ]
1928 [ NotifyPropertyChangedFor ( nameof ( SaveButtonText ) ) ]
2029 private AccountModel ? selectedAccount ;
2130
31+ public ObservableCollection < BaseCurrencyType > CurrencyTypes { get ; }
32+
33+ public ObservableCollection < AccountType > AccountTypes { get ; }
34+
2235 private readonly ILogger < AccountViewModel > _logger ;
2336
2437 public string FormTitle => IsEditing ? "Hesabı Düzenle" : "Yeni Hesap Ekle" ;
@@ -28,22 +41,78 @@ public partial class AccountViewModel : ObservableObject
2841
2942 private readonly IApiService _apiService ;
3043
44+ [ ObservableProperty ]
45+ private ISeries [ ] series = new ISeries [ 0 ] ;
46+
47+ [ ObservableProperty ]
48+ private Axis [ ] xAxes = new Axis [ 0 ] ;
49+
50+ [ ObservableProperty ]
51+ private Axis [ ] yAxes = new Axis [ 0 ] ;
52+
53+ [ ObservableProperty ]
54+ private LabelVisual title = new LabelVisual { /* Başlık için yer tutucu */ } ;
55+
3156 public AccountViewModel ( ILogger < AccountViewModel > logger , IApiService apiService )
3257 {
3358 _logger = logger ;
3459 _apiService = apiService ;
60+
61+ InitializeEmptyChart ( ) ;
3562 _ = LoadData ( ) ;
63+ _ = InitializeViewModel ( ) ;
3664 PrepareForNewAccount ( ) ;
65+
66+ CurrencyTypes = new ObservableCollection < BaseCurrencyType > ( ) ;
67+ AccountTypes = new ObservableCollection < AccountType > ( ) ;
68+
69+ CurrencyTypes . Clear ( ) ;
70+ foreach ( BaseCurrencyType currencyType in Enum . GetValues ( typeof ( BaseCurrencyType ) ) )
71+ {
72+ CurrencyTypes . Add ( currencyType ) ;
73+ }
74+ }
75+
76+ private void InitializeEmptyChart ( )
77+ {
78+ Series = new ISeries [ 0 ] ;
79+ Title = new LabelVisual
80+ {
81+ Text = "Verileri görmek için bir hesap seçin." ,
82+ TextSize = 18 ,
83+ Paint = new SolidColorPaint ( SKColors . Gray ) ,
84+ Padding = new LiveChartsCore . Drawing . Padding ( 15 )
85+ } ;
86+ }
87+
88+ private async Task InitializeViewModel ( )
89+ {
90+ await LoadData ( ) ;
91+ if ( Accounts . Any ( ) )
92+ {
93+ var firstAccount = Accounts . First ( ) ;
94+ if ( firstAccount . Id . HasValue )
95+ {
96+ SelectedAccount = firstAccount ;
97+ }
98+ }
3799 }
38100
39101 partial void OnSelectedAccountChanged ( AccountModel ? value )
40102 {
41103 _logger . LogInformation ( "Seçilen hesap değişti: {AccountName}" , value ? . Name ?? "Hiçbiri" ) ;
42-
43104 IsEditing = value != null && value . Id != null ;
44-
45105 OnPropertyChanged ( nameof ( FormTitle ) ) ;
46106 OnPropertyChanged ( nameof ( SaveButtonText ) ) ;
107+
108+ if ( value != null && value . Id . HasValue )
109+ {
110+ _ = LoadTransactionHistory ( value . Id . Value , value . Name ) ;
111+ }
112+ else
113+ {
114+ InitializeEmptyChart ( ) ;
115+ }
47116 }
48117
49118 private async Task LoadData ( )
@@ -59,44 +128,126 @@ private async Task LoadData()
59128 Id = item . Id ,
60129 Name = item . Name ,
61130 Type = item . Type ,
62- Balance = item . Balance ,
63- Currency = item . Currency . ToString ( ) ,
131+ balance = item . Balance ,
132+ Currency = item . Currency ,
64133 } ) ;
65134 }
66135 }
67136 }
68137
69- [ RelayCommand ]
70- private async Task SaveAccount ( )
138+ private async Task LoadTransactionHistory ( int accountId , string accountName )
71139 {
72- if ( SelectedAccount == null || string . IsNullOrWhiteSpace ( SelectedAccount . Name ) ) return ;
140+ var transactions = await _apiService . GetAsync < List < TransactionDto > > ( $ "Transactions/account-id/ { accountId } " ) ;
73141
74- if ( Enum . TryParse ( SelectedAccount . Currency , out BaseCurrencyType currency ) )
142+ if ( transactions == null || ! transactions . Any ( ) )
75143 {
76- _logger . LogInformation ( "Seçilen para birimi: {Currency}" , currency ) ;
77- }
78- else
79- {
80- _logger . LogWarning ( "Geçersiz para birimi: {Currency}" , SelectedAccount . Currency ) ;
144+ Series = new ISeries [ 0 ] ;
145+ Title = new LabelVisual
146+ {
147+ Text = "Veri yok." ,
148+ TextSize = 18 ,
149+ Paint = new SolidColorPaint ( SKColors . Gray ) ,
150+ Padding = new LiveChartsCore . Drawing . Padding ( 15 )
151+ } ;
81152 return ;
82153 }
83154
155+ var incomePoints = transactions
156+ . Where ( t => t . Category . Type == TransactionType . Income )
157+ . Select ( t => new DateTimePoint ( t . TransactionDateUtc , ( double ) t . Amount ) )
158+ . ToList ( ) ;
159+
160+ var expensePoints = transactions
161+ . Where ( t => t . Category . Type == TransactionType . Expense )
162+ . Select ( t => new DateTimePoint ( t . TransactionDateUtc , ( double ) t . Amount ) )
163+ . ToList ( ) ;
164+
165+ Series = new ISeries [ ]
166+ {
167+ new LineSeries < DateTimePoint >
168+ {
169+ Name = "Gelir" ,
170+ Values = incomePoints ,
171+ Stroke = new SolidColorPaint ( SKColors . MediumSpringGreen ) { StrokeThickness = 2 } ,
172+ GeometryStroke = new SolidColorPaint ( SKColors . MediumSpringGreen ) { StrokeThickness = 4 } ,
173+ Fill = new LinearGradientPaint ( SKColors . MediumSpringGreen . WithAlpha ( 90 ) , SKColors . MediumSpringGreen . WithAlpha ( 10 ) , new SKPoint ( 0.5f , 0 ) , new SKPoint ( 0.5f , 1 ) )
174+ } ,
175+ new LineSeries < DateTimePoint >
176+ {
177+ Name = "Gider" ,
178+ Values = expensePoints ,
179+ Stroke = new SolidColorPaint ( SKColors . IndianRed ) { StrokeThickness = 2 } ,
180+ GeometryStroke = new SolidColorPaint ( SKColors . IndianRed ) { StrokeThickness = 4 } ,
181+ Fill = new LinearGradientPaint ( SKColors . IndianRed . WithAlpha ( 90 ) , SKColors . IndianRed . WithAlpha ( 10 ) , new SKPoint ( 0.5f , 0 ) , new SKPoint ( 0.5f , 1 ) )
182+ }
183+ } ;
184+
185+ Title = new LabelVisual
186+ {
187+ Text = $ "{ accountName } - Hareketler",
188+ TextSize = 16 ,
189+ Paint = new SolidColorPaint ( SKColors . WhiteSmoke ) ,
190+ Padding = new LiveChartsCore . Drawing . Padding ( 15 )
191+ } ;
192+
193+ XAxes = new Axis [ ]
194+ {
195+ new Axis
196+ {
197+ Labeler = value =>
198+ {
199+ try
200+ {
201+ var ticks = ( long ) value ;
202+ if ( ticks >= DateTime . MinValue . Ticks && ticks <= DateTime . MaxValue . Ticks )
203+ {
204+ return new DateTime ( ticks ) . ToString ( "dd MMM" ) ;
205+ }
206+ return string . Empty ;
207+ }
208+ catch
209+ {
210+ return string . Empty ;
211+ }
212+ }
213+ ,
214+ LabelsPaint = new SolidColorPaint ( SKColors . LightGray ) ,
215+ UnitWidth = TimeSpan . FromDays ( 1 ) . Ticks ,
216+ MinStep = TimeSpan . FromDays ( 1 ) . Ticks
217+
218+ }
219+ } ;
220+
221+ YAxes = new Axis [ ]
222+ {
223+ new Axis
224+ {
225+ Labeler = value => value . ToString ( "C0" ) ,
226+ LabelsPaint = new SolidColorPaint ( SKColors . LightGray ) ,
227+ SeparatorsPaint = new SolidColorPaint ( SKColors . Gray ) { StrokeThickness = 0.5f }
228+ }
229+ } ;
230+ }
231+
232+ [ RelayCommand ]
233+ private async Task SaveAccount ( )
234+ {
235+ if ( SelectedAccount == null || string . IsNullOrWhiteSpace ( SelectedAccount . Name ) ) return ;
236+
84237 if ( IsEditing )
85238 {
86239 var existingAccount = Accounts . FirstOrDefault ( a => a . Id == SelectedAccount . Id ) ;
87240 if ( existingAccount != null )
88241 {
89242 existingAccount . Name = SelectedAccount . Name ;
90243 existingAccount . Type = SelectedAccount . Type ;
91- existingAccount . Balance = SelectedAccount . Balance ;
92244 existingAccount . Currency = SelectedAccount . Currency ;
93245
94246 await _apiService . PutAsync < object > ( $ "Account/{ SelectedAccount . Id } ", new AccountUpdateDto
95247 {
96248 Name = SelectedAccount . Name ,
97249 Type = SelectedAccount . Type ,
98- Balance = SelectedAccount . Balance ,
99- Currency = currency
250+ Currency = SelectedAccount . Currency
100251 } ) ;
101252 }
102253 }
@@ -107,8 +258,7 @@ private async Task SaveAccount()
107258 Name = SelectedAccount . Name ,
108259 Type = SelectedAccount . Type ,
109260 IsActive = true ,
110- Balance = SelectedAccount . Balance ,
111- Currency = currency ,
261+ Currency = SelectedAccount . Currency ,
112262 } ) ;
113263
114264 SelectedAccount . Id = newAccount . Id ;
0 commit comments