Files
Clario/Clario/Views/DashboardView.axaml
Nouredeen06 e9c155b272 - Fixed DateRangePicker when mode is singledate
- added Transaction Creation/Editing/Deletion
- added confirmation for transaction deletion
- added app icon
2026-03-28 14:56:54 +03:00

381 lines
31 KiB
XML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:vm="clr-namespace:Clario.ViewModels"
xmlns:lvc="using:LiveChartsCore.SkiaSharpView.Avalonia"
xmlns:model="clr-namespace:Clario.Models"
mc:Ignorable="d" d:DesignWidth="1180" d:DesignHeight="800"
MinWidth="780" MinHeight="600"
x:DataType="vm:DashboardViewModel"
x:Class="Clario.Views.DashboardView">
<Design.DataContext>
<vm:DashboardViewModel />
</Design.DataContext>
<Grid ColumnDefinitions="*">
<ScrollViewer Grid.Column="0" HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Auto" Name="mainScrollviewer">
<StackPanel Spacing="24" Margin="32,28,32,32">
<!-- Top Bar -->
<Grid ColumnDefinitions="*,Auto">
<StackPanel Grid.Column="0">
<TextBlock Classes="muted" Text="Friday, March 6, 2026" />
<TextBlock Text="Financial Overview" FontSize="{StaticResource FontSizePageTitle}" FontWeight="Bold"
Foreground="{DynamicResource TextPrimary}" Margin="0,2,0,0" />
</StackPanel>
<StackPanel Grid.Column="1" Orientation="Horizontal" Spacing="10" VerticalAlignment="Center">
<Border Background="{DynamicResource BgSurface}" CornerRadius="{StaticResource RadiusControl}"
BorderBrush="{DynamicResource BorderSubtle}" BorderThickness="1" Padding="14,8">
<StackPanel Orientation="Horizontal" Spacing="8">
<Svg Path="../Assets/Icons/calendar-days.svg" Height="13" Width="13" />
<TextBlock Text="Jan Mar 2026" FontSize="{StaticResource FontSizeBody}" Foreground="{DynamicResource TextSecondary}"
VerticalAlignment="Center" />
</StackPanel>
</Border>
<Button Background="{DynamicResource AccentBlue}" Foreground="{DynamicResource BgBase}" FontWeight="SemiBold"
FontSize="{StaticResource FontSizeBody}" CornerRadius="{StaticResource RadiusControl}" Padding="16,8" BorderThickness="0"
Cursor="Hand" Content="+ Add Transaction" Command="{Binding CreateTransactionCommand}" />
</StackPanel>
</Grid>
<!-- KPI Cards Row -->
<Grid ColumnDefinitions="*,*,*" HorizontalAlignment="Stretch" MaxHeight="160">
<Grid.Styles>
<Style Selector="Grid > Border">
<Setter Property="Margin" Value="0,0,16,0" />
</Style>
</Grid.Styles>
<!-- Monthly Income -->
<Border Grid.Column="0" Classes="card">
<StackPanel Spacing="12">
<StackPanel Orientation="Horizontal" Spacing="8">
<Border Background="{DynamicResource IconBgGreen}" CornerRadius="{StaticResource RadiusIcon}" Padding="7">
<Svg Path="../Assets/Icons/trending-up.svg" Height="14" Width="14" Css="{DynamicResource SvgGreen}" />
</Border>
<TextBlock Classes="label" Text="MONTHLY INCOME" VerticalAlignment="Center" />
</StackPanel>
<TextBlock Text="{Binding MonthlyIncome, StringFormat='$0.00'}" FontSize="{StaticResource FontSizePageTitle}" FontWeight="Bold"
Foreground="{DynamicResource TextPrimary}" />
<StackPanel Orientation="Horizontal" Spacing="6">
<Border Classes="badge-green">
<TextBlock Text="{Binding MonthlyIncomeChangeFormatted}" FontSize="{StaticResource FontSizeLabel}" FontWeight="SemiBold"
Foreground="{DynamicResource AccentGreen}" />
</Border>
<TextBlock Classes="muted" Text="vs last month" VerticalAlignment="Center" />
</StackPanel>
</StackPanel>
</Border>
<!-- Monthly Expenses -->
<Border Grid.Column="1" Classes="card">
<StackPanel Spacing="12">
<StackPanel Orientation="Horizontal" Spacing="8">
<Border Background="{DynamicResource IconBgOrange}" CornerRadius="{StaticResource RadiusIcon}" Padding="7">
<Svg Path="../Assets/Icons/trending-down.svg" Height="14" Width="14" Css="{DynamicResource SvgRed}" />
</Border>
<TextBlock Classes="label" Text="MONTHLY EXPENSES" VerticalAlignment="Center" />
</StackPanel>
<TextBlock Text="{Binding MonthlyExpenses, StringFormat='$0.00'}" FontSize="{StaticResource FontSizePageTitle}" FontWeight="Bold"
Foreground="{DynamicResource TextPrimary}" />
<StackPanel Orientation="Horizontal" Spacing="6">
<Border Classes="badge-red">
<TextBlock Text="{Binding MonthlyExpenseChangeFormatted}" FontSize="{StaticResource FontSizeLabel}" FontWeight="SemiBold"
Foreground="{DynamicResource AccentRed}" />
</Border>
<TextBlock Classes="muted" Text="vs last month" VerticalAlignment="Center" />
</StackPanel>
</StackPanel>
</Border>
<!-- Savings Rate -->
<Border Grid.Column="2" Classes="card" Margin="0">
<StackPanel Spacing="12">
<StackPanel Orientation="Horizontal" Spacing="8">
<Border Background="{DynamicResource IconBgPurple}" CornerRadius="{StaticResource RadiusIcon}" Padding="7">
<Svg Path="../Assets/Icons/landmark.svg" Height="14" Width="14" Css="{DynamicResource SvgPurple}" />
</Border>
<TextBlock Classes="label" Text="SAVINGS RATE" VerticalAlignment="Center" />
</StackPanel>
<TextBlock FontSize="{StaticResource FontSizePageTitle}" FontWeight="Bold" Foreground="{DynamicResource TextPrimary}">
<TextBlock.Text>
<MultiBinding Converter="{StaticResource PercentageConverter}">
<Binding Path="MonthlyExpenses" /> <Binding Path="MonthlyIncome" />
</MultiBinding>
</TextBlock.Text>
</TextBlock>
<ProgressBar Classes="green" Minimum="0" Maximum="{Binding MonthlyIncome}" Value="{Binding MonthlyExpenses}" />
</StackPanel>
</Border>
</Grid>
<!-- Mid Row: Spending Chart + Budget -->
<Grid ColumnDefinitions="*,340" MaxHeight="470">
<!-- Spending Breakdown -->
<Border Grid.Column="0" Classes="card" Margin="0,0,16,0">
<StackPanel Spacing="20">
<Grid ColumnDefinitions="*,Auto">
<StackPanel Grid.Column="0">
<TextBlock Text="Spending by Category" FontSize="{StaticResource FontSizeSectionHeading}" FontWeight="SemiBold"
Foreground="{DynamicResource TextPrimary}" />
<TextBlock Classes="muted" Text="March 2026" />
</StackPanel>
<ComboBox Grid.Column="1" SelectedIndex="0" ItemsSource="{Binding ChartTimePeriods}"
SelectedItem="{Binding SelectedChartTimePeriod}" Background="{DynamicResource BgHover}"
Foreground="{DynamicResource TextSecondary}" BorderBrush="{DynamicResource BorderAccent}"
CornerRadius="{StaticResource RadiusIcon}" Padding="10,6">
</ComboBox>
</Grid>
<Panel>
<StackPanel Spacing="20" IsVisible="{Binding HasSpendingData}">
<lvc:CartesianChart Series="{Binding SpendingByCategoryChartSeries}" Height="250" Background="{DynamicResource BgSurface}"
LegendPosition="Hidden" TooltipPosition="Hidden" ZoomMode="None" Name="chart">
<lvc:CartesianChart.XAxes>
<lvc:XamlAxis IsVisible="False" />
</lvc:CartesianChart.XAxes>
<lvc:CartesianChart.YAxes>
<lvc:XamlLogarithmicAxis LogBase="10" IsVisible="False" MinLimit="1" />
</lvc:CartesianChart.YAxes>
</lvc:CartesianChart>
<ItemsControl ItemsSource="{Binding SpendingByCategoryChartData}" Margin="0 -10 ">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Rows="1" HorizontalAlignment="Stretch" MaxWidth="{Binding MaxChartWidth}" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate x:DataType="model:ColumnChartData">
<TextBlock Text="{Binding Name}" HorizontalAlignment="Center" Foreground="{DynamicResource TextDisabled}"
Margin="4 0" TextTrimming="CharacterEllipsis" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<Border HorizontalAlignment="Stretch" Height="1" Background="{DynamicResource BorderSubtle}" Margin="5 0" />
<ItemsControl ItemsSource="{Binding SpendingByCategoryChartData}" Margin="0 -10 0 0 ">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Rows="1" HorizontalAlignment="Stretch" MaxWidth="{Binding MaxChartWidth}" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate x:DataType="model:ColumnChartData">
<TextBlock Text="{Binding Values, Converter={StaticResource FirstValueConverter},StringFormat='$0'}"
HorizontalAlignment="Center" Margin="4 0" TextTrimming="CharacterEllipsis"
Foreground="{Binding Fill, Converter={StaticResource SkPaintToBrushConverter}}"
FontWeight="SemiBold" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center" Spacing="12" Margin="0,60"
IsVisible="{Binding !HasSpendingData}">
<Svg Path="../Assets/Icons/chart-column.svg" Css="{DynamicResource SvgDisabled}" Height="40" Width="40" />
<TextBlock Text="No spending data" FontSize="15" FontWeight="SemiBold"
Foreground="{DynamicResource TextDisabled}" HorizontalAlignment="Center" />
<TextBlock Text="Add expense transactions to see your spending breakdown." FontSize="13"
Foreground="{DynamicResource TextDisabled}" HorizontalAlignment="Center" TextWrapping="Wrap"
TextAlignment="Center"
MaxWidth="250" />
</StackPanel>
</Panel>
</StackPanel>
</Border>
<!-- Budget Tracker -->
<Border Grid.Column="1" Classes="card">
<ScrollViewer Padding="12 0" Margin="-12 0">
<StackPanel Spacing="20">
<StackPanel>
<TextBlock Text="Budget Tracker" FontSize="{StaticResource FontSizeSectionHeading}" FontWeight="SemiBold"
Foreground="{DynamicResource TextPrimary}" />
<TextBlock Classes="muted" Text="Monthly limits" />
</StackPanel>
<Panel>
<ItemsControl ItemsSource="{Binding BudgetsTrackerData}" IsVisible="{Binding HasBudgetData}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Spacing="20" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate DataType="model:Budget">
<StackPanel Spacing="8">
<Grid ColumnDefinitions="*,Auto">
<StackPanel Grid.Column="0" Orientation="Horizontal" Spacing="4">
<Svg Path="{Binding Category.Icon, Converter={StaticResource SvgPathFromName}}" Height="13"
Width="13"
VerticalAlignment="Center" />
<TextBlock Text="{Binding Category.Name}" FontSize="{StaticResource FontSizeBody}"
VerticalAlignment="Center" Foreground="{DynamicResource TextSecondary}" />
</StackPanel>
<Panel Grid.Column="1">
<StackPanel Orientation="Horizontal" IsVisible="{Binding !IsOverBudget}">
<TextBlock Text="{Binding Spent, StringFormat='$0'}" FontSize="{StaticResource FontSizeMeta}"
Foreground="{DynamicResource TextMuted}" />
<TextBlock Text=" / " FontSize="{StaticResource FontSizeMeta}"
Foreground="{DynamicResource TextMuted}" />
<TextBlock Text="{Binding LimitAmount, StringFormat='$0'}"
FontSize="{StaticResource FontSizeMeta}"
Foreground="{DynamicResource TextMuted}" />
</StackPanel>
<StackPanel Orientation="Horizontal" IsVisible="{Binding IsOverBudget}">
<TextBlock Text="{Binding Spent, StringFormat='$0'}" FontSize="{StaticResource FontSizeMeta}"
Foreground="{DynamicResource AccentRed}" />
<TextBlock Text=" / " FontSize="{StaticResource FontSizeMeta}"
Foreground="{DynamicResource AccentRed}" />
<TextBlock Text="{Binding LimitAmount, StringFormat='$0'}"
FontSize="{StaticResource FontSizeMeta}"
Foreground="{DynamicResource AccentRed}" />
</StackPanel>
</Panel>
</Grid>
<ProgressBar Classes.green="{Binding IsOnTrack}" Classes.yellow="{Binding IsWarning}"
Classes.red="{Binding IsOverBudget}" Minimum="0" Value="{Binding Spent}"
Maximum="{Binding LimitAmount}" />
<Separator Margin="-8 4" />
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center" Spacing="12" Margin="0,60"
IsVisible="{Binding !HasBudgetData}">
<Svg Path="../Assets/Icons/wallet.svg" Css="{DynamicResource SvgDisabled}" Height="40" Width="40" />
<TextBlock Text="No budgets set" FontSize="15" FontWeight="SemiBold"
Foreground="{DynamicResource TextDisabled}" HorizontalAlignment="Center" />
<TextBlock Text="Create budgets to track your spending limits." FontSize="13"
Foreground="{DynamicResource TextDisabled}" HorizontalAlignment="Center" TextWrapping="Wrap"
TextAlignment="Center" MaxWidth="200" />
</StackPanel>
</Panel>
</StackPanel>
</ScrollViewer>
</Border>
</Grid>
<!-- Bottom Row: Recent Transactions + Accounts -->
<Grid ColumnDefinitions="*,300" MaxHeight="500">
<!-- Recent Transactions -->
<Border Grid.Column="0" Classes="card" Margin="0,0,16,0">
<StackPanel Spacing="18">
<Grid ColumnDefinitions="*,Auto">
<StackPanel Grid.Column="0">
<TextBlock Text="Recent Transactions" FontSize="{StaticResource FontSizeSectionHeading}" FontWeight="SemiBold"
Foreground="{DynamicResource TextPrimary}" />
<TextBlock Classes="muted" Text="Last 5 transactions" />
</StackPanel>
<Button Grid.Column="1" Background="Transparent" Foreground="{DynamicResource AccentBlue}" BorderThickness="0"
FontSize="{StaticResource FontSizeBody}" Cursor="Hand" Content="View all →" VerticalAlignment="Center"
Command="{Binding ViewAllTransactionsCommand}" />
</Grid>
<Panel>
<ItemsControl ItemsSource="{Binding RecentTransactions}" IsVisible="{Binding HasTransactionData}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Spacing="18" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate DataType="model:Transaction">
<StackPanel Spacing="4">
<Grid ColumnDefinitions="Auto,*,Auto" Margin="0,4,0,0">
<Border Grid.Column="0" CornerRadius="{StaticResource RadiusControl}" Width="42" Height="42"
Margin="0,0,14,0">
<Border.Background>
<SolidColorBrush
Color="{Binding Category.Color, Converter={StaticResource HexToColorConverter},ConverterParameter=color}"
Opacity="0.15" />
</Border.Background>
<Svg Path="{Binding Category.Icon,Converter={StaticResource SvgPathFromName}}" Height="18" Width="18"
Css="{Binding Category.Color, Converter={StaticResource HexToColorConverter},ConverterParameter=css}" />
</Border>
<StackPanel Grid.Column="1" VerticalAlignment="Center">
<TextBlock Text="{Binding Description}" FontSize="{StaticResource FontSizeBody}" FontWeight="SemiBold"
Foreground="{DynamicResource TextSecondary}" />
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Category.Name}" Classes="muted" />
<TextBlock Text=" · " Classes="muted" />
<TextBlock
Text="{Binding Date,Converter={StaticResource DateFormatConverter},ConverterParameter='MMM d'}"
Classes="muted" />
</StackPanel>
</StackPanel>
<TextBlock Grid.Column="2" FontSize="{StaticResource FontSizeAmount}" FontWeight="SemiBold"
Foreground="{Binding Type, Converter={StaticResource AmountColorConverter}}"
VerticalAlignment="Center">
<TextBlock.Text>
<MultiBinding Converter="{StaticResource AmountSignConverter}">
<Binding Path="Amount" /> <Binding Path="Type" />
</MultiBinding>
</TextBlock.Text>
</TextBlock>
</Grid>
<Separator />
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center" Spacing="12" Margin="0,60"
IsVisible="{Binding !HasTransactionData}">
<Svg Path="../Assets/Icons/receipt.svg" Css="{DynamicResource SvgDisabled}" Height="40" Width="40" />
<TextBlock Text="No transactions yet" FontSize="15" FontWeight="SemiBold"
Foreground="{DynamicResource TextDisabled}" HorizontalAlignment="Center" />
<TextBlock Text="Start tracking your finances by adding a transaction." FontSize="13"
Foreground="{DynamicResource TextDisabled}" HorizontalAlignment="Center" TextWrapping="Wrap"
TextAlignment="Center"
MaxWidth="250" />
</StackPanel>
</Panel>
</StackPanel>
</Border>
<!-- Accounts Summary -->
<Border Grid.Column="1" Classes="card">
<Grid RowDefinitions="Auto,*,Auto" RowSpacing="18">
<StackPanel Grid.Row="0">
<TextBlock Text="Accounts" FontSize="{StaticResource FontSizeSectionHeading}" FontWeight="SemiBold"
Foreground="{DynamicResource TextPrimary}" />
<TextBlock Classes="muted" Text="{Binding AccountsSubtitle}" />
</StackPanel>
<ItemsControl ItemsSource="{Binding AccountsSummaryData}" Grid.Row="1">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Spacing="18" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate DataType="model:Account">
<Border Background="{DynamicResource BgBase}" CornerRadius="{StaticResource RadiusInset}" Padding="14,12"
BorderBrush="{DynamicResource BorderSubtle}" BorderThickness="1">
<Grid ColumnDefinitions="Auto,*,Auto">
<Border Grid.Column="0" CornerRadius="{StaticResource RadiusIcon}" Width="36" Height="36" Margin="0,0,12,0">
<Border.Background>
<SolidColorBrush
Color="{Binding Color, Converter={StaticResource HexToColorConverter}, ConverterParameter=color}"
Opacity="0.15" />
</Border.Background>
<Svg Path="{Binding Icon, Converter={StaticResource SvgPathFromName}}" Height="16" Width="16"
Css="{Binding Color, Converter={StaticResource HexToColorConverter}, ConverterParameter=css}" />
</Border>
<StackPanel Grid.Column="1" VerticalAlignment="Center">
<TextBlock Text="{Binding Name}" FontSize="{StaticResource FontSizeMeta}" FontWeight="SemiBold"
Foreground="{DynamicResource TextSecondary}" />
<TextBlock Text="{Binding Mask, Converter={StaticResource MaskToStringConverter}}"
FontSize="{StaticResource FontSizeLabel}" Classes="muted" />
</StackPanel>
<TextBlock Grid.Column="2" Text="{Binding CurrentBalance, StringFormat='$0'}"
FontSize="{StaticResource FontSizeBody}" FontWeight="Bold"
Foreground="{DynamicResource TextPrimary}" VerticalAlignment="Center" />
</Grid>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<StackPanel Spacing="18" Grid.Row="2">
<Separator />
<Grid ColumnDefinitions="*,Auto">
<TextBlock Grid.Column="0" Text="Total Balance" FontSize="{StaticResource FontSizeBody}" FontWeight="SemiBold"
Foreground="{DynamicResource TextMuted}" />
<TextBlock Grid.Column="1" Text="{Binding TotalNetworth, StringFormat=$0}"
FontSize="{StaticResource FontSizeSectionHeading}" FontWeight="Bold" Foreground="{DynamicResource TextPrimary}" />
</Grid>
</StackPanel>
</Grid>
</Border>
</Grid>
</StackPanel>
</ScrollViewer>
</Grid>
</UserControl>