Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added FinTrack/Assets/Images/Icons/calendar.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added FinTrack/Assets/Images/Icons/credit-card.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added FinTrack/Assets/Images/Icons/investment.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
17 changes: 12 additions & 5 deletions FinTrack/Core/SecureTokenStorage.cs
Original file line number Diff line number Diff line change
@@ -1,17 +1,22 @@
using System.IO;
using Microsoft.Extensions.Logging;
using System.IO;
using System.Security.Cryptography;
using System.Text;

namespace FinTrack.Core
{
public class SecureTokenStorage : ISecureTokenStorage
{
private readonly ILogger<SecureTokenStorage> _logger;

private readonly string _filePath;

private static readonly byte[] s_entropy = Encoding.UTF8.GetBytes("E5A3B8B8_4A8C_4F1D_9F0B_2B3A7F9C1D0E"); // [TEST]

public SecureTokenStorage()
public SecureTokenStorage(ILogger<SecureTokenStorage> logger)
{
_logger = logger;

var appDataPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
var appFolder = Path.Combine(appDataPath, "FinTrack");
Directory.CreateDirectory(appFolder);
Expand All @@ -27,10 +32,11 @@ public void SaveToken(string token)
{
var encryptedToken = ProtectedData.Protect(Encoding.UTF8.GetBytes(token), s_entropy, DataProtectionScope.CurrentUser);
File.WriteAllBytes(_filePath, encryptedToken);
_logger.LogInformation("Token başarıyla kaydedildi.");
}
catch (Exception ex)
{
Console.WriteLine($"Error saving token: {ex.Message}");
_logger.LogError(ex, "Token 'ı kaydederken hata oluştu.");
throw;
}
}
Expand All @@ -48,7 +54,7 @@ public void SaveToken(string token)
}
catch (Exception ex)
{
Console.WriteLine($"Error retrieving token: {ex.Message}");
_logger.LogError(ex, "Token 'ı alırken hata oluştu.");
ClearToken();
return null;
}
Expand All @@ -61,10 +67,11 @@ public void ClearToken()
try
{
File.Delete(_filePath);
_logger.LogInformation("Token başarıyla temizlendi.");
}
catch (Exception ex)
{
Console.WriteLine($"Error clearing token: {ex.Message}");
_logger.LogError(ex, "Token 'ı temizlerken hata oluştu.");
}
}
}
Expand Down
6 changes: 6 additions & 0 deletions FinTrack/FinTrack.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,16 @@
<None Remove="Assets\Images\Icons\add.png" />
<None Remove="Assets\Images\Icons\bank.png" />
<None Remove="Assets\Images\Icons\bell.png" />
<None Remove="Assets\Images\Icons\calendar.png" />
<None Remove="Assets\Images\Icons\conversation.png" />
<None Remove="Assets\Images\Icons\credit-card.png" />
<None Remove="Assets\Images\Icons\delete.png" />
<None Remove="Assets\Images\Icons\done.png" />
<None Remove="Assets\Images\Icons\edit.png" />
<None Remove="Assets\Images\Icons\email.png" />
<None Remove="Assets\Images\Icons\eyeclose.png" />
<None Remove="Assets\Images\Icons\eyeopen.png" />
<None Remove="Assets\Images\Icons\investment.png" />
<None Remove="Assets\Images\Icons\login.png" />
<None Remove="Assets\Images\Icons\message.png" />
<None Remove="Assets\Images\Icons\money.png" />
Expand Down Expand Up @@ -73,8 +76,11 @@
<Resource Include="Assets\Images\Icons\add.png" />
<Resource Include="Assets\Images\Icons\bank.png" />
<Resource Include="Assets\Images\Icons\bell.png" />
<Resource Include="Assets\Images\Icons\calendar.png" />
<Resource Include="Assets\Images\Icons\credit-card.png" />
<Resource Include="Assets\Images\Icons\delete.png" />
<Resource Include="Assets\Images\Icons\edit.png" />
<Resource Include="Assets\Images\Icons\investment.png" />
<Resource Include="Assets\Images\Icons\money.png" />
<Resource Include="Assets\Images\Icons\report.png" />
<Resource Include="Assets\Images\Icons\send-message.png" />
Expand Down
6 changes: 3 additions & 3 deletions FinTrack/Models/Account/AccountModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ public partial class AccountModel : ObservableObject
private Guid id = Guid.NewGuid();

[ObservableProperty]
private string name;
private string name = string.Empty;

[ObservableProperty]
private AccountType type;
Expand All @@ -30,9 +30,9 @@ public partial class AccountModel : ObservableObject
public string IconPath => Type switch
{
AccountType.Checking => "/Assets/Images/Icons/bank.png",
AccountType.CreditCard => "/Assets/Images/Icons/credit_card.png",
AccountType.CreditCard => "/Assets/Images/Icons/credit-card.png",
AccountType.Loan => "/Assets/Images/Icons/investment.png",
_ => string.Empty
_ => "/Assets/Images/Icons/money.png"
};

public Brush IconBackground => Type switch
Expand Down
12 changes: 12 additions & 0 deletions FinTrack/Models/Currency/CurrencyModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,18 @@ public partial class CurrencyModel : ObservableObject
[NotifyPropertyChangedFor(nameof(ToCurrencyChangeForeground))]
private CurrencyConversionType type = CurrencyConversionType.Increase;

[ObservableProperty]
private string dailyLow = string.Empty;

[ObservableProperty]
private string dailyHigh = string.Empty;

[ObservableProperty]
private string weeklyChange = string.Empty;

[ObservableProperty]
private string monthlyChange = string.Empty;

private static readonly Brush IncreaseBrush = new SolidColorBrush(Colors.Green);
private static readonly Brush DecreaseBrush = new SolidColorBrush(Colors.Red);
private static readonly Brush DefaultBrush = new SolidColorBrush(Colors.Gray);
Expand Down
6 changes: 4 additions & 2 deletions FinTrack/Models/Dashboard/DebtDashboard.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
namespace FinTrack.Models.Dashboard
using System.Windows.Media;

namespace FinTrack.Models.Dashboard
{
public class DebtDashboard
{
Expand All @@ -7,7 +9,7 @@ public class DebtDashboard
public string BorrowerName { get; set; } = string.Empty;
public string BorrowerIconPath { get; set; } = string.Empty;
public string Status { get; set; } = string.Empty;
public string StatusBrush { get; set; } = string.Empty;
public Brush StatusBrush { get; set; } = Brushes.Transparent;
public string Amount { get; set; } = string.Empty;
public string CreationDate { get; set; } = string.Empty;
public string DueDate { get; set; } = string.Empty;
Expand Down
9 changes: 0 additions & 9 deletions FinTrack/Models/Dashboard/ReportDashboard.cs

This file was deleted.

39 changes: 39 additions & 0 deletions FinTrack/Models/Dashboard/ReportDashboardModel.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using FinTrack.Enums;
using Microsoft.Extensions.Logging;
using System.Collections.ObjectModel;
using System.Windows;

namespace FinTrack.Models.Dashboard
{
public partial class ReportDashboardModel : ObservableObject
{
[ObservableProperty]
private string name = string.Empty;

public ObservableCollection<ExportFormat> Formats { get; set; }

private readonly ILogger<ReportDashboardModel> _logger;

public ReportDashboardModel(ILogger<ReportDashboardModel> logger)
{
_logger = logger;

Formats = new ObservableCollection<ExportFormat>();

foreach (ExportFormat exportFormat in Enum.GetValues(typeof(ExportFormat)))
{
Formats.Add(exportFormat);
}
}

[RelayCommand]
private void Generate(ExportFormat format)
{

_logger.LogInformation("Rapor oluşturuluyor -> Rapor Adı: {ReportName}, Format: {Format}", this.Name, format);
MessageBox.Show($"Rapor oluşturuldu:\nAd: {this.Name}\nFormat: {format}", "Rapor Oluşturma", MessageBoxButton.OK, MessageBoxImage.Information);
}
}
}
6 changes: 3 additions & 3 deletions FinTrack/Models/Notification/NotificationModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,18 @@ public partial class NotificationModel : ObservableObject
private NotificationType type;

[ObservableProperty]
[NotifyPropertyChangedFor(nameof(isUnread))]
[NotifyPropertyChangedFor(nameof(IsUnread))]
private bool isRead = false;

public bool isUnread => !IsRead;
public bool IsUnread => !IsRead;

public NotificationModel(string title, string message, string? timestamp, NotificationType type, bool _isRead = false)
{
Title = title;
Message = message;
Type = type;
Timestamp = timestamp ?? DateTime.Now.ToString();
isRead = _isRead;
IsRead = _isRead;
}
}
}
6 changes: 2 additions & 4 deletions FinTrack/Services/Api/ApiService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,8 @@
private readonly HttpClient _httpClient;
private readonly ILogger<ApiService> _logger;
private readonly JsonSerializerOptions _jsonSerializerOptions;
private readonly ISecureTokenStorage _secureTokenStorage;

public ApiService(ILogger<ApiService> logger, ISecureTokenStorage secureTokenStorage)
public ApiService(ILogger<ApiService> logger)
{
_baseUrl = "http://localhost:5000/api/";
_httpClient = new HttpClient
Expand All @@ -24,7 +23,6 @@
_httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

_logger = logger;
_secureTokenStorage = secureTokenStorage;

_jsonSerializerOptions = new JsonSerializerOptions
{
Expand All @@ -34,7 +32,7 @@

private void AddAuthorizationHeader()
{
string token = _secureTokenStorage.GetToken() ?? "null";
string token = SessionManager.CurrentToken;
if (!string.IsNullOrEmpty(token))
{
_httpClient.DefaultRequestHeaders.Authorization = null;
Expand All @@ -42,7 +40,7 @@
}
}

public async Task<T?> DeleteAsync<T>(string endpoint)

Check warning on line 43 in FinTrack/Services/Api/ApiService.cs

View workflow job for this annotation

GitHub Actions / build-and-test

Nullability of reference types in return type of 'Task<T?> ApiService.DeleteAsync<T>(string endpoint)' doesn't match implicitly implemented member 'Task<T> IApiService.DeleteAsync<T>(string endpoint)'.
{
_logger.LogInformation("DELETE isteği başlatılıyor: {Endpoint}", endpoint);
if (string.IsNullOrWhiteSpace(endpoint))
Expand Down Expand Up @@ -76,7 +74,7 @@
}
}

public async Task<T?> GetAsync<T>(string endpoint)

Check warning on line 77 in FinTrack/Services/Api/ApiService.cs

View workflow job for this annotation

GitHub Actions / build-and-test

Nullability of reference types in return type of 'Task<T?> ApiService.GetAsync<T>(string endpoint)' doesn't match implicitly implemented member 'Task<T> IApiService.GetAsync<T>(string endpoint)'.
{
_logger.LogInformation("GET isteği başlatılıyor: {Endpoint}", endpoint);
try
Expand Down Expand Up @@ -109,7 +107,7 @@
}
}

public async Task<T?> PostAsync<T>(string endpoint, object data)

Check warning on line 110 in FinTrack/Services/Api/ApiService.cs

View workflow job for this annotation

GitHub Actions / build-and-test

Nullability of reference types in return type of 'Task<T?> ApiService.PostAsync<T>(string endpoint, object data)' doesn't match implicitly implemented member 'Task<T> IApiService.PostAsync<T>(string endpoint, object data)'.
{
_logger.LogInformation("POST isteği başlatılıyor: {Endpoint}", endpoint);
if (string.IsNullOrWhiteSpace(endpoint))
Expand Down Expand Up @@ -151,7 +149,7 @@
}
}

public async Task<T?> PutAsync<T>(string endpoint, object data)

Check warning on line 152 in FinTrack/Services/Api/ApiService.cs

View workflow job for this annotation

GitHub Actions / build-and-test

Nullability of reference types in return type of 'Task<T?> ApiService.PutAsync<T>(string endpoint, object data)' doesn't match implicitly implemented member 'Task<T> IApiService.PutAsync<T>(string endpoint, object data)'.
{
_logger.LogInformation("PUT isteği başlatılıyor: {Endpoint}", endpoint);
if (string.IsNullOrWhiteSpace(endpoint))
Expand Down
14 changes: 13 additions & 1 deletion FinTrack/ViewModels/ApplicationRecognizeSlideViewModel.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using FinTrack.Core;
using Microsoft.Extensions.Logging;

namespace FinTrack.ViewModels
{
Expand Down Expand Up @@ -94,10 +96,17 @@ Your financial advisor is now available 24/7.
}
};

private readonly ILogger<ApplicationRecognizeSlideViewModel> _logger;

private readonly ISecureTokenStorage _secureToken;

private int currentSlideIndex = 0;

public ApplicationRecognizeSlideViewModel()
public ApplicationRecognizeSlideViewModel(ILogger<ApplicationRecognizeSlideViewModel> logger, ISecureTokenStorage secureToken)
{
_logger = logger;
_secureToken = secureToken;

UpdateCurrentSlide(CurrentSlide);
}

Expand All @@ -108,6 +117,7 @@ public void Back_ApplicationRecognizeSlideView_Button()
{
currentSlideIndex--;
UpdateCurrentSlide(CurrentSlide);
_logger.LogInformation("Kullanıcı geri düğmesine bastı. Şu anki slayt: {CurrentSlideTitle}", CurrentSlide.Title);
}
}

Expand All @@ -117,13 +127,15 @@ public void Next_ApplicationRecognizeSlideView_Button()
if (currentSlideIndex < applicationRecognizeSlides.Count - 1)
{
currentSlideIndex++;
_logger.LogInformation("Kullanıcı ileri düğmesine bastı. Şu anki slayt: {CurrentSlideTitle}", CurrentSlide.Title);
UpdateCurrentSlide(CurrentSlide);
}
}

[RelayCommand]
public void Skip_ApplicationRecognizeSlideView_Button()
{
_logger.LogInformation("Kullanıcı uygulama tanıtımını atladı. Giriş ekranına yönlendiriliyor.");
NavigateToLoginRequested?.Invoke();
}

Expand Down
49 changes: 48 additions & 1 deletion FinTrack/ViewModels/AuthenticatorViewModel.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Messaging;
using FinTrack.Core;
using FinTrack.Messages;
using Microsoft.Extensions.Logging;
using System.Windows;

namespace FinTrack.ViewModels
{
Expand All @@ -13,12 +18,18 @@ public partial class AuthenticatorViewModel : ObservableObject
private readonly ForgotPasswordViewModel _forgotPasswordViewModel;
private readonly ApplicationRecognizeSlideViewModel _applicationRecognizeSlideViewModel;

private readonly ISecureTokenStorage _secureToken;

private readonly ILogger<AuthenticatorViewModel> _logger;

public AuthenticatorViewModel(
LoginViewModel loginViewModel,
RegisterViewModel registerViewModel,
OtpVerificationViewModel otpVerificationViewModel,
ForgotPasswordViewModel forgotPasswordViewModel,
ApplicationRecognizeSlideViewModel applicationRecognizeSlideViewModel)
ApplicationRecognizeSlideViewModel applicationRecognizeSlideViewModel,
ISecureTokenStorage secureToken,
ILogger<AuthenticatorViewModel> logger)
{
_loginViewModel = loginViewModel;
_registerViewModel = registerViewModel;
Expand All @@ -41,6 +52,42 @@ public AuthenticatorViewModel(
_forgotPasswordViewModel.NavigateToLoginRequested += () => CurrentViewModel = _loginViewModel;

CurrentViewModel = _applicationRecognizeSlideViewModel;

_registerViewModel.SendOtpVerificationRequested += OnSendOtpVerificationRequested;

_logger = logger;
_secureToken = secureToken;

SavedTokenLogin();
}

private void OnSendOtpVerificationRequested(object? sender, EventArgs e)
{
_otpVerificationViewModel.StartCounter();
}

private void SavedTokenLogin()
{
string? token = _secureToken.GetToken();
if (token is not null)
{
bool isValid = TokenValidator.IsTokenValid(token);
if (!isValid)
{
MessageBox.Show("Token geçersiz. Lütfen tekrar giriş yapın.", "Hata", MessageBoxButton.OK, MessageBoxImage.Error);
_logger.LogWarning("Geçersiz token bulundu. Kullanıcıdan yeni giriş yapması istendi.");
SessionManager.ClearToken();
_secureToken.ClearToken();
}

SessionManager.SetToken(token);
_logger.LogInformation("Kullanıcı zaten giriş yapmış. Token kullanıldı.");
WeakReferenceMessenger.Default.Send(new LoginSuccessMessage());
}
else
{
_logger.LogInformation("Kullanıcı henüz giriş yapmamış. Uygulama tanıtım slaytları gösteriliyor.");
}
}
}
}
Loading
Loading