Initial Commit

This commit is contained in:
2026-03-19 04:03:19 +03:00
commit 9704f9f36d
170 changed files with 8322 additions and 0 deletions

View File

@@ -0,0 +1,373 @@
<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:model="clr-namespace:Clario.Models"
x:DataType="vm:AccountsViewModel"
mc:Ignorable="d" d:DesignWidth="1180" d:DesignHeight="800"
x:Class="Clario.Views.AccountsView"
x:Name="AccountsPage">
<Design.DataContext>
<vm:AccountsViewModel />
</Design.DataContext>
<Grid RowDefinitions="Auto,*" Margin="32,28,32,0">
<!-- TOP BAR -->
<Grid Grid.Row="0" ColumnDefinitions="*,Auto" Margin="0,0,0,24">
<StackPanel Grid.Column="0">
<TextBlock Text="4 accounts" FontSize="12" Foreground="{DynamicResource TextMuted}" />
<TextBlock Text="Accounts" FontSize="26" FontWeight="Bold" Foreground="{DynamicResource TextPrimary}" Margin="0,2,0,0" />
</StackPanel>
<Button Grid.Column="1" Classes="accented" Padding="16,9" VerticalAlignment="Center">
<StackPanel Orientation="Horizontal" Spacing="8">
<Svg Path="../Assets/Icons/plus.svg" Width="14" Height="14"
Css="path, circle, rect, ellipse, line, polyline, polygon, text, use { stroke: #0D0F14; }" />
<TextBlock Text="Add Account" FontSize="13" FontWeight="SemiBold" Foreground="{DynamicResource BgBase}" VerticalAlignment="Center" />
</StackPanel>
</Button>
</Grid>
<!-- MAIN CONTENT Left * — account cards list Right 340 — selected account detail panel -->
<Grid Grid.Row="1" ColumnDefinitions="*,Auto">
<!-- LEFT — Account Cards -->
<Grid Grid.Column="0" RowDefinitions="*,Auto">
<ScrollViewer Grid.Row="0" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled" Margin="0,0,20,0" Padding="8 0">
<StackPanel Spacing="12" Margin="0 0 0 28">
<Border BorderBrush="{DynamicResource BorderSubtle}" BorderThickness="0 0 0 1" CornerRadius="16 16 16 16" Padding="20 0 20 12"
Margin="0,0,0,0">
<Grid ColumnDefinitions="Auto,*,Auto">
<Border Grid.Column="0" Background="{DynamicResource IconBgBlue}" CornerRadius="10" Width="40" Height="40" Margin="0,0,14,0">
<Svg Path="../Assets/Icons/circle-dollar-sign.svg" Width="18" Height="18" Css="{DynamicResource SvgBlue}" />
</Border>
<TextBlock Grid.Column="1" Text="Total Net Worth" FontSize="14" FontWeight="SemiBold"
Foreground="{DynamicResource TextPrimary}" VerticalAlignment="Center" />
<TextBlock Grid.Column="2" Text="{Binding TotalBalance,StringFormat='$0.00'}" FontSize="17" FontWeight="Bold"
Foreground="{DynamicResource AccentBlue}" VerticalAlignment="Center" />
</Grid>
</Border>
<ItemsControl ItemsSource="{Binding VisibleAccounts}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Spacing="12" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate DataType="model:Account">
<Panel>
<TextBlock Text="{Binding Name}" Classes="label" Margin="0,0,0,4" IsVisible="{Binding GroupHeader}" />
<Button Classes="account" IsVisible="{Binding !GroupHeader}" HorizontalAlignment="Stretch"
Command="{Binding DataContext.SelectAccountCommand, ElementName=AccountsPage}" CommandParameter="{Binding .}">
<Classes.active>
<MultiBinding Converter="{StaticResource EqualValueConverter}">
<Binding Path="." /> <Binding Path="DataContext.SelectedAccount" ElementName="AccountsPage" />
</MultiBinding>
</Classes.active>
<Grid ColumnDefinitions="Auto,*,Auto">
<Border Grid.Column="0" CornerRadius="12" Width="48" Height="48" Margin="0,0,16,0">
<Border.Background>
<SolidColorBrush
Color="{Binding Color, Converter={StaticResource HexToColorConverter}, ConverterParameter=color}"
Opacity="0.15" />
</Border.Background>
<Svg Path="{Binding Icon,Converter={StaticResource SvgPathFromName}}" Width="22" Height="22"
Css="{Binding Color, Converter={StaticResource HexToColorConverter}, ConverterParameter=css}" />
</Border>
<StackPanel Grid.Column="1" VerticalAlignment="Center" Spacing="3">
<TextBlock Text="{Binding Name}" FontSize="14" FontWeight="SemiBold"
Foreground="{DynamicResource TextPrimary}" />
<StackPanel Orientation="Horizontal" Spacing="8">
<TextBlock Text="{Binding Institution}" FontSize="12" Foreground="{DynamicResource TextMuted}" />
<TextBlock Text="{Binding Mask, Converter={StaticResource MaskToStringConverter}}" FontSize="12"
Foreground="{DynamicResource TextMuted}" />
</StackPanel>
</StackPanel>
<StackPanel Grid.Column="2" HorizontalAlignment="Right" VerticalAlignment="Center" Spacing="4">
<TextBlock Text="{Binding CurrentBalance,StringFormat='$0.00'}" FontSize="15" FontWeight="Bold"
Foreground="{DynamicResource TextPrimary}" HorizontalAlignment="Right" />
<StackPanel Orientation="Horizontal" Spacing="4" HorizontalAlignment="Right">
<Svg Width="12" Height="12">
<Svg.Path>
<MultiBinding Converter="{StaticResource DecimalColorConverter}">
<Binding Path="MonthlyIncrease" />
<Binding Source="../Assets/Icons/trending-down.svg" />
<Binding Source="../Assets/Icons/trending-up.svg" />
</MultiBinding>
</Svg.Path>
<Svg.Css>
<MultiBinding Converter="{StaticResource DecimalColorConverter}">
<Binding Path="MonthlyIncrease" />
<DynamicResource ResourceKey="SvgRed" />
<DynamicResource ResourceKey="SvgGreen" />
</MultiBinding>
</Svg.Css>
</Svg>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding MonthlyIncrease,Converter={StaticResource DecimalSignConverter}}"
FontSize="11">
<TextBlock.Foreground>
<MultiBinding Converter="{StaticResource DecimalColorConverter}">
<Binding Path="MonthlyIncrease" />
<DynamicResource ResourceKey="AccentRed" />
<DynamicResource ResourceKey="AccentGreen" />
</MultiBinding>
</TextBlock.Foreground>
</TextBlock>
<TextBlock Text=" this month" FontSize="11">
<TextBlock.Foreground>
<MultiBinding Converter="{StaticResource DecimalColorConverter}">
<Binding Path="MonthlyIncrease" />
<DynamicResource ResourceKey="AccentRed" />
<DynamicResource ResourceKey="AccentGreen" />
</MultiBinding>
</TextBlock.Foreground>
</TextBlock>
</StackPanel>
</StackPanel>
</StackPanel>
</Grid>
</Button>
</Panel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</ScrollViewer>
</Grid>
<ScrollViewer Grid.Column="1" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled" Width="340" Padding="8 0"
IsVisible="{Binding SelectedAccount, Converter={x:Static ObjectConverters.IsNotNull}}">
<StackPanel Spacing="14" Margin="0 0 0 28">
<!-- Account detail card -->
<Border Background="{DynamicResource BgSurface}" BorderBrush="{DynamicResource BorderSubtle}" BorderThickness="1" CornerRadius="16"
Padding="22">
<StackPanel Spacing="18">
<!-- Header row -->
<Grid ColumnDefinitions="Auto,*,Auto">
<Border Grid.Column="0" CornerRadius="12" Width="46" Height="46" Margin="0,0,14,0">
<Border.Background>
<SolidColorBrush
Color="{Binding SelectedAccount.Color, Converter={StaticResource HexToColorConverter}, ConverterParameter=color}"
Opacity="0.15" />
</Border.Background>
<Svg Path="{Binding SelectedAccount.Icon,Converter={StaticResource SvgPathFromName}}" Width="20" Height="20"
Css="{Binding SelectedAccount.Color, Converter={StaticResource HexToColorConverter}, ConverterParameter=css}" />
</Border>
<StackPanel Grid.Column="1" VerticalAlignment="Center" Spacing="2">
<TextBlock Text="{Binding SelectedAccount.Name}" FontSize="14" FontWeight="Bold" Foreground="{DynamicResource TextPrimary}" />
<TextBlock Text="{Binding SelectedAccount.Institution}" FontSize="12" Foreground="{DynamicResource TextMuted}" />
</StackPanel>
<Button Grid.Column="2" Background="Transparent" BorderThickness="0" Padding="6" VerticalAlignment="Top" Cursor="Hand">
<Svg Path="../Assets/Icons/pencil.svg" Width="14" Height="14" Css="{DynamicResource SvgMuted}" />
</Button>
</Grid>
<Separator />
<!-- Balance -->
<StackPanel Spacing="6">
<TextBlock Text="CURRENT BALANCE" Classes="label" />
<TextBlock Text="{Binding SelectedAccount.CurrentBalance}" FontSize="26" FontWeight="Bold"
Foreground="{DynamicResource TextPrimary}" />
</StackPanel>
<Separator />
<!-- Detail fields -->
<Grid ColumnDefinitions="*,*" RowDefinitions="Auto,Auto,Auto">
<StackPanel Grid.Column="0" Grid.Row="0" Spacing="3" Margin="0,0,0,14">
<TextBlock Text="TYPE" Classes="label" />
<TextBlock Text="{Binding SelectedAccount.Type}" FontSize="13" FontWeight="SemiBold"
Foreground="{DynamicResource TextPrimary}" />
</StackPanel>
<StackPanel Grid.Column="1" Grid.Row="0" Spacing="3" Margin="0,0,0,14">
<TextBlock Text="INSTITUTION" Classes="label" />
<TextBlock Text="{Binding SelectedAccount.Institution}" FontSize="13" FontWeight="SemiBold"
Foreground="{DynamicResource TextPrimary}" />
</StackPanel>
<StackPanel Grid.Column="0" Grid.Row="1" Spacing="3" Margin="0,0,0,14">
<TextBlock Text="ACCOUNT NO." Classes="label" />
<TextBlock Text="{Binding SelectedAccount.Mask, Converter={StaticResource MaskToStringConverter}}" FontSize="13"
FontWeight="SemiBold" Foreground="{DynamicResource TextPrimary}" />
</StackPanel>
<StackPanel Grid.Column="1" Grid.Row="1" Spacing="3" Margin="0,0,0,14">
<TextBlock Text="CURRENCY" Classes="label" />
<TextBlock Text="{Binding SelectedAccount.Currency}" FontSize="13" FontWeight="SemiBold"
Foreground="{DynamicResource TextPrimary}" />
</StackPanel>
<StackPanel Grid.Column="0" Grid.Row="2" Spacing="3">
<TextBlock Text="OPENED" Classes="label" />
<TextBlock
Text="{Binding SelectedAccount.OpenedAt, Converter={StaticResource DateFormatConverter},ConverterParameter='MMM yyyy'}"
FontSize="13" FontWeight="SemiBold" Foreground="{DynamicResource TextPrimary}" />
</StackPanel>
<StackPanel Grid.Column="1" Grid.Row="2" Spacing="3">
<TextBlock Text="TRANSACTIONS" Classes="label" />
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding SelectedAccount.TransactionsCount}" FontSize="13" FontWeight="SemiBold"
Foreground="{DynamicResource TextPrimary}" />
<TextBlock Text=" total" FontSize="13" FontWeight="SemiBold" Foreground="{DynamicResource TextPrimary}" />
</StackPanel>
</StackPanel>
</Grid>
</StackPanel>
</Border>
<!-- Monthly Flow -->
<Border Background="{DynamicResource BgSurface}" BorderBrush="{DynamicResource BorderSubtle}" BorderThickness="1" CornerRadius="16"
Padding="22">
<StackPanel Spacing="14">
<TextBlock Text="This Month" FontSize="14" FontWeight="SemiBold" Foreground="{DynamicResource TextPrimary}" />
<!-- Money In -->
<Grid ColumnDefinitions="Auto,*,Auto">
<Border Grid.Column="0" Background="{DynamicResource IconBgGreen}" CornerRadius="8" Width="32" Height="32" Margin="0,0,12,0">
<Svg Path="../Assets/Icons/arrow-down-left.svg" Width="15" Height="15" Css="{DynamicResource SvgGreen}" />
</Border>
<StackPanel Grid.Column="1" VerticalAlignment="Center" Spacing="1">
<TextBlock Text="Money In" FontSize="11" Foreground="{DynamicResource TextMuted}" />
<TextBlock Text="{Binding SelectedAccount.TotalIncomeThisMonth, StringFormat='$0.00'}" FontSize="14" FontWeight="SemiBold"
Foreground="{DynamicResource AccentGreen}" />
</StackPanel>
<TextBlock Grid.Column="2" Text="{Binding SelectedAccount.IncomeTransactionsThisMonth}" FontSize="11"
Foreground="{DynamicResource TextDisabled}" VerticalAlignment="Center" />
</Grid>
<!-- Money Out -->
<Grid ColumnDefinitions="Auto,*,Auto">
<Border Grid.Column="0" Background="{DynamicResource IconBgRed}" CornerRadius="8" Width="32" Height="32" Margin="0,0,12,0">
<Svg Path="../Assets/Icons/arrow-up-right.svg" Width="15" Height="15" Css="{DynamicResource SvgRed}" />
</Border>
<StackPanel Grid.Column="1" VerticalAlignment="Center" Spacing="1">
<TextBlock Text="Money Out" FontSize="11" Foreground="{DynamicResource TextMuted}" />
<TextBlock Text="{Binding SelectedAccount.TotalExpenseThisMonth,StringFormat='$0.00'}" FontSize="14" FontWeight="SemiBold"
Foreground="{DynamicResource AccentRed}" />
</StackPanel>
<TextBlock Grid.Column="2" Text="{Binding SelectedAccount.ExpenseTransactionsThisMonth}" FontSize="11"
Foreground="{DynamicResource TextDisabled}" VerticalAlignment="Center" />
</Grid>
<Separator />
<Grid ColumnDefinitions="*,Auto">
<TextBlock Grid.Column="0" Text="Net" FontSize="13" FontWeight="SemiBold" Foreground="{DynamicResource TextMuted}"
VerticalAlignment="Center" />
<TextBlock Grid.Column="1" FontSize="14" FontWeight="Bold" Foreground="{DynamicResource AccentGreen}">
<TextBlock.Text>
<MultiBinding Converter="{StaticResource NetworthSumConverter}">
<Binding Path="SelectedAccount.TotalIncomeThisMonth" /> <Binding Path="SelectedAccount.TotalExpenseThisMonth" />
</MultiBinding>
</TextBlock.Text>
</TextBlock>
</Grid>
</StackPanel>
</Border>
<!-- Recent Transactions -->
<Border Background="{DynamicResource BgSurface}" BorderBrush="{DynamicResource BorderSubtle}" BorderThickness="1" CornerRadius="16"
Padding="22">
<StackPanel Spacing="14">
<Grid ColumnDefinitions="*,Auto">
<TextBlock Grid.Column="0" Text="Recent Transactions" FontSize="14" FontWeight="SemiBold"
Foreground="{DynamicResource TextPrimary}" VerticalAlignment="Center" />
<Button Grid.Column="1" Background="Transparent" BorderThickness="0" Padding="0" Cursor="Hand"
Command="{Binding ShowAccountTransactionsCommand}">
<StackPanel Orientation="Horizontal" Spacing="4">
<TextBlock Text="View all" FontSize="12" Foreground="{DynamicResource AccentBlue}" VerticalAlignment="Center" />
<Svg Path="../Assets/Icons/chevron-right.svg" Width="12" Height="12" Css="{DynamicResource SvgBlue}" />
</StackPanel>
</Button>
</Grid>
<ItemsControl ItemsSource="{Binding SelectedAccount.RecentTransactions}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Spacing="14" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate DataType="model:Transaction">
<Grid ColumnDefinitions="Auto,*,Auto">
<Border Grid.Column="0" CornerRadius="8" Width="32" Height="32"
Margin="0,0,12,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}}" Width="14" Height="14"
Css="{Binding Category.Color, Converter={StaticResource HexToColorConverter}, ConverterParameter='css'}" />
</Border>
<StackPanel Grid.Column="1" VerticalAlignment="Center" Spacing="1">
<TextBlock Text="{Binding Description}" FontSize="12" FontWeight="SemiBold"
Foreground="{DynamicResource TextPrimary}" />
<TextBlock Text="{Binding Date,Converter={StaticResource DateFormatConverter},ConverterParameter='MMM d'}"
FontSize="11" Foreground="{DynamicResource TextMuted}" />
</StackPanel>
<TextBlock Grid.Column="2" FontSize="12"
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>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</Border>
<!-- Net Worth Contribution -->
<Border Background="{DynamicResource BgSurface}" BorderBrush="{DynamicResource BorderSubtle}" BorderThickness="1" CornerRadius="16"
Padding="22">
<StackPanel Spacing="12">
<TextBlock Text="Net Worth Share" FontSize="14" FontWeight="SemiBold" Foreground="{DynamicResource TextPrimary}" />
<ProgressBar Classes="blue" Value="{Binding SelectedAccount.CurrentBalance}" Minimum="0" Maximum="{Binding TotalBalance}"
Height="6" />
<Grid ColumnDefinitions="*,Auto">
<TextBlock Grid.Column="0" Text="Share of total net worth" FontSize="12" Foreground="{DynamicResource TextMuted}"
VerticalAlignment="Center" />
<TextBlock Grid.Column="1" FontSize="12" FontWeight="SemiBold" Foreground="{DynamicResource AccentBlue}">
<TextBlock.Text>
<MultiBinding Converter="{StaticResource PercentageConverter}">
<Binding Path="SelectedAccount.CurrentBalance" />
<Binding Path="TotalBalance" />
</MultiBinding>
</TextBlock.Text>
</TextBlock>
</Grid>
<Separator />
<Grid ColumnDefinitions="*,Auto">
<TextBlock Grid.Column="0" Text="Total Net Worth" FontSize="12" Foreground="{DynamicResource TextMuted}"
VerticalAlignment="Center" />
<TextBlock Grid.Column="1" Text="{Binding TotalBalance,StringFormat='$0.00'}" FontSize="13" FontWeight="Bold"
Foreground="{DynamicResource TextPrimary}" />
</Grid>
</StackPanel>
</Border>
<!-- Manage Account -->
<Border Background="{DynamicResource BgSurface}" BorderBrush="{DynamicResource BorderSubtle}" BorderThickness="1" CornerRadius="16"
Padding="22">
<StackPanel Spacing="10">
<TextBlock Text="Manage" FontSize="14" FontWeight="SemiBold" Foreground="{DynamicResource TextPrimary}" Margin="0,0,0,4" />
<!-- Archive -->
<Button Background="Transparent" BorderBrush="{DynamicResource BorderSubtle}" BorderThickness="1" CornerRadius="10" Padding="14,10"
HorizontalAlignment="Stretch" HorizontalContentAlignment="Left" Cursor="Hand">
<StackPanel Orientation="Horizontal" Spacing="10">
<Svg Path="../Assets/Icons/archive.svg" Width="14" Height="14" Css="{DynamicResource SvgMuted}" />
<StackPanel Spacing="1">
<TextBlock Text="Archive Account" FontSize="12" FontWeight="SemiBold" Foreground="{DynamicResource TextPrimary}" />
<TextBlock Text="Hide from active list, keep history" FontSize="11" Foreground="{DynamicResource TextMuted}" />
</StackPanel>
</StackPanel>
</Button>
<!-- Delete -->
<Button Background="#2A0D0D" BorderBrush="#3A1515" BorderThickness="1" CornerRadius="10" Padding="14,10"
HorizontalAlignment="Stretch" HorizontalContentAlignment="Left" Cursor="Hand">
<StackPanel Orientation="Horizontal" Spacing="10">
<Svg Path="../Assets/Icons/trash-2.svg" Width="14" Height="14"
Css="path, circle, rect, ellipse, line, polyline, polygon, text, use { stroke: #FF5E5E; }" />
<StackPanel Spacing="1">
<TextBlock Text="Delete Account" FontSize="12" FontWeight="SemiBold" Foreground="#FF5E5E" />
<TextBlock Text="Permanently removes all data" FontSize="11" Foreground="{DynamicResource TextMuted}" />
</StackPanel>
</StackPanel>
</Button>
</StackPanel>
</Border>
</StackPanel>
</ScrollViewer>
</Grid>
</Grid>
</UserControl>

View File

@@ -0,0 +1,13 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
namespace Clario.Views;
public partial class AccountsView : UserControl
{
public AccountsView()
{
InitializeComponent();
}
}

448
Clario/Views/AuthView.axaml Normal file
View File

@@ -0,0 +1,448 @@
<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:cc="clr-namespace:Clario.CustomControls"
xmlns:vm="clr-namespace:Clario.ViewModels"
mc:Ignorable="d" d:DesignWidth="1400" d:DesignHeight="1200"
x:DataType="vm:AuthViewModel"
x:Class="Clario.Views.AuthView">
<Grid>
<!-- ── Background ────────────────────────── -->
<Border Background="{DynamicResource BgBase}" />
<!-- <Calendar SelectionMode="SingleRange"> -->
<!-- </Calendar> -->
<!-- ── Subtle grid pattern overlay ──────── -->
<!-- <Border Opacity="0.03" Background="{DynamicResource BgBase}"> -->
<!-- -->
<!-- </Border> -->
<!-- ── Center card ───────────────────────── -->
<Border HorizontalAlignment="Center"
VerticalAlignment="Center"
Background="{DynamicResource BgSurface}"
BorderBrush="{DynamicResource BorderSubtle}"
BorderThickness="1"
CornerRadius="20"
Padding="40"
Width="420"
BoxShadow="0 24 64 0 #40000000">
<StackPanel Spacing="0">
<!-- ── Logo + App name ─────────────── -->
<StackPanel HorizontalAlignment="Center"
Spacing="0"
Margin="0,0,0,32">
<Border
CornerRadius="16"
Height="100"
HorizontalAlignment="Center">
<Image Source="../Assets/Logo textmark.png"></Image>
</Border>
<!-- REPLACE: app name -->
<StackPanel Spacing="4" HorizontalAlignment="Center">
<!-- <TextBlock Text="Clario" -->
<!-- FontSize="22" -->
<!-- FontWeight="Bold" -->
<!-- Foreground="{DynamicResource TextPrimary}" -->
<!-- HorizontalAlignment="Center" /> -->
<TextBlock Text="Your personal finance tracker"
FontSize="12"
Foreground="{DynamicResource TextMuted}"
HorizontalAlignment="Center" />
</StackPanel>
</StackPanel>
<!-- ── Tab switcher ────────────────── -->
<Border Background="{DynamicResource BgBase}"
BorderBrush="{DynamicResource BorderSubtle}"
BorderThickness="1"
CornerRadius="{DynamicResource RadiusControl}"
Padding="3"
Margin="0,0,0,26">
<Grid ColumnDefinitions="*,*">
<!-- REPLACE: active state driven by IsLoginMode -->
<!-- Sign In — active -->
<Button Grid.Column="0"
HorizontalAlignment="Stretch"
HorizontalContentAlignment="Center"
Classes="nav"
Classes.accented="{Binding isSignin}"
CornerRadius="7"
Padding="0,7"
Cursor="Hand"
Command="{Binding SetOperationCommand}" CommandParameter="login">
<TextBlock Text="Sign In"
FontSize="13" FontWeight="SemiBold"
HorizontalAlignment="Center" />
</Button>
<!-- Sign Up -->
<Button Grid.Column="1"
HorizontalAlignment="Stretch"
HorizontalContentAlignment="Center"
Classes="nav"
Classes.accented="{Binding isCreateAccount}"
Padding="0,7"
Cursor="Hand"
Command="{Binding SetOperationCommand}" CommandParameter="signup">
<TextBlock Text="Create Account"
FontSize="13"
HorizontalAlignment="Center" />
</Button>
</Grid>
</Border>
<!-- SIGN IN PANEL -->
<StackPanel Spacing="0" IsVisible="{Binding isSignin}">
<!-- Email -->
<TextBlock Text="EMAIL" Classes="label" Margin="0,0,0,6" />
<Border Background="{DynamicResource BgBase}"
BorderBrush="{DynamicResource BorderSubtle}"
BorderThickness="1"
CornerRadius="{DynamicResource RadiusControl}"
Padding="0"
Margin="0,0,0,14">
<Grid ColumnDefinitions="Auto,*">
<Svg Grid.Column="0"
Path="../Assets/Icons/mail.svg"
Width="15" Height="15"
Css="{DynamicResource SvgMuted}"
VerticalAlignment="Center"
Margin="12,0,10,0" />
<!-- REPLACE: Text="{Binding Email, Mode=TwoWay}" -->
<TextBox Grid.Column="1" Classes="ghost"
Watermark="you@example.com"
Text="{Binding Email }"
BorderThickness="0"
FontSize="13"
Foreground="{DynamicResource TextPrimary}"
Height="42"
Padding="0"
VerticalContentAlignment="Center" />
</Grid>
</Border>
<!-- Password -->
<TextBlock Text="PASSWORD" Classes="label" Margin="0,0,0,6" />
<Border Background="{DynamicResource BgBase}"
BorderBrush="{DynamicResource BorderSubtle}"
BorderThickness="1"
CornerRadius="{DynamicResource RadiusControl}"
Padding="0,0"
Margin="0,0,0,8">
<Grid ColumnDefinitions="Auto,*,Auto">
<Svg Grid.Column="0"
Path="../Assets/Icons/lock.svg"
Width="15" Height="15"
Css="{DynamicResource SvgMuted}"
VerticalAlignment="Center"
Margin="12,0,10,0" />
<!-- REPLACE: Text="{Binding Password, Mode=TwoWay}" PasswordChar="●" -->
<TextBox Grid.Column="1" Classes="ghost"
Watermark="••••••••"
Text="{Binding Password}"
PasswordChar="●"
RevealPassword="{Binding #showPassword.IsChecked}"
BorderThickness="0"
FontSize="13"
Foreground="{DynamicResource TextPrimary}"
Height="42"
Padding="0"
VerticalContentAlignment="Center" />
<!-- REPLACE: Command="{Binding TogglePasswordCommand}" -->
<ToggleButton Grid.Column="2" Name="showPassword"
Background="Transparent"
CornerRadius="{DynamicResource RadiusControl}"
BorderThickness="0" Height="42"
Padding="8,0"
Cursor="Hand"
VerticalAlignment="Center">
<ToggleButton.Styles>
<Style Selector="ToggleButton:checked /template/ ContentPresenter">
<Setter Property="Background" Value="Transparent" />
<Setter Property="BorderThickness" Value="0" />
</Style>
</ToggleButton.Styles>
<Panel>
<Svg Path="../Assets/Icons/eye.svg"
Width="15" Height="15" IsVisible="{Binding #showPassword.IsChecked}"
Css="{DynamicResource SvgMuted}" />
<Svg Path="../Assets/Icons/eye-closed.svg"
Width="15" Height="15" IsVisible="{Binding !#showPassword.IsChecked}"
Css="{DynamicResource SvgMuted}" />
</Panel>
</ToggleButton>
</Grid>
</Border>
<!-- Forgot password -->
<!-- REPLACE: Command="{Binding ForgotPasswordCommand}" -->
<Button Background="Transparent"
BorderThickness="0"
Padding="0"
Cursor="Hand"
HorizontalAlignment="Right"
Margin="0,0,0,24">
<TextBlock Text="Forgot password?"
FontSize="12"
Foreground="{DynamicResource AccentBlue}" />
</Button>
<!-- Error message -->
<!-- REPLACE: IsVisible="{Binding HasError}" Text="{Binding ErrorMessage}" -->
<Border Background="{DynamicResource BadgeBgRed}"
BorderBrush="{DynamicResource AccentRed}"
BorderThickness="1"
CornerRadius="10"
Padding="12,10"
Margin="0,0,0,16"
IsVisible="False">
<StackPanel Orientation="Horizontal" Spacing="8">
<Svg Path="../Assets/Icons/circle-alert.svg"
Width="14" Height="14"
Css="path, circle, rect, ellipse, line, polyline, polygon, text, use { stroke: #FF5E5E; }" />
<TextBlock Text="Invalid email or password."
FontSize="12"
Foreground="{DynamicResource AccentRed}"
VerticalAlignment="Center" />
</StackPanel>
</Border>
<!-- Sign In button -->
<!-- REPLACE: Command="{Binding SignInCommand}" IsEnabled="{Binding IsNotLoading}" -->
<Button Classes="accented"
HorizontalAlignment="Stretch"
HorizontalContentAlignment="Center"
Padding="0,12"
Margin="0,0,0,20"
Command="{Binding ConfirmLoginCommand}">
<StackPanel Orientation="Horizontal" Spacing="8">
<Svg Path="../Assets/Icons/log-in.svg"
Width="15" Height="15"
Css="path, circle, rect, ellipse, line, polyline, polygon, text, use { stroke: #0D0F14; }" />
<TextBlock Text="Sign In"
FontSize="14" FontWeight="SemiBold"
Foreground="{DynamicResource BgBase}"
VerticalAlignment="Center" />
</StackPanel>
</Button>
</StackPanel>
<!-- ══════════════════════════════════
SIGN UP PANEL
REPLACE: IsVisible="{Binding !IsLoginMode}"
══════════════════════════════════ -->
<StackPanel Spacing="0" IsVisible="{Binding isCreateAccount}">
<!-- Name row -->
<Grid ColumnDefinitions="*,10,*" Margin="0,0,0,14">
<StackPanel Grid.Column="0" Spacing="6">
<TextBlock Text="FIRST NAME" Classes="label" />
<!-- REPLACE: Text="{Binding FirstName, Mode=TwoWay}" -->
<Border Background="{DynamicResource BgBase}"
BorderBrush="{DynamicResource BorderSubtle}"
BorderThickness="1"
CornerRadius="{DynamicResource RadiusControl}"
Padding="0"
Margin="0,0,0,0">
<TextBox Watermark=""
Text="{Binding FirstName}"
Classes="ghost"
FontSize="13" Height="42"
Padding="12,0"
VerticalContentAlignment="Center" />
</Border>
</StackPanel>
<StackPanel Grid.Column="2" Spacing="6">
<TextBlock Text="LAST NAME" Classes="label" />
<!-- REPLACE: Text="{Binding LastName, Mode=TwoWay}" -->
<Border Background="{DynamicResource BgBase}"
BorderBrush="{DynamicResource BorderSubtle}"
BorderThickness="1"
CornerRadius="{DynamicResource RadiusControl}"
Padding="0"
Margin="0,0,0,0">
<TextBox Watermark=""
Classes="ghost"
Text="{Binding LastName}"
FontSize="13" Height="42"
Padding="12,0"
VerticalContentAlignment="Center" />
</Border>
</StackPanel>
</Grid>
<!-- Email -->
<TextBlock Text="EMAIL" Classes="label" Margin="0,0,0,6" />
<Border Background="{DynamicResource BgBase}"
BorderBrush="{DynamicResource BorderSubtle}"
BorderThickness="1"
CornerRadius="{DynamicResource RadiusControl}"
Padding="0,0"
Margin="0,0,0,14">
<Grid ColumnDefinitions="Auto,*">
<Svg Grid.Column="0"
Path="../Assets/Icons/mail.svg"
Width="15" Height="15"
Css="{DynamicResource SvgMuted}"
VerticalAlignment="Center"
Margin="12,0,10,0" />
<!-- REPLACE: Text="{Binding Email, Mode=TwoWay}" -->
<TextBox Grid.Column="1"
Watermark="you@example.com"
Classes="ghost"
Text="{Binding Email}"
Background="Transparent"
BorderThickness="0"
FontSize="13"
Foreground="{DynamicResource TextPrimary}"
Height="42"
Padding="0"
VerticalContentAlignment="Center" />
</Grid>
</Border>
<!-- Password -->
<TextBlock Text="PASSWORD" Classes="label" Margin="0,0,0,6" />
<Border Background="{DynamicResource BgBase}"
BorderBrush="{DynamicResource BorderSubtle}"
BorderThickness="1"
CornerRadius="{DynamicResource RadiusControl}"
Padding="0"
Margin="0,0,0,14">
<Grid ColumnDefinitions="Auto,*,Auto">
<Svg Grid.Column="0"
Path="../Assets/Icons/lock.svg"
Width="15" Height="15"
Css="{DynamicResource SvgMuted}"
VerticalAlignment="Center"
Margin="12,0,10,0" />
<!-- REPLACE: Text="{Binding Password, Mode=TwoWay}" -->
<TextBox Grid.Column="1"
Watermark="At least 8 characters"
Classes="ghost"
Text="{Binding Password}"
RevealPassword="{Binding #showPasswordSignup.IsChecked}"
PasswordChar="●"
Background="Transparent"
BorderThickness="0"
FontSize="13"
Foreground="{DynamicResource TextPrimary}"
Height="42"
Padding="0"
VerticalContentAlignment="Center" />
<!-- REPLACE: Command="{Binding TogglePasswordCommand}" -->
<ToggleButton Grid.Column="2" Name="showPasswordSignup"
Background="Transparent"
CornerRadius="{DynamicResource RadiusControl}"
BorderThickness="0" Height="42"
Padding="8,0"
Cursor="Hand"
VerticalAlignment="Center">
<ToggleButton.Styles>
<Style Selector="ToggleButton:checked /template/ ContentPresenter">
<Setter Property="Background" Value="Transparent" />
<Setter Property="BorderThickness" Value="0" />
</Style>
</ToggleButton.Styles>
<Panel>
<Svg Path="../Assets/Icons/eye.svg"
Width="15" Height="15" IsVisible="{Binding #showPasswordSignup.IsChecked}"
Css="{DynamicResource SvgMuted}" />
<Svg Path="../Assets/Icons/eye-closed.svg"
Width="15" Height="15" IsVisible="{Binding !#showPasswordSignup.IsChecked}"
Css="{DynamicResource SvgMuted}" />
</Panel>
</ToggleButton>
</Grid>
</Border>
<!-- Confirm Password -->
<TextBlock Text="CONFIRM PASSWORD" Classes="label" Margin="0,0,0,6" />
<Border Background="{DynamicResource BgBase}"
BorderBrush="{DynamicResource BorderSubtle}"
BorderThickness="1"
CornerRadius="{DynamicResource RadiusControl}"
Padding="0,0"
Margin="0,0,0,16">
<Grid ColumnDefinitions="Auto,*">
<Svg Grid.Column="0"
Path="../Assets/Icons/lock.svg"
Width="15" Height="15"
Css="{DynamicResource SvgMuted}"
VerticalAlignment="Center"
Margin="12,0,10,0" />
<!-- REPLACE: Text="{Binding ConfirmPassword, Mode=TwoWay}" -->
<TextBox Grid.Column="1"
Watermark="Repeat your password"
PasswordChar="●"
Text="{Binding ConfirmPassword}"
Classes="ghost"
Background="Transparent"
BorderThickness="0"
FontSize="13"
Foreground="{DynamicResource TextPrimary}"
Height="42"
Padding="0"
VerticalContentAlignment="Center" />
</Grid>
</Border>
<!-- Error message -->
<!-- REPLACE: IsVisible="{Binding HasError}" Text="{Binding ErrorMessage}" -->
<Border Background="{DynamicResource BadgeBgRed}"
BorderBrush="{DynamicResource AccentRed}"
BorderThickness="1"
CornerRadius="10"
Padding="12,10"
Margin="0,0,0,16"
IsVisible="False">
<StackPanel Orientation="Horizontal" Spacing="8">
<Svg Path="../Assets/Icons/circle-alert.svg"
Width="14" Height="14"
Css="path, circle, rect, ellipse, line, polyline, polygon, text, use { stroke: #FF5E5E; }" />
<TextBlock Text="Something went wrong. Please try again."
FontSize="12"
Foreground="{DynamicResource AccentRed}"
VerticalAlignment="Center" />
</StackPanel>
</Border>
<!-- Create Account button -->
<!-- REPLACE: Command="{Binding SignUpCommand}" IsEnabled="{Binding IsNotLoading}" -->
<Button Classes="accented"
HorizontalAlignment="Stretch"
HorizontalContentAlignment="Center"
Padding="0,12"
Margin="0,0,0,20"
Command="{Binding ConfirmCreateAccountCommand}">
<StackPanel Orientation="Horizontal" Spacing="8">
<Svg Path="../Assets/Icons/user-plus.svg"
Width="15" Height="15"
Css="path, circle, rect, ellipse, line, polyline, polygon, text, use { stroke: #0D0F14; }" />
<TextBlock Text="Create Account"
FontSize="14" FontWeight="SemiBold"
Foreground="{DynamicResource BgBase}"
VerticalAlignment="Center" />
</StackPanel>
</Button>
</StackPanel>
<!-- ── Footer ──────────────────────── -->
<Separator Margin="0,0,0,16" />
<TextBlock Text="Your data is encrypted and synced securely."
FontSize="11"
Foreground="{DynamicResource TextDisabled}"
HorizontalAlignment="Center" />
</StackPanel>
</Border>
</Grid>
</UserControl>

View File

@@ -0,0 +1,14 @@
using System;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
namespace Clario.Views;
public partial class AuthView : UserControl
{
public AuthView()
{
InitializeComponent();
}
}

View File

@@ -0,0 +1,85 @@
<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:views="clr-namespace:Clario.Views"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="Clario.Views.BudgetCardMenuView">
<Border Background="{DynamicResource BgSurface}"
BorderBrush="{DynamicResource BorderSubtle}"
BorderThickness="1"
CornerRadius="12"
Padding="6"
Width="196"
BoxShadow="0 8 32 0 #3C000000">
<StackPanel Spacing="1">
<!-- Edit -->
<Button Background="Transparent"
BorderThickness="0"
CornerRadius="8"
Padding="10,9"
HorizontalAlignment="Stretch"
HorizontalContentAlignment="Left"
Cursor="Hand">
<Button.Flyout>
<Flyout Placement="LeftEdgeAlignedTop"
FlyoutPresenterTheme="{StaticResource TransparentFlyoutPresenter}">
<views:BudgetFormView />
</Flyout>
</Button.Flyout>
<StackPanel Orientation="Horizontal" Spacing="10">
<Svg Path="../Assets/Icons/pencil.svg" Width="14" Height="14" Css="{DynamicResource SvgSecondary}" />
<TextBlock Text="Edit Budget" FontSize="13" Foreground="{DynamicResource TextSecondary}" VerticalAlignment="Center" />
</StackPanel>
</Button>
<!-- View Transactions -->
<Button Background="Transparent"
BorderThickness="0"
CornerRadius="8"
Padding="10,9"
HorizontalAlignment="Stretch"
HorizontalContentAlignment="Left"
Cursor="Hand">
<StackPanel Orientation="Horizontal" Spacing="10">
<Svg Path="../Assets/Icons/list.svg" Width="14" Height="14" Css="{DynamicResource SvgSecondary}" />
<TextBlock Text="View Transactions" FontSize="13" Foreground="{DynamicResource TextSecondary}" VerticalAlignment="Center" />
</StackPanel>
</Button>
<!-- Reset Spent -->
<Button Background="Transparent"
BorderThickness="0"
CornerRadius="8"
Padding="10,9"
HorizontalAlignment="Stretch"
HorizontalContentAlignment="Left"
Cursor="Hand">
<StackPanel Orientation="Horizontal" Spacing="10">
<Svg Path="../Assets/Icons/rotate-ccw.svg" Width="14" Height="14" Css="{DynamicResource SvgSecondary}" />
<TextBlock Text="Reset Spent" FontSize="13" Foreground="{DynamicResource TextSecondary}" VerticalAlignment="Center" />
</StackPanel>
</Button>
<Separator Margin="4,2" />
<!-- Delete -->
<Button Background="Transparent"
BorderThickness="0"
CornerRadius="8"
Padding="10,9"
HorizontalAlignment="Stretch"
HorizontalContentAlignment="Left"
Cursor="Hand">
<StackPanel Orientation="Horizontal" Spacing="10">
<Svg Path="../Assets/Icons/trash-2.svg" Width="14" Height="14"
Css="path, circle, rect, ellipse, line, polyline, polygon, text, use { stroke: #FF5E5E; }" />
<TextBlock Text="Delete Budget" FontSize="13" Foreground="#FF5E5E" VerticalAlignment="Center" />
</StackPanel>
</Button>
</StackPanel>
</Border>
</UserControl>

View File

@@ -0,0 +1,13 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
namespace Clario.Views;
public partial class BudgetCardMenuView : UserControl
{
public BudgetCardMenuView()
{
InitializeComponent();
}
}

View File

@@ -0,0 +1,227 @@
<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:styles="clr-namespace:Clario.Theme.Styles"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="Clario.Views.BudgetFormView">
<Border Background="{DynamicResource BgSurface}"
BorderBrush="{DynamicResource BorderSubtle}"
BorderThickness="1"
CornerRadius="16"
Padding="24"
Width="380"
BoxShadow="0 12 40 0 #4C000000">
<StackPanel Spacing="0">
<!-- ── Header ─────────────────────────── -->
<Grid ColumnDefinitions="Auto,*,Auto" Margin="0,0,0,22">
<Border Grid.Column="0"
Background="{DynamicResource IconBgBlue}"
CornerRadius="10"
Width="38" Height="38"
Margin="0,0,12,0">
<Svg Path="../Assets/Icons/wallet.svg" Width="17" Height="17" Css="{DynamicResource SvgBlue}" />
</Border>
<StackPanel Grid.Column="1" VerticalAlignment="Center" Spacing="1">
<!-- REPLACE: bind to DialogTitle -->
<TextBlock Text="Edit Budget"
FontSize="15" FontWeight="Bold"
Foreground="{DynamicResource TextPrimary}" />
<!-- REPLACE: bind to SelectedCategory -->
<TextBlock Text="Food &amp; Dining"
FontSize="11"
Foreground="{DynamicResource TextMuted}" />
</StackPanel>
<Button Grid.Column="2"
Background="Transparent" BorderThickness="0"
Padding="6" VerticalAlignment="Top" Cursor="Hand">
<Svg Path="../Assets/Icons/x.svg" Width="15" Height="15" Css="{DynamicResource SvgMuted}" />
</Button>
</Grid>
<!-- ── Category ───────────────────────── -->
<TextBlock Text="CATEGORY" Classes="label" Margin="0,0,0,6" />
<Border Background="{DynamicResource BgBase}"
BorderBrush="{DynamicResource BorderSubtle}"
BorderThickness="1"
CornerRadius="10"
Margin="0,0,0,18">
<Grid ColumnDefinitions="Auto,*">
<Border Grid.Column="0"
Background="{DynamicResource IconBgGreen}"
CornerRadius="8"
Width="34" Height="34"
Margin="8,0,0,0"
VerticalAlignment="Center">
<!-- REPLACE: icon changes with SelectedCategory -->
<Svg Path="../Assets/Icons/utensils.svg" Width="15" Height="15" Css="{DynamicResource SvgGreen}" />
</Border>
<!-- REPLACE: SelectedItem="{Binding SelectedCategory}" -->
<ComboBox Grid.Column="1"
Background="Transparent" BorderThickness="0"
Padding="10,11" FontSize="13"
HorizontalAlignment="Stretch"
SelectedIndex="0">
<ComboBoxItem Content="Food &amp; Dining" />
<ComboBoxItem Content="Housing" />
<ComboBoxItem Content="Transport" />
<ComboBoxItem Content="Health" />
<ComboBoxItem Content="Leisure" />
<ComboBoxItem Content="Shopping" />
<ComboBoxItem Content="Education" />
<ComboBoxItem Content="Subscriptions" />
<ComboBoxItem Content="Other" />
</ComboBox>
</Grid>
</Border>
<!-- ── Monthly Limit ──────────────────── -->
<TextBlock Text="MONTHLY LIMIT" Classes="label" Margin="0,0,0,6" />
<Border Background="{DynamicResource BgBase}"
BorderBrush="{DynamicResource BorderSubtle}"
BorderThickness="1"
CornerRadius="10"
Padding="14,0"
Margin="0,0,0,8">
<Grid ColumnDefinitions="Auto,*">
<TextBlock Grid.Column="0" Text="$"
FontSize="15" FontWeight="SemiBold"
Foreground="{DynamicResource TextMuted}"
VerticalAlignment="Center" Margin="0,0,4,0" />
<!-- REPLACE: Text="{Binding LimitAmount, Mode=TwoWay}" -->
<TextBox Grid.Column="1" Text="500" Watermark="0.00"
Background="Transparent" BorderThickness="0"
FontSize="15" FontWeight="SemiBold"
Foreground="{DynamicResource TextPrimary}"
Height="44" Padding="0" VerticalContentAlignment="Center" />
</Grid>
</Border>
<!-- Quick-pick amounts -->
<StackPanel Orientation="Horizontal" Spacing="6" Margin="0,0,0,18">
<Border Background="{DynamicResource BgBase}" BorderBrush="{DynamicResource BorderSubtle}" BorderThickness="1" CornerRadius="20" Padding="10,4"
Cursor="Hand">
<TextBlock Text="$100" FontSize="11" Foreground="{DynamicResource TextMuted}" />
</Border>
<Border Background="{DynamicResource BgBase}" BorderBrush="{DynamicResource BorderSubtle}" BorderThickness="1" CornerRadius="20" Padding="10,4"
Cursor="Hand">
<TextBlock Text="$250" FontSize="11" Foreground="{DynamicResource TextMuted}" />
</Border>
<Border Background="{DynamicResource AccentBlue}" CornerRadius="20" Padding="10,4" Cursor="Hand">
<TextBlock Text="$500" FontSize="11" FontWeight="SemiBold" Foreground="{DynamicResource BgBase}" />
</Border>
<Border Background="{DynamicResource BgBase}" BorderBrush="{DynamicResource BorderSubtle}" BorderThickness="1" CornerRadius="20" Padding="10,4"
Cursor="Hand">
<TextBlock Text="$1,000" FontSize="11" Foreground="{DynamicResource TextMuted}" />
</Border>
</StackPanel>
<!-- ── Rollover ───────────────────────── -->
<Border Background="{DynamicResource BgBase}"
BorderBrush="{DynamicResource BorderSubtle}"
BorderThickness="1"
CornerRadius="10"
Padding="14,11"
Margin="0,0,0,18">
<Grid ColumnDefinitions="*,Auto">
<StackPanel Grid.Column="0" Spacing="2">
<TextBlock Text="Rollover unused budget"
FontSize="13" FontWeight="SemiBold"
Foreground="{DynamicResource TextPrimary}" />
<TextBlock Text="Carry leftover amount into next month"
FontSize="11" Foreground="{DynamicResource TextMuted}" />
</StackPanel>
<!-- REPLACE: IsChecked="{Binding RolloverEnabled}" -->
<ToggleSwitch Grid.Column="1" styles:ToggleSwitchExtensions.KnobWidth="16"
styles:ToggleSwitchExtensions.KnobHeight="16" VerticalAlignment="Center" OffContent="" OnContent="" />
</Grid>
</Border>
<!-- ── Alert Threshold ────────────────── -->
<TextBlock Text="ALERT THRESHOLD" Classes="label" Margin="0,0,0,6" />
<Border Background="{DynamicResource BgBase}"
BorderBrush="{DynamicResource BorderSubtle}"
BorderThickness="1"
CornerRadius="10"
Margin="0,0,0,8">
<Grid ColumnDefinitions="*,Auto">
<StackPanel Grid.Column="0" Spacing="2" Margin="14,11,0,11">
<TextBlock Text="Warn me when I reach"
FontSize="13" Foreground="{DynamicResource TextSecondary}" />
<!-- REPLACE: bind to AlertThresholdLabel -->
<TextBlock Text="80% of limit ($400)"
FontSize="11" Foreground="{DynamicResource TextMuted}" />
</StackPanel>
<!-- Stepper -->
<Border Grid.Column="1"
Background="{DynamicResource BgSurface}"
BorderBrush="{DynamicResource BorderSubtle}"
BorderThickness="1"
CornerRadius="8"
Margin="8">
<StackPanel Orientation="Horizontal">
<Button Background="Transparent" BorderThickness="0" Padding="8,6" Cursor="Hand">
<Svg Path="../Assets/Icons/minus.svg" Width="12" Height="12" Css="{DynamicResource SvgMuted}" />
</Button>
<!-- REPLACE: bind to AlertThreshold -->
<TextBlock Text="80%"
FontSize="13" FontWeight="SemiBold"
Foreground="{DynamicResource TextPrimary}"
VerticalAlignment="Center" Margin="4,0" />
<Button Background="Transparent" BorderThickness="0" Padding="8,6" Cursor="Hand">
<Svg Path="../Assets/Icons/plus.svg" Width="12" Height="12" Css="{DynamicResource SvgMuted}" />
</Button>
</StackPanel>
</Border>
</Grid>
</Border>
<!-- Threshold quick-picks -->
<StackPanel Orientation="Horizontal" Spacing="6" Margin="0,0,0,24">
<Border Background="{DynamicResource BgBase}" BorderBrush="{DynamicResource BorderSubtle}" BorderThickness="1" CornerRadius="20" Padding="10,4"
Cursor="Hand">
<TextBlock Text="60%" FontSize="11" Foreground="{DynamicResource TextMuted}" />
</Border>
<Border Background="{DynamicResource BgBase}" BorderBrush="{DynamicResource BorderSubtle}" BorderThickness="1" CornerRadius="20" Padding="10,4"
Cursor="Hand">
<TextBlock Text="70%" FontSize="11" Foreground="{DynamicResource TextMuted}" />
</Border>
<Border Background="{DynamicResource AccentBlue}" CornerRadius="20" Padding="10,4" Cursor="Hand">
<TextBlock Text="80%" FontSize="11" FontWeight="SemiBold" Foreground="{DynamicResource BgBase}" />
</Border>
<Border Background="{DynamicResource BgBase}" BorderBrush="{DynamicResource BorderSubtle}" BorderThickness="1" CornerRadius="20" Padding="10,4"
Cursor="Hand">
<TextBlock Text="90%" FontSize="11" Foreground="{DynamicResource TextMuted}" />
</Border>
</StackPanel>
<!-- ── Actions ────────────────────────── -->
<Grid ColumnDefinitions="*,*">
<!-- REPLACE: Command="{Binding CancelCommand}" -->
<Button Grid.Column="0"
Classes="base"
Margin="0,0,6,0" Padding="0,10"
HorizontalAlignment="Stretch"
HorizontalContentAlignment="Center"
FontSize="13" Content="Cancel" />
<!-- REPLACE: Command="{Binding SaveCommand}" -->
<Button Grid.Column="1"
Classes="accented"
Margin="6,0,0,0" Padding="0,10"
HorizontalAlignment="Stretch"
HorizontalContentAlignment="Center">
<StackPanel Orientation="Horizontal" Spacing="8">
<Svg Path="../Assets/Icons/check.svg" Width="13" Height="13"
Css="path, circle, rect, ellipse, line, polyline, polygon, text, use { stroke: #0D0F14; }" />
<TextBlock Text="Save" FontSize="13" FontWeight="SemiBold"
Foreground="{DynamicResource BgBase}" VerticalAlignment="Center" />
</StackPanel>
</Button>
</Grid>
</StackPanel>
</Border>
</UserControl>

View File

@@ -0,0 +1,13 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
namespace Clario.Views;
public partial class BudgetFormView : UserControl
{
public BudgetFormView()
{
InitializeComponent();
}
}

View File

@@ -0,0 +1,822 @@
<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:views="clr-namespace:Clario.Views"
xmlns:system="clr-namespace:System;assembly=System.Runtime"
xmlns:skiaSharpView="clr-namespace:LiveChartsCore.SkiaSharpView;assembly=LiveChartsCore.SkiaSharpView"
x:DataType="vm:BudgetViewModel"
mc:Ignorable="d" d:DesignWidth="1180" d:DesignHeight="800"
x:Class="Clario.Views.BudgetView">
<Design.DataContext>
<vm:BudgetViewModel />
</Design.DataContext>
<!-- ═══════════════════════════════════════════════════
ROOT
═══════════════════════════════════════════════════ -->
<Grid RowDefinitions="Auto,*"
Margin="32,28,32,0">
<!-- ══════════════════════════════════════════
TOP BAR
══════════════════════════════════════════ -->
<Grid Grid.Row="0"
ColumnDefinitions="*,Auto"
Margin="0,0,0,24">
<StackPanel Grid.Column="0">
<!-- REPLACE: bind to CurrentPeriodLabel e.g. "March 2026" -->
<TextBlock Text="March 2026"
FontSize="12"
Foreground="{DynamicResource TextMuted}" />
<TextBlock Text="Budget"
FontSize="26"
FontWeight="Bold"
Foreground="{DynamicResource TextPrimary}"
Margin="0,2,0,0" />
</StackPanel>
<StackPanel Grid.Column="1"
Orientation="Horizontal"
Spacing="10"
VerticalAlignment="Center">
<!-- Period navigator -->
<Border Background="{DynamicResource BgSurface}"
BorderBrush="{DynamicResource BorderSubtle}"
BorderThickness="1"
CornerRadius="10">
<StackPanel Orientation="Horizontal">
<!-- REPLACE: Command="{Binding PreviousPeriodCommand}" -->
<Button Background="Transparent"
BorderThickness="0"
Padding="10,8"
Cursor="Hand">
<Svg Path="../Assets/Icons/chevron-left.svg"
Width="14" Height="14"
Css="{DynamicResource SvgMuted}" />
</Button>
<!-- REPLACE: bind to CurrentPeriodLabel -->
<TextBlock Text="Mar 2026"
FontSize="13"
FontWeight="SemiBold"
Foreground="{DynamicResource TextPrimary}"
VerticalAlignment="Center"
Margin="4,0" />
<!-- REPLACE: Command="{Binding NextPeriodCommand}" -->
<Button Background="Transparent"
BorderThickness="0"
Padding="10,8"
Cursor="Hand">
<Svg Path="../Assets/Icons/chevron-right.svg"
Width="14" Height="14"
Css="{DynamicResource SvgMuted}" />
</Button>
</StackPanel>
</Border>
<!-- Add budget button -->
<!-- REPLACE: Command="{Binding AddBudgetCommand}" -->
<Button Classes="accented"
Padding="16,9">
<Button.Flyout>
<Flyout Placement="LeftEdgeAlignedTop"
FlyoutPresenterTheme="{StaticResource TransparentFlyoutPresenter}">
<views:BudgetFormView />
</Flyout>
</Button.Flyout>
<StackPanel Orientation="Horizontal" Spacing="8">
<Svg Path="../Assets/Icons/plus.svg"
Width="14" Height="14"
Css="path, circle, rect, ellipse, line, polyline, polygon, text, use { stroke: #0D0F14; }" />
<TextBlock Text="Add Budget"
FontSize="13"
FontWeight="SemiBold"
Foreground="{DynamicResource BgBase}"
VerticalAlignment="Center" />
</StackPanel>
</Button>
</StackPanel>
</Grid>
<!-- ══════════════════════════════════════════
MAIN CONTENT
Left * — budget categories
Right 320 — monthly overview panel
══════════════════════════════════════════ -->
<Grid Grid.Row="1" ColumnDefinitions="*,320">
<!-- ─────────────────────────────────────
LEFT — Budget Categories
───────────────────────────────────── -->
<ScrollViewer Grid.Column="0"
VerticalScrollBarVisibility="Auto"
HorizontalScrollBarVisibility="Disabled"
Margin="0,0,12,0" Padding="0 0 8 0">
<StackPanel Spacing="12" Margin="0 0 0 28">
<!-- ── On Track ───────────────────────── -->
<TextBlock Text="ON TRACK"
Classes="label"
Margin="0,0,0,4" />
<!-- REPLACE: ItemsSource="{Binding OnTrackBudgets}" with DataTemplate -->
<!-- Budget Card — Food (healthy) -->
<Border Background="{DynamicResource BgSurface}"
BorderBrush="{DynamicResource BorderSubtle}"
BorderThickness="1"
CornerRadius="16"
Padding="20"
Cursor="Hand">
<StackPanel Spacing="14">
<!-- Header row -->
<Grid ColumnDefinitions="Auto,*,Auto,Auto">
<Border Grid.Column="0"
Background="{DynamicResource IconBgGreen}"
CornerRadius="10"
Width="40" Height="40"
Margin="0,0,14,0">
<Svg Path="../Assets/Icons/utensils.svg"
Width="18" Height="18"
Css="{DynamicResource SvgGreen}" />
</Border>
<StackPanel Grid.Column="1" VerticalAlignment="Center" Spacing="2">
<!-- REPLACE: bind to Budget.CategoryName -->
<TextBlock Text="Food &amp; Dining"
FontSize="14"
FontWeight="SemiBold"
Foreground="{DynamicResource TextPrimary}" />
<!-- REPLACE: bind to Budget.TransactionCount -->
<TextBlock Text="8 transactions"
FontSize="11"
Foreground="{DynamicResource TextMuted}" />
</StackPanel>
<!-- Spent / Limit -->
<StackPanel Grid.Column="2"
HorizontalAlignment="Right"
VerticalAlignment="Center"
Spacing="2"
Margin="0,0,12,0">
<!-- REPLACE: bind to Budget.SpentFormatted -->
<TextBlock Text="$340"
FontSize="14"
FontWeight="Bold"
Foreground="{DynamicResource TextPrimary}"
HorizontalAlignment="Right" />
<!-- REPLACE: bind to Budget.LimitFormatted -->
<TextBlock Text="of $500"
FontSize="11"
Foreground="{DynamicResource TextMuted}"
HorizontalAlignment="Right" />
</StackPanel>
<!-- Edit button -->
<!-- REPLACE: Command="{Binding EditBudgetCommand}" CommandParameter="{Binding}" -->
<Button Grid.Column="3"
Background="Transparent"
BorderThickness="0"
Padding="4"
VerticalAlignment="Center"
Cursor="Hand">
<Button.Flyout>
<Flyout Placement="BottomEdgeAlignedRight"
FlyoutPresenterTheme="{StaticResource TransparentFlyoutPresenter}">
<views:BudgetCardMenuView />
</Flyout>
</Button.Flyout>
<Svg Path="../Assets/Icons/ellipsis.svg"
Width="15" Height="15"
Css="{DynamicResource SvgMuted}" />
</Button>
</Grid>
<!-- Progress bar + remaining -->
<StackPanel Spacing="6">
<!-- REPLACE: Value="{Binding Budget.PercentageUsed}" -->
<ProgressBar Classes="green"
Value="68"
Minimum="0"
Maximum="100"
Height="6" />
<Grid ColumnDefinitions="*,Auto">
<StackPanel Grid.Column="0" Orientation="Horizontal" Spacing="6">
<Border Background="{DynamicResource IconBgGreen}"
CornerRadius="20"
Padding="6,2">
<TextBlock Text="68% used"
FontSize="11"
Foreground="{DynamicResource AccentGreen}" />
</Border>
</StackPanel>
<!-- REPLACE: bind to Budget.RemainingFormatted -->
<TextBlock Grid.Column="1"
Text="$160 left"
FontSize="11"
Foreground="{DynamicResource TextMuted}"
VerticalAlignment="Center" />
</Grid>
</StackPanel>
</StackPanel>
</Border>
<!-- Budget Card — Transport (healthy) -->
<Border Background="{DynamicResource BgSurface}"
BorderBrush="{DynamicResource BorderSubtle}"
BorderThickness="1"
CornerRadius="16"
Padding="20"
Cursor="Hand">
<StackPanel Spacing="14">
<Grid ColumnDefinitions="Auto,*,Auto,Auto">
<Border Grid.Column="0" Background="{DynamicResource IconBgBlue}" CornerRadius="10" Width="40" Height="40" Margin="0,0,14,0">
<Svg Path="../Assets/Icons/car.svg" Width="18" Height="18" Css="{DynamicResource SvgBlue}" />
</Border>
<StackPanel Grid.Column="1" VerticalAlignment="Center" Spacing="2">
<TextBlock Text="Transport" FontSize="14" FontWeight="SemiBold" Foreground="{DynamicResource TextPrimary}" />
<TextBlock Text="3 transactions" FontSize="11" Foreground="{DynamicResource TextMuted}" />
</StackPanel>
<StackPanel Grid.Column="2" HorizontalAlignment="Right" VerticalAlignment="Center" Spacing="2" Margin="0,0,12,0">
<TextBlock Text="$110" FontSize="14" FontWeight="Bold" Foreground="{DynamicResource TextPrimary}"
HorizontalAlignment="Right" />
<TextBlock Text="of $200" FontSize="11" Foreground="{DynamicResource TextMuted}" HorizontalAlignment="Right" />
</StackPanel>
<Button Grid.Column="3" Background="Transparent" BorderThickness="0" Padding="4" VerticalAlignment="Center" Cursor="Hand">
<Button.Flyout>
<Flyout Placement="BottomEdgeAlignedRight"
FlyoutPresenterTheme="{StaticResource TransparentFlyoutPresenter}">
<views:BudgetCardMenuView />
</Flyout>
</Button.Flyout>
<Svg Path="../Assets/Icons/ellipsis.svg" Width="15" Height="15" Css="{DynamicResource SvgMuted}" />
</Button>
</Grid>
<StackPanel Spacing="6">
<ProgressBar Classes="green" Value="55" Minimum="0" Maximum="100" Height="6" />
<Grid ColumnDefinitions="*,Auto">
<Border Grid.Column="0" Background="{DynamicResource IconBgGreen}" CornerRadius="20" Padding="6,2"
HorizontalAlignment="Left">
<TextBlock Text="55% used" FontSize="11" Foreground="{DynamicResource AccentGreen}" />
</Border>
<TextBlock Grid.Column="1" Text="$90 left" FontSize="11" Foreground="{DynamicResource TextMuted}"
VerticalAlignment="Center" />
</Grid>
</StackPanel>
</StackPanel>
</Border>
<!-- Budget Card — Health (healthy) -->
<Border Background="{DynamicResource BgSurface}"
BorderBrush="{DynamicResource BorderSubtle}"
BorderThickness="1"
CornerRadius="16"
Padding="20"
Cursor="Hand">
<StackPanel Spacing="14">
<Grid ColumnDefinitions="Auto,*,Auto,Auto">
<Border Grid.Column="0" Background="{DynamicResource IconBgPink}" CornerRadius="10" Width="40" Height="40" Margin="0,0,14,0">
<Svg Path="../Assets/Icons/heart-pulse.svg" Width="18" Height="18" Css="{DynamicResource SvgPink}" />
</Border>
<StackPanel Grid.Column="1" VerticalAlignment="Center" Spacing="2">
<TextBlock Text="Health" FontSize="14" FontWeight="SemiBold" Foreground="{DynamicResource TextPrimary}" />
<TextBlock Text="2 transactions" FontSize="11" Foreground="{DynamicResource TextMuted}" />
</StackPanel>
<StackPanel Grid.Column="2" HorizontalAlignment="Right" VerticalAlignment="Center" Spacing="2" Margin="0,0,12,0">
<TextBlock Text="$69" FontSize="14" FontWeight="Bold" Foreground="{DynamicResource TextPrimary}"
HorizontalAlignment="Right" />
<TextBlock Text="of $150" FontSize="11" Foreground="{DynamicResource TextMuted}" HorizontalAlignment="Right" />
</StackPanel>
<Button Grid.Column="3" Background="Transparent" BorderThickness="0" Padding="4" VerticalAlignment="Center" Cursor="Hand">
<Button.Flyout>
<Flyout Placement="BottomEdgeAlignedRight"
FlyoutPresenterTheme="{StaticResource TransparentFlyoutPresenter}">
<views:BudgetCardMenuView />
</Flyout>
</Button.Flyout>
<Svg Path="../Assets/Icons/ellipsis.svg" Width="15" Height="15" Css="{DynamicResource SvgMuted}" />
</Button>
</Grid>
<StackPanel Spacing="6">
<ProgressBar Classes="green" Value="46" Minimum="0" Maximum="100" Height="6" />
<Grid ColumnDefinitions="*,Auto">
<Border Grid.Column="0" Background="{DynamicResource IconBgGreen}" CornerRadius="20" Padding="6,2"
HorizontalAlignment="Left">
<TextBlock Text="46% used" FontSize="11" Foreground="{DynamicResource AccentGreen}" />
</Border>
<TextBlock Grid.Column="1" Text="$81 left" FontSize="11" Foreground="{DynamicResource TextMuted}"
VerticalAlignment="Center" />
</Grid>
</StackPanel>
</StackPanel>
</Border>
<!-- ── Approaching Limit ───────────────── -->
<TextBlock Text="APPROACHING LIMIT"
Classes="label"
Margin="0,12,0,4" />
<!-- REPLACE: ItemsSource="{Binding WarningBudgets}" with DataTemplate -->
<!-- Budget Card — Leisure (warning ~85%) -->
<Border Background="{DynamicResource BgSurface}"
BorderBrush="{DynamicResource AccentYellow}"
BorderThickness="1"
CornerRadius="16"
Padding="20"
Cursor="Hand">
<StackPanel Spacing="14">
<Grid ColumnDefinitions="Auto,*,Auto,Auto">
<Border Grid.Column="0" Background="{DynamicResource IconBgPurple}" CornerRadius="10" Width="40" Height="40" Margin="0,0,14,0">
<Svg Path="../Assets/Icons/gamepad-2.svg" Width="18" Height="18" Css="{DynamicResource SvgPurple}" />
</Border>
<StackPanel Grid.Column="1" VerticalAlignment="Center" Spacing="2">
<TextBlock Text="Entertainment" FontSize="14" FontWeight="SemiBold" Foreground="{DynamicResource TextPrimary}" />
<TextBlock Text="5 transactions" FontSize="11" Foreground="{DynamicResource TextMuted}" />
</StackPanel>
<StackPanel Grid.Column="2" HorizontalAlignment="Right" VerticalAlignment="Center" Spacing="2" Margin="0,0,12,0">
<TextBlock Text="$170" FontSize="14" FontWeight="Bold" Foreground="{DynamicResource AccentYellow}"
HorizontalAlignment="Right" />
<TextBlock Text="of $200" FontSize="11" Foreground="{DynamicResource TextMuted}" HorizontalAlignment="Right" />
</StackPanel>
<Button Grid.Column="3" Background="Transparent" BorderThickness="0" Padding="4" VerticalAlignment="Center" Cursor="Hand">
<Button.Flyout>
<Flyout Placement="BottomEdgeAlignedRight"
FlyoutPresenterTheme="{StaticResource TransparentFlyoutPresenter}">
<views:BudgetCardMenuView />
</Flyout>
</Button.Flyout>
<Svg Path="../Assets/Icons/ellipsis.svg" Width="15" Height="15" Css="{DynamicResource SvgMuted}" />
</Button>
</Grid>
<StackPanel Spacing="6">
<ProgressBar Classes="yellow" Value="85" Minimum="0" Maximum="100" Height="6" />
<Grid ColumnDefinitions="*,Auto">
<Border Grid.Column="0" Background="{DynamicResource BadgeBgYellow}" CornerRadius="20" Padding="6,2"
HorizontalAlignment="Left">
<StackPanel Orientation="Horizontal" Spacing="5">
<Svg Path="../Assets/Icons/triangle-alert.svg" Width="11" Height="11"
Css="path, circle, rect, ellipse, line, polyline, polygon, text, use { stroke: #F5C842; }" />
<TextBlock Text="85% used" FontSize="11" Foreground="{DynamicResource AccentYellow}" VerticalAlignment="Center" />
</StackPanel>
</Border>
<TextBlock Grid.Column="1" Text="$30 left" FontSize="11" Foreground="{DynamicResource TextMuted}"
VerticalAlignment="Center" />
</Grid>
</StackPanel>
</StackPanel>
</Border>
<!-- Budget Card — Housing (warning ~90%) -->
<Border Background="{DynamicResource BgSurface}"
BorderBrush="{DynamicResource AccentYellow}"
BorderThickness="1"
CornerRadius="16"
Padding="20"
Cursor="Hand">
<StackPanel Spacing="14">
<Grid ColumnDefinitions="Auto,*,Auto,Auto">
<Border Grid.Column="0" Background="{DynamicResource IconBgOrange}" CornerRadius="10" Width="40" Height="40" Margin="0,0,14,0">
<Svg Path="../Assets/Icons/house.svg" Width="18" Height="18" Css="{DynamicResource SvgOrange}" />
</Border>
<StackPanel Grid.Column="1" VerticalAlignment="Center" Spacing="2">
<TextBlock Text="Housing" FontSize="14" FontWeight="SemiBold" Foreground="{DynamicResource TextPrimary}" />
<TextBlock Text="4 transactions" FontSize="11" Foreground="{DynamicResource TextMuted}" />
</StackPanel>
<StackPanel Grid.Column="2" HorizontalAlignment="Right" VerticalAlignment="Center" Spacing="2" Margin="0,0,12,0">
<TextBlock Text="$540" FontSize="14" FontWeight="Bold" Foreground="{DynamicResource AccentYellow}"
HorizontalAlignment="Right" />
<TextBlock Text="of $600" FontSize="11" Foreground="{DynamicResource TextMuted}" HorizontalAlignment="Right" />
</StackPanel>
<Button Grid.Column="3" Background="Transparent" BorderThickness="0" Padding="4" VerticalAlignment="Center" Cursor="Hand">
<Button.Flyout>
<Flyout Placement="BottomEdgeAlignedRight"
FlyoutPresenterTheme="{StaticResource TransparentFlyoutPresenter}">
<views:BudgetCardMenuView />
</Flyout>
</Button.Flyout>
<Svg Path="../Assets/Icons/ellipsis.svg" Width="15" Height="15" Css="{DynamicResource SvgMuted}" />
</Button>
</Grid>
<StackPanel Spacing="6">
<ProgressBar Classes="yellow" Value="90" Minimum="0" Maximum="100" Height="6" />
<Grid ColumnDefinitions="*,Auto">
<Border Grid.Column="0" Background="{DynamicResource BadgeBgYellow}" CornerRadius="20" Padding="6,2"
HorizontalAlignment="Left">
<StackPanel Orientation="Horizontal" Spacing="5">
<Svg Path="../Assets/Icons/triangle-alert.svg" Width="11" Height="11"
Css="path, circle, rect, ellipse, line, polyline, polygon, text, use { stroke: #F5C842; }" />
<TextBlock Text="90% used" FontSize="11" Foreground="{DynamicResource AccentYellow}" VerticalAlignment="Center" />
</StackPanel>
</Border>
<TextBlock Grid.Column="1" Text="$60 left" FontSize="11" Foreground="{DynamicResource TextMuted}"
VerticalAlignment="Center" />
</Grid>
</StackPanel>
</StackPanel>
</Border>
<!-- ── Over Budget ────────────────────── -->
<TextBlock Text="OVER BUDGET"
Classes="label"
Margin="0,12,0,4" />
<!-- REPLACE: ItemsSource="{Binding OverBudgets}" with DataTemplate -->
<!-- Budget Card — Other (over budget) -->
<Border Background="{DynamicResource BgSurface}"
BorderBrush="{DynamicResource AccentRed}"
BorderThickness="1"
CornerRadius="16"
Padding="20"
Cursor="Hand">
<StackPanel Spacing="14">
<Grid ColumnDefinitions="Auto,*,Auto,Auto">
<Border Grid.Column="0" Background="{DynamicResource IconBgRed}" CornerRadius="10" Width="40" Height="40" Margin="0,0,14,0">
<Svg Path="../Assets/Icons/shopping-bag.svg" Width="18" Height="18" Css="{DynamicResource SvgRed}" />
</Border>
<StackPanel Grid.Column="1" VerticalAlignment="Center" Spacing="2">
<TextBlock Text="Shopping" FontSize="14" FontWeight="SemiBold" Foreground="{DynamicResource TextPrimary}" />
<TextBlock Text="7 transactions" FontSize="11" Foreground="{DynamicResource TextMuted}" />
</StackPanel>
<StackPanel Grid.Column="2" HorizontalAlignment="Right" VerticalAlignment="Center" Spacing="2" Margin="0,0,12,0">
<TextBlock Text="$380" FontSize="14" FontWeight="Bold" Foreground="{DynamicResource AccentRed}" HorizontalAlignment="Right" />
<TextBlock Text="of $300" FontSize="11" Foreground="{DynamicResource TextMuted}" HorizontalAlignment="Right" />
</StackPanel>
<Button Grid.Column="3" Background="Transparent" BorderThickness="0" Padding="4" VerticalAlignment="Center" Cursor="Hand">
<Button.Flyout>
<Flyout Placement="BottomEdgeAlignedRight"
FlyoutPresenterTheme="{StaticResource TransparentFlyoutPresenter}">
<views:BudgetCardMenuView />
</Flyout>
</Button.Flyout>
<Svg Path="../Assets/Icons/ellipsis.svg" Width="15" Height="15" Css="{DynamicResource SvgMuted}" />
</Button>
</Grid>
<StackPanel Spacing="6">
<!-- Clamped to 100 visually, real % shown in badge -->
<ProgressBar Classes="red" Value="100" Minimum="0" Maximum="100" Height="6" />
<Grid ColumnDefinitions="*,Auto">
<Border Grid.Column="0" Background="{DynamicResource BadgeBgRed}" CornerRadius="20" Padding="6,2"
HorizontalAlignment="Left">
<StackPanel Orientation="Horizontal" Spacing="5">
<Svg Path="../Assets/Icons/circle-alert.svg" Width="11" Height="11"
Css="path, circle, rect, ellipse, line, polyline, polygon, text, use { stroke: #FF5E5E; }" />
<TextBlock Text="$80 over budget" FontSize="11" Foreground="{DynamicResource AccentRed}" VerticalAlignment="Center" />
</StackPanel>
</Border>
<TextBlock Grid.Column="1" Text="127%" FontSize="11" Foreground="{DynamicResource AccentRed}" VerticalAlignment="Center" />
</Grid>
</StackPanel>
</StackPanel>
</Border>
</StackPanel>
</ScrollViewer>
<!-- ─────────────────────────────────────
RIGHT — Overview Panel
───────────────────────────────────── -->
<ScrollViewer Grid.Column="1"
VerticalScrollBarVisibility="Auto"
HorizontalScrollBarVisibility="Disabled" Margin="0,0,0,0" Padding="0 0 8 0">
<StackPanel Spacing="14" Margin="0 0 0 28">
<!-- ── Period Overview ───────────────── -->
<Border Background="{DynamicResource BgSurface}"
BorderBrush="{DynamicResource BorderSubtle}"
BorderThickness="1"
CornerRadius="16"
Padding="22">
<StackPanel Spacing="18">
<TextBlock Text="Period Overview"
FontSize="14"
FontWeight="SemiBold"
Foreground="{DynamicResource TextPrimary}" />
<!-- Total budgeted vs spent -->
<StackPanel Spacing="8">
<Grid ColumnDefinitions="*,Auto">
<TextBlock Grid.Column="0" Text="Total Budgeted" FontSize="12" Foreground="{DynamicResource TextMuted}" />
<!-- REPLACE: bind to TotalBudgetedFormatted -->
<TextBlock Grid.Column="1" Text="$1,950" FontSize="13" FontWeight="SemiBold" Foreground="{DynamicResource TextPrimary}" />
</Grid>
<Grid ColumnDefinitions="*,Auto">
<TextBlock Grid.Column="0" Text="Total Spent" FontSize="12" Foreground="{DynamicResource TextMuted}" />
<!-- REPLACE: bind to TotalSpentFormatted -->
<TextBlock Grid.Column="1" Text="$1,609" FontSize="13" FontWeight="SemiBold" Foreground="{DynamicResource TextPrimary}" />
</Grid>
<!-- Overall progress bar -->
<StackPanel Spacing="5" Margin="0,4,0,0">
<!-- REPLACE: Value="{Binding OverallPercentageUsed}" -->
<ProgressBar Classes="green" Value="82" Minimum="0" Maximum="100" Height="8" />
<Grid ColumnDefinitions="*,Auto">
<TextBlock Grid.Column="0" Text="82% of total budget" FontSize="11" Foreground="{DynamicResource TextMuted}" />
<!-- REPLACE: bind to TotalRemainingFormatted -->
<TextBlock Grid.Column="1" Text="$341 left" FontSize="11" Foreground="{DynamicResource AccentGreen}" />
</Grid>
</StackPanel>
</StackPanel>
<Separator />
<!-- Status summary rows -->
<StackPanel Spacing="10">
<!-- On track count -->
<Grid ColumnDefinitions="Auto,*,Auto">
<Border Grid.Column="0"
Background="{DynamicResource IconBgGreen}"
CornerRadius="6"
Width="28" Height="28"
Margin="0,0,10,0">
<Svg Path="../Assets/Icons/check.svg" Width="13" Height="13" Css="{DynamicResource SvgGreen}" />
</Border>
<TextBlock Grid.Column="1" Text="On track" FontSize="13" Foreground="{DynamicResource TextSecondary}"
VerticalAlignment="Center" />
<!-- REPLACE: bind to OnTrackCount -->
<TextBlock Grid.Column="2" Text="3 budgets" FontSize="12" Foreground="{DynamicResource AccentGreen}"
VerticalAlignment="Center" />
</Grid>
<!-- Warning count -->
<Grid ColumnDefinitions="Auto,*,Auto">
<Border Grid.Column="0"
Background="{DynamicResource BadgeBgYellow}"
CornerRadius="6"
Width="28" Height="28"
Margin="0,0,10,0">
<Svg Path="../Assets/Icons/triangle-alert.svg" Width="13" Height="13"
Css="path, circle, rect, ellipse, line, polyline, polygon, text, use { stroke: #F5C842; }" />
</Border>
<TextBlock Grid.Column="1" Text="Approaching limit" FontSize="13" Foreground="{DynamicResource TextSecondary}"
VerticalAlignment="Center" />
<!-- REPLACE: bind to WarningCount -->
<TextBlock Grid.Column="2" Text="2 budgets" FontSize="12" Foreground="{DynamicResource AccentYellow}"
VerticalAlignment="Center" />
</Grid>
<!-- Over budget count -->
<Grid ColumnDefinitions="Auto,*,Auto">
<Border Grid.Column="0"
Background="{DynamicResource BadgeBgRed}"
CornerRadius="6"
Width="28" Height="28"
Margin="0,0,10,0">
<Svg Path="../Assets/Icons/circle-alert.svg" Width="13" Height="13"
Css="path, circle, rect, ellipse, line, polyline, polygon, text, use { stroke: #FF5E5E; }" />
</Border>
<TextBlock Grid.Column="1" Text="Over budget" FontSize="13" Foreground="{DynamicResource TextSecondary}"
VerticalAlignment="Center" />
<!-- REPLACE: bind to OverBudgetCount -->
<TextBlock Grid.Column="2" Text="1 budget" FontSize="12" Foreground="{DynamicResource AccentRed}"
VerticalAlignment="Center" />
</Grid>
</StackPanel>
</StackPanel>
</Border>
<!-- ── Days remaining in period ───────── -->
<Border Background="{DynamicResource BgSurface}"
BorderBrush="{DynamicResource BorderSubtle}"
BorderThickness="1"
CornerRadius="16"
Padding="22">
<StackPanel Spacing="14">
<Grid ColumnDefinitions="Auto,*">
<Border Grid.Column="0"
Background="{DynamicResource IconBgBlue}"
CornerRadius="10"
Width="40" Height="40"
Margin="0,0,14,0">
<Svg Path="../Assets/Icons/calendar-days.svg" Width="18" Height="18" Css="{DynamicResource SvgBlue}" />
</Border>
<StackPanel Grid.Column="1" VerticalAlignment="Center" Spacing="2">
<TextBlock Text="Period Progress" FontSize="13" FontWeight="SemiBold" Foreground="{DynamicResource TextPrimary}" />
<!-- REPLACE: bind to PeriodProgressLabel e.g. "22 of 31 days" -->
<TextBlock Text="22 of 31 days elapsed" FontSize="11" Foreground="{DynamicResource TextMuted}" />
</StackPanel>
</Grid>
<!-- REPLACE: Value="{Binding PeriodDayPercentage}" -->
<ProgressBar Classes="blue" Value="71" Minimum="0" Maximum="100" Height="6" />
<Grid ColumnDefinitions="*,Auto">
<TextBlock Grid.Column="0" Text="Days remaining" FontSize="12" Foreground="{DynamicResource TextMuted}" />
<!-- REPLACE: bind to DaysRemainingLabel -->
<TextBlock Grid.Column="1" Text="9 days" FontSize="12" FontWeight="SemiBold" Foreground="{DynamicResource AccentBlue}" />
</Grid>
<Separator />
<!-- Daily remaining spend -->
<Grid ColumnDefinitions="*,Auto">
<StackPanel Grid.Column="0" Spacing="2">
<TextBlock Text="Daily budget left" FontSize="12" Foreground="{DynamicResource TextMuted}" />
<TextBlock Text="Based on remaining budget ÷ days" FontSize="10" Foreground="{DynamicResource TextDisabled}" />
</StackPanel>
<!-- REPLACE: bind to DailyRemainingFormatted -->
<TextBlock Grid.Column="1"
Text="$37.90"
FontSize="16"
FontWeight="Bold"
Foreground="{DynamicResource TextPrimary}"
VerticalAlignment="Center" />
</Grid>
</StackPanel>
</Border>
<!-- ── Spending Breakdown ─────────────── -->
<Border Background="{DynamicResource BgSurface}"
BorderBrush="{DynamicResource BorderSubtle}"
BorderThickness="1"
CornerRadius="16"
Padding="22">
<StackPanel Spacing="16">
<TextBlock Text="Spending Breakdown"
FontSize="14"
FontWeight="SemiBold"
Foreground="{DynamicResource TextPrimary}" />
<Border Height="150" ClipToBounds="True">
<lvc:PieChart SeriesSource="{Binding SpendingBreakdown}" Height="300" LegendPosition="Hidden" InitialRotation="-180"
MaxAngle="180" FlowDirection="LeftToRight" VerticalAlignment="Top" Background="{DynamicResource BgSurface}">
<lvc:PieChart.SeriesTemplate>
<DataTemplate x:DataType="vm:PieData">
<lvc:XamlPieSeries SeriesName="{Binding Name}"
Values="{Binding Values}"
Fill="{Binding Fill}"
InnerRadius="{Binding InnerRadius}"
ToolTipLabelFormatter="{Binding Formatter}" />
</DataTemplate>
</lvc:PieChart.SeriesTemplate>
</lvc:PieChart>
</Border>
<ItemsControl ItemsSource="{Binding SpendingBreakdown}" Margin="0 16 0 0">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel ItemSpacing="16" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate DataType="vm:PieData">
<StackPanel Orientation="Horizontal" Spacing="4">
<Border Height="10" Width="10" CornerRadius="5" Background="{Binding Bg}" />
<TextBlock Text="{Binding Name}" />
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<!-- REPLACE: ItemsSource="{Binding SpendingBreakdown}" with DataTemplate -->
<!-- Row: Food -->
<!-- <Grid ColumnDefinitions="Auto,*,Auto"> -->
<!-- <Border Grid.Column="0" Background="{DynamicResource IconBgGreen}" CornerRadius="6" Width="10" Height="10" Margin="0,0,10,0" -->
<!-- VerticalAlignment="Center" /> -->
<!-- <TextBlock Grid.Column="1" Text="Food &amp; Dining" FontSize="12" Foreground="{DynamicResource TextSecondary}" -->
<!-- VerticalAlignment="Center" /> -->
<!-- <StackPanel Grid.Column="2" HorizontalAlignment="Right" Spacing="1"> -->
<!-- <TextBlock Text="$340" FontSize="12" FontWeight="SemiBold" Foreground="{DynamicResource TextPrimary}" -->
<!-- HorizontalAlignment="Right" /> -->
<!-- <TextBlock Text="21%" FontSize="10" Foreground="{DynamicResource TextMuted}" HorizontalAlignment="Right" /> -->
<!-- </StackPanel> -->
<!-- </Grid> -->
<!-- Row: Housing -->
<!-- <Grid ColumnDefinitions="Auto,*,Auto"> -->
<!-- <Border Grid.Column="0" Background="{DynamicResource AccentOrange}" CornerRadius="6" Width="10" Height="10" Margin="0,0,10,0" -->
<!-- VerticalAlignment="Center" /> -->
<!-- <TextBlock Grid.Column="1" Text="Housing" FontSize="12" Foreground="{DynamicResource TextSecondary}" VerticalAlignment="Center" /> -->
<!-- <StackPanel Grid.Column="2" HorizontalAlignment="Right" Spacing="1"> -->
<!-- <TextBlock Text="$540" FontSize="12" FontWeight="SemiBold" Foreground="{DynamicResource TextPrimary}" -->
<!-- HorizontalAlignment="Right" /> -->
<!-- <TextBlock Text="34%" FontSize="10" Foreground="{DynamicResource TextMuted}" HorizontalAlignment="Right" /> -->
<!-- </StackPanel> -->
<!-- </Grid> -->
<!-- Row: Transport -->
<!-- <Grid ColumnDefinitions="Auto,*,Auto"> -->
<!-- <Border Grid.Column="0" Background="{DynamicResource AccentBlue}" CornerRadius="6" Width="10" Height="10" Margin="0,0,10,0" -->
<!-- VerticalAlignment="Center" /> -->
<!-- <TextBlock Grid.Column="1" Text="Transport" FontSize="12" Foreground="{DynamicResource TextSecondary}" -->
<!-- VerticalAlignment="Center" /> -->
<!-- <StackPanel Grid.Column="2" HorizontalAlignment="Right" Spacing="1"> -->
<!-- <TextBlock Text="$110" FontSize="12" FontWeight="SemiBold" Foreground="{DynamicResource TextPrimary}" -->
<!-- HorizontalAlignment="Right" /> -->
<!-- <TextBlock Text="7%" FontSize="10" Foreground="{DynamicResource TextMuted}" HorizontalAlignment="Right" /> -->
<!-- </StackPanel> -->
<!-- </Grid> -->
<!-- Row: Shopping (over) -->
<!-- <Grid ColumnDefinitions="Auto,*,Auto"> -->
<!-- <Border Grid.Column="0" Background="{DynamicResource AccentRed}" CornerRadius="6" Width="10" Height="10" Margin="0,0,10,0" -->
<!-- VerticalAlignment="Center" /> -->
<!-- <TextBlock Grid.Column="1" Text="Shopping" FontSize="12" Foreground="{DynamicResource TextSecondary}" -->
<!-- VerticalAlignment="Center" /> -->
<!-- <StackPanel Grid.Column="2" HorizontalAlignment="Right" Spacing="1"> -->
<!-- <TextBlock Text="$380" FontSize="12" FontWeight="SemiBold" Foreground="{DynamicResource AccentRed}" -->
<!-- HorizontalAlignment="Right" /> -->
<!-- <TextBlock Text="24%" FontSize="10" Foreground="{DynamicResource TextMuted}" HorizontalAlignment="Right" /> -->
<!-- </StackPanel> -->
<!-- </Grid> -->
<!-- Row: Leisure -->
<!-- <Grid ColumnDefinitions="Auto,*,Auto"> -->
<!-- <Border Grid.Column="0" Background="{DynamicResource AccentPurple}" CornerRadius="6" Width="10" Height="10" Margin="0,0,10,0" -->
<!-- VerticalAlignment="Center" /> -->
<!-- <TextBlock Grid.Column="1" Text="Entertainment" FontSize="12" Foreground="{DynamicResource TextSecondary}" -->
<!-- VerticalAlignment="Center" /> -->
<!-- <StackPanel Grid.Column="2" HorizontalAlignment="Right" Spacing="1"> -->
<!-- <TextBlock Text="$170" FontSize="12" FontWeight="SemiBold" Foreground="{DynamicResource TextPrimary}" -->
<!-- HorizontalAlignment="Right" /> -->
<!-- <TextBlock Text="11%" FontSize="10" Foreground="{DynamicResource TextMuted}" HorizontalAlignment="Right" /> -->
<!-- </StackPanel> -->
<!-- </Grid> -->
<!-- Row: Health -->
<!-- <Grid ColumnDefinitions="Auto,*,Auto"> -->
<!-- <Border Grid.Column="0" Background="{DynamicResource AccentPink}" CornerRadius="6" Width="10" Height="10" Margin="0,0,10,0" -->
<!-- VerticalAlignment="Center" /> -->
<!-- <TextBlock Grid.Column="1" Text="Health" FontSize="12" Foreground="{DynamicResource TextSecondary}" VerticalAlignment="Center" /> -->
<!-- <StackPanel Grid.Column="2" HorizontalAlignment="Right" Spacing="1"> -->
<!-- <TextBlock Text="$69" FontSize="12" FontWeight="SemiBold" Foreground="{DynamicResource TextPrimary}" -->
<!-- HorizontalAlignment="Right" /> -->
<!-- <TextBlock Text="4%" FontSize="10" Foreground="{DynamicResource TextMuted}" HorizontalAlignment="Right" /> -->
<!-- </StackPanel> -->
<!-- </Grid> -->
</StackPanel>
</Border>
<!-- ── Savings Goal ───────────────────── -->
<Border Background="{DynamicResource BgSurface}"
BorderBrush="{DynamicResource BorderSubtle}"
BorderThickness="1"
CornerRadius="16"
Padding="22">
<StackPanel Spacing="14">
<Grid ColumnDefinitions="*,Auto">
<TextBlock Grid.Column="0"
Text="Savings Goal"
FontSize="14"
FontWeight="SemiBold"
Foreground="{DynamicResource TextPrimary}"
VerticalAlignment="Center" />
<!-- REPLACE: Command="{Binding EditSavingsGoalCommand}" -->
<Button Grid.Column="1"
Background="Transparent"
BorderThickness="0"
Padding="4"
Cursor="Hand">
<Svg Path="../Assets/Icons/pencil.svg" Width="14" Height="14" Css="{DynamicResource SvgMuted}" />
</Button>
</Grid>
<!-- Goal amount vs projected -->
<StackPanel Spacing="6">
<Grid ColumnDefinitions="*,Auto">
<TextBlock Grid.Column="0" Text="Monthly goal" FontSize="12" Foreground="{DynamicResource TextMuted}" />
<!-- REPLACE: bind to SavingsGoalFormatted -->
<TextBlock Grid.Column="1" Text="$500" FontSize="12" FontWeight="SemiBold" Foreground="{DynamicResource TextPrimary}" />
</Grid>
<Grid ColumnDefinitions="*,Auto">
<TextBlock Grid.Column="0" Text="Projected savings" FontSize="12" Foreground="{DynamicResource TextMuted}" />
<!-- REPLACE: bind to ProjectedSavingsFormatted -->
<TextBlock Grid.Column="1" Text="$341" FontSize="12" FontWeight="SemiBold" Foreground="{DynamicResource AccentYellow}" />
</Grid>
</StackPanel>
<!-- REPLACE: Value="{Binding SavingsGoalPercentage}" -->
<ProgressBar Classes="yellow" Value="68" Minimum="0" Maximum="100" Height="6" />
<Border Background="{DynamicResource BadgeBgYellow}"
CornerRadius="10"
Padding="12,8">
<StackPanel Orientation="Horizontal" Spacing="8">
<Svg Path="../Assets/Icons/info.svg" Width="14" Height="14"
Css="path, circle, rect, ellipse, line, polyline, polygon, text, use { stroke: #F5C842; }" />
<TextBlock Text="Reduce spending by $159 to hit your goal"
FontSize="12"
Foreground="{DynamicResource AccentYellow}"
TextWrapping="Wrap"
VerticalAlignment="Center" />
</StackPanel>
</Border>
</StackPanel>
</Border>
</StackPanel>
</ScrollViewer>
</Grid>
</Grid>
</UserControl>

View File

@@ -0,0 +1,13 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
namespace Clario.Views;
public partial class BudgetView : UserControl
{
public BudgetView()
{
InitializeComponent();
}
}

View File

@@ -0,0 +1,504 @@
<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"
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="*">
<!-- ───────────────────────────────────── MAIN CONTENT ───────────────────────────────────── -->
<ScrollViewer Grid.Column="0" HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Auto">
<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" />
</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="$6,850.00" FontSize="{StaticResource FontSizePageTitle}" FontWeight="Bold"
Foreground="{DynamicResource TextPrimary}" />
<StackPanel Orientation="Horizontal" Spacing="6">
<Border Classes="badge-green">
<TextBlock Text="↑ 3.2%"
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="$3,240.00" FontSize="{StaticResource FontSizePageTitle}" FontWeight="Bold"
Foreground="{DynamicResource TextPrimary}" />
<StackPanel Orientation="Horizontal" Spacing="6">
<Border Classes="badge-red">
<TextBlock Text="↑ 5.1%" 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 Text="52.7%" FontSize="{StaticResource FontSizePageTitle}" FontWeight="Bold"
Foreground="{DynamicResource TextPrimary}" />
<ProgressBar Classes="green" Minimum="0" Maximum="100" Value="52.7" />
</StackPanel>
</Border>
</Grid>
<!-- ── Mid Row: Spending Chart + Budget ─ -->
<Grid ColumnDefinitions="*,340" MaxHeight="470">
<!-- Spending Breakdown (placeholder chart area) -->
<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" Background="{DynamicResource BgHover}"
Foreground="{DynamicResource TextSecondary}"
BorderBrush="{DynamicResource BorderAccent}" CornerRadius="{StaticResource RadiusIcon}" Padding="10,6">
<ComboBoxItem Content="This Month" /> <ComboBoxItem Content="Last Month" />
<ComboBoxItem Content="This Quarter" />
</ComboBox>
</Grid>
<lvc:CartesianChart SeriesSource="{Binding ChartData}" Height="250" Background="{DynamicResource BgSurface}"
LegendPosition="Hidden" TooltipPosition="Hidden">
<lvc:CartesianChart.SeriesTemplate>
<DataTemplate x:DataType="vm:ChartData">
<lvc:XamlColumnSeries SeriesName="{Binding Name}" Fill="{Binding Fill}" Values="{Binding Values}" Padding="4"
MaxBarWidth="9999999" YToolTipLabelFormatter="{Binding ToolTipFormatter}" />
</DataTemplate>
</lvc:CartesianChart.SeriesTemplate>
<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 ChartData}" Margin="0 -10 ">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Rows="1" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate x:DataType="vm:ChartData">
<TextBlock Text="{Binding Name}" HorizontalAlignment="Center" Foreground="{DynamicResource TextDisabled}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<Border HorizontalAlignment="Stretch" Height="1" Background="{DynamicResource BorderSubtle}" Margin="5 0" />
<ItemsControl ItemsSource="{Binding ChartData}" Margin="0 -10 0 0 ">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Rows="1" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate x:DataType="vm:ChartData">
<TextBlock Text="{Binding Values, Converter={StaticResource FirstValueConverter},StringFormat='$0,00'}"
HorizontalAlignment="Center"
Foreground="{Binding Fill, Converter={StaticResource SkPaintToBrushConverter}}" FontWeight="SemiBold" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<!-- <Grid RowDefinitions="*,Auto" Height="200"> -->
<!-- <Grid Grid.Row="0" ColumnDefinitions="*,*,*,*,*,*" VerticalAlignment="Stretch"> -->
<!-- <Grid Grid.Column="0" RowDefinitions="*,Auto" Margin="6,0"> -->
<!-- <Border Grid.Row="0" VerticalAlignment="Bottom" CornerRadius="4,4,0,0" -->
<!-- Height="140" Background="{DynamicResource AccentBlue}" /> -->
<!-- <TextBlock Grid.Row="1" Text="Housing" Classes="muted" -->
<!-- HorizontalAlignment="Center" Margin="0,6,0,0" /> -->
<!-- </Grid> -->
<!-- <Grid Grid.Column="1" RowDefinitions="*,Auto" Margin="6,0"> -->
<!-- <Border Grid.Row="0" VerticalAlignment="Bottom" CornerRadius="4,4,0,0" -->
<!-- Height="80" Background="{DynamicResource AccentGreen}" /> -->
<!-- <TextBlock Grid.Row="1" Text="Food" Classes="muted" -->
<!-- HorizontalAlignment="Center" Margin="0,6,0,0" /> -->
<!-- </Grid> -->
<!-- <Grid Grid.Column="2" RowDefinitions="*,Auto" Margin="6,0"> -->
<!-- <Border Grid.Row="0" VerticalAlignment="Bottom" CornerRadius="4,4,0,0" -->
<!-- Height="55" Background="{DynamicResource AccentYellow}" /> -->
<!-- <TextBlock Grid.Row="1" Text="Transport" Classes="muted" -->
<!-- HorizontalAlignment="Center" Margin="0,6,0,0" /> -->
<!-- </Grid> -->
<!-- <Grid Grid.Column="3" RowDefinitions="*,Auto" Margin="6,0"> -->
<!-- <Border Grid.Row="0" VerticalAlignment="Bottom" CornerRadius="4,4,0,0" -->
<!-- Height="45" Background="#FF7E5E" /> -->
<!-- <TextBlock Grid.Row="1" Text="Health" Classes="muted" -->
<!-- HorizontalAlignment="Center" Margin="0,6,0,0" /> -->
<!-- </Grid> -->
<!-- <Grid Grid.Column="4" RowDefinitions="*,Auto" Margin="6,0"> -->
<!-- <Border Grid.Row="0" VerticalAlignment="Bottom" CornerRadius="4,4,0,0" -->
<!-- Height="35" Background="{DynamicResource AccentPurple}" /> -->
<!-- <TextBlock Grid.Row="1" Text="Leisure" Classes="muted" -->
<!-- HorizontalAlignment="Center" Margin="0,6,0,0" /> -->
<!-- </Grid> -->
<!-- <Grid Grid.Column="5" RowDefinitions="*,Auto" Margin="6,0"> -->
<!-- <Border Grid.Row="0" VerticalAlignment="Bottom" CornerRadius="4,4,0,0" -->
<!-- Height="25" Background="{DynamicResource AccentPink}" /> -->
<!-- <TextBlock Grid.Row="1" Text="Other" Classes="muted" -->
<!-- HorizontalAlignment="Center" Margin="0,6,0,0" /> -->
<!-- </Grid> -->
<!-- </Grid> -->
<!-- ~1~ baseline @1@ -->
<!-- <Border Grid.Row="1" Height="1" Background="{DynamicResource BorderSubtle}" -->
<!-- Margin="0,8,0,0" /> -->
<!-- </Grid> -->
<!-- ~1~ Legend amounts @1@ -->
<!-- <Grid ColumnDefinitions="*,*,*,*,*,*"> -->
<!-- <TextBlock Grid.Column="0" Text="$1,200" FontSize="{StaticResource FontSizeMeta}" FontWeight="SemiBold" -->
<!-- Foreground="{DynamicResource AccentBlue}" HorizontalAlignment="Center" /> -->
<!-- <TextBlock Grid.Column="1" Text="$680" FontSize="{StaticResource FontSizeMeta}" FontWeight="SemiBold" -->
<!-- Foreground="{DynamicResource AccentGreen}" HorizontalAlignment="Center" /> -->
<!-- <TextBlock Grid.Column="2" Text="$420" FontSize="{StaticResource FontSizeMeta}" FontWeight="SemiBold" -->
<!-- Foreground="{DynamicResource AccentYellow}" HorizontalAlignment="Center" /> -->
<!-- <TextBlock Grid.Column="3" Text="$340" FontSize="{StaticResource FontSizeMeta}" FontWeight="SemiBold" -->
<!-- Foreground="#FF7E5E" HorizontalAlignment="Center" /> -->
<!-- <TextBlock Grid.Column="4" Text="$290" FontSize="{StaticResource FontSizeMeta}" FontWeight="SemiBold" -->
<!-- Foreground="{DynamicResource AccentPurple}" HorizontalAlignment="Center" /> -->
<!-- <TextBlock Grid.Column="5" Text="$210" FontSize="{StaticResource FontSizeMeta}" FontWeight="SemiBold" -->
<!-- Foreground="{DynamicResource AccentPink}" HorizontalAlignment="Center" /> -->
<!-- </Grid> -->
</StackPanel>
</Border>
<!-- Budget Tracker -->
<Border Grid.Column="1" Classes="card">
<ScrollViewer>
<StackPanel Spacing="20">
<StackPanel>
<TextBlock Text="Budget Tracker" FontSize="{StaticResource FontSizeSectionHeading}" FontWeight="SemiBold"
Foreground="{DynamicResource TextPrimary}" />
<TextBlock Classes="muted" Text="Monthly limits" />
</StackPanel>
<!-- Budget Item 1 -->
<StackPanel Spacing="8">
<Grid ColumnDefinitions="*,Auto">
<StackPanel Grid.Column="0" Orientation="Horizontal" Spacing="4">
<Svg Path="../Assets/Icons/house.svg" Height="13" Width="13"
VerticalAlignment="Center" />
<TextBlock Text="Housing" FontSize="{StaticResource FontSizeBody}" VerticalAlignment="Center"
Foreground="{DynamicResource TextSecondary}" />
</StackPanel>
<TextBlock Grid.Column="1" Text="$1,200 / $1,500" FontSize="{StaticResource FontSizeMeta}"
Foreground="{DynamicResource TextMuted}" />
</Grid>
<ProgressBar Classes="green" Minimum="0" Maximum="100" Value="80" />
</StackPanel>
<Separator />
<!-- Budget Item 2 -->
<StackPanel Spacing="8">
<Grid ColumnDefinitions="*,Auto">
<StackPanel Grid.Column="0" Orientation="Horizontal" Spacing="4">
<Svg Path="../Assets/Icons/hamburger.svg" Height="13" Width="13" />
<TextBlock Text="Food" FontSize="{StaticResource FontSizeBody}"
Foreground="{DynamicResource TextSecondary}" />
</StackPanel>
<TextBlock Grid.Column="1" Text="$680 / $700" FontSize="{StaticResource FontSizeMeta}"
Foreground="{DynamicResource TextMuted}" />
</Grid>
<ProgressBar Classes="yellow" Minimum="0" Maximum="100" Value="97" />
</StackPanel>
<Separator />
<!-- Budget Item 3 -->
<StackPanel Spacing="8">
<Grid ColumnDefinitions="*,Auto">
<StackPanel Grid.Column="0" Orientation="Horizontal" Spacing="4">
<Svg Path="../Assets/Icons/car.svg" Height="13" Width="13" />
<TextBlock Text="Transport" FontSize="{StaticResource FontSizeBody}"
Foreground="{DynamicResource TextSecondary}" />
</StackPanel>
<TextBlock Grid.Column="1" Text="$420 / $400" FontSize="{StaticResource FontSizeMeta}"
Foreground="{DynamicResource AccentRed}" />
</Grid>
<ProgressBar Classes="red" Minimum="0" Maximum="100" Value="105" />
</StackPanel>
<Separator />
<!-- Budget Item 4 -->
<StackPanel Spacing="8">
<Grid ColumnDefinitions="*,Auto">
<StackPanel Grid.Column="0" Orientation="Horizontal" Spacing="4">
<Svg Path="../Assets/Icons/heart-pulse.svg" Height="13" Width="13" />
<TextBlock Text="Health" FontSize="{StaticResource FontSizeBody}"
Foreground="{DynamicResource TextSecondary}" />
</StackPanel>
<TextBlock Grid.Column="1" Text="$340 / $500" FontSize="{StaticResource FontSizeMeta}"
Foreground="{DynamicResource TextMuted}" />
</Grid>
<ProgressBar Classes="green" Minimum="0" Maximum="100" Value="68" />
</StackPanel>
<Separator />
<!-- Budget Item 5 -->
<StackPanel Spacing="8">
<Grid ColumnDefinitions="*,Auto">
<StackPanel Grid.Column="0" Orientation="Horizontal" Spacing="4">
<Svg Path="../Assets/Icons/gamepad-2.svg" Height="13" Width="13" />
<TextBlock Text="Entertainment" FontSize="{StaticResource FontSizeBody}"
Foreground="{DynamicResource TextSecondary}" />
</StackPanel>
<TextBlock Grid.Column="1" Text="$290 / $300" FontSize="{StaticResource FontSizeMeta}"
Foreground="{DynamicResource TextMuted}" />
</Grid>
<ProgressBar Classes="yellow" Minimum="0" Maximum="100" Value="96" />
</StackPanel>
</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 7 days" />
</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>
<!-- Transaction Row Template -->
<Grid ColumnDefinitions="Auto,*,Auto" Margin="0,4,0,0">
<Border Grid.Column="0" Background="{DynamicResource IconBgGreen}" CornerRadius="{StaticResource RadiusControl}"
Width="42" Height="42" Margin="0,0,14,0">
<Svg Path="../Assets/Icons/shopping-cart.svg" Height="18" Width="18"
Css="{DynamicResource SvgGreen}" />
</Border>
<StackPanel Grid.Column="1" VerticalAlignment="Center">
<TextBlock Text="Grocery Shopping" FontSize="{StaticResource FontSizeBody}" FontWeight="SemiBold"
Foreground="{DynamicResource TextSecondary}" />
<TextBlock Text="Food · Mar 5" Classes="muted" />
</StackPanel>
<TextBlock Grid.Column="2" Text="- $127.40" FontSize="{StaticResource FontSizeAmount}" FontWeight="SemiBold"
Foreground="{DynamicResource AccentRed}" VerticalAlignment="Center" />
</Grid>
<Separator />
<Grid ColumnDefinitions="Auto,*,Auto">
<Border Grid.Column="0" Background="{DynamicResource IconBgPurple}" CornerRadius="{StaticResource RadiusControl}"
Width="42" Height="42" Margin="0,0,14,0">
<Svg Path="../Assets/Icons/banknote-arrow-up.svg" Height="18" Width="18"
Css="{DynamicResource SvgPurple}" />
</Border>
<StackPanel Grid.Column="1" VerticalAlignment="Center">
<TextBlock Text="Salary Deposit" FontSize="{StaticResource FontSizeBody}" FontWeight="SemiBold"
Foreground="{DynamicResource TextSecondary}" />
<TextBlock Text="Income · Mar 4" Classes="muted" />
</StackPanel>
<TextBlock Grid.Column="2" Text="+ $3,425.00" FontSize="{StaticResource FontSizeAmount}" FontWeight="SemiBold"
Foreground="{DynamicResource AccentGreen}" VerticalAlignment="Center" />
</Grid>
<Separator />
<Grid ColumnDefinitions="Auto,*,Auto">
<Border Grid.Column="0" Background="{DynamicResource IconBgOrange}" CornerRadius="{StaticResource RadiusControl}"
Width="42" Height="42" Margin="0,0,14,0">
<Svg Path="../Assets/Icons/zap.svg" Height="18" Width="18"
Css="{DynamicResource SvgOrange}" />
</Border>
<StackPanel Grid.Column="1" VerticalAlignment="Center">
<TextBlock Text="Electricity Bill" FontSize="{StaticResource FontSizeBody}" FontWeight="SemiBold"
Foreground="{DynamicResource TextSecondary}" />
<TextBlock Text="Utilities · Mar 3" Classes="muted" />
</StackPanel>
<TextBlock Grid.Column="2" Text="- $88.00" FontSize="{StaticResource FontSizeAmount}" FontWeight="SemiBold"
Foreground="{DynamicResource AccentRed}" VerticalAlignment="Center" />
</Grid>
<Separator />
<Grid ColumnDefinitions="Auto,*,Auto">
<Border Grid.Column="0" Background="{DynamicResource IconBgPink}" CornerRadius="{StaticResource RadiusControl}"
Width="42" Height="42" Margin="0,0,14,0">
<Svg Path="../Assets/Icons/pill.svg" Height="18" Width="18"
Css="{DynamicResource SvgPink}" />
</Border>
<StackPanel Grid.Column="1" VerticalAlignment="Center">
<TextBlock Text="Pharmacy" FontSize="{StaticResource FontSizeBody}" FontWeight="SemiBold"
Foreground="{DynamicResource TextSecondary}" />
<TextBlock Text="Health · Mar 2" Classes="muted" />
</StackPanel>
<TextBlock Grid.Column="2" Text="- $34.50" FontSize="{StaticResource FontSizeAmount}" FontWeight="SemiBold"
Foreground="{DynamicResource AccentRed}" VerticalAlignment="Center" />
</Grid>
<Separator />
<Grid ColumnDefinitions="Auto,*,Auto">
<Border Grid.Column="0" Background="{DynamicResource IconBgGreen}" CornerRadius="{StaticResource RadiusControl}"
Width="42" Height="42" Margin="0,0,14,0">
<Svg Path="../Assets/Icons/hand-coins.svg" Height="18" Width="18"
Css="{DynamicResource SvgGreen}" />
</Border>
<StackPanel Grid.Column="1" VerticalAlignment="Center">
<TextBlock Text="Freelance Payment" FontSize="{StaticResource FontSizeBody}" FontWeight="SemiBold"
Foreground="{DynamicResource TextSecondary}" />
<TextBlock Text="Income · Mar 1" Classes="muted" />
</StackPanel>
<TextBlock Grid.Column="2" Text="+ $850.00" FontSize="{StaticResource FontSizeAmount}" FontWeight="SemiBold"
Foreground="{DynamicResource AccentGreen}" VerticalAlignment="Center" />
</Grid>
</StackPanel>
</Border>
<!-- Accounts Summary -->
<Border Grid.Column="1" Classes="card">
<StackPanel Spacing="18">
<StackPanel>
<TextBlock Text="Accounts" FontSize="{StaticResource FontSizeSectionHeading}" FontWeight="SemiBold"
Foreground="{DynamicResource TextPrimary}" />
<TextBlock Classes="muted" Text="4 linked accounts" />
</StackPanel>
<!-- Account 1 -->
<Border Background="{DynamicResource BgBase}" CornerRadius="{StaticResource RadiusInset}" Padding="14,12"
BorderBrush="{DynamicResource BorderSubtle}" BorderThickness="1">
<Grid ColumnDefinitions="Auto,*,Auto">
<Border Grid.Column="0" Background="{DynamicResource IconBgBlue}" CornerRadius="{StaticResource RadiusIcon}"
Width="36" Height="36" Margin="0,0,12,0">
<Svg Path="../Assets/Icons/landmark.svg" Height="16" Width="16"
Css="{DynamicResource SvgBlue}" />
</Border>
<StackPanel Grid.Column="1" VerticalAlignment="Center">
<TextBlock Text="Main Checking" FontSize="{StaticResource FontSizeMeta}" FontWeight="SemiBold"
Foreground="{DynamicResource TextSecondary}" />
<TextBlock Text="•••• 4821" FontSize="{StaticResource FontSizeLabel}" Classes="muted" />
</StackPanel>
<TextBlock Grid.Column="2" Text="$12,450" FontSize="{StaticResource FontSizeBody}" FontWeight="Bold"
Foreground="{DynamicResource TextPrimary}" VerticalAlignment="Center" />
</Grid>
</Border>
<!-- Account 2 -->
<Border Background="{DynamicResource BgBase}" CornerRadius="{StaticResource RadiusInset}" Padding="14,12"
BorderBrush="{DynamicResource BorderSubtle}" BorderThickness="1">
<Grid ColumnDefinitions="Auto,*,Auto">
<Border Grid.Column="0" Background="{DynamicResource IconBgGreen}" CornerRadius="{StaticResource RadiusIcon}"
Width="36" Height="36" Margin="0,0,12,0">
<Svg Path="../Assets/Icons/piggy-bank.svg" Height="16" Width="16"
Css="{DynamicResource SvgGreen}" />
</Border>
<StackPanel Grid.Column="1" VerticalAlignment="Center">
<TextBlock Text="Savings Account" FontSize="{StaticResource FontSizeMeta}" FontWeight="SemiBold"
Foreground="{DynamicResource TextSecondary}" />
<TextBlock Text="•••• 2034" FontSize="{StaticResource FontSizeLabel}" Classes="muted" />
</StackPanel>
<TextBlock Grid.Column="2" Text="$38,700" FontSize="{StaticResource FontSizeBody}" FontWeight="Bold"
Foreground="{DynamicResource AccentGreen}" VerticalAlignment="Center" />
</Grid>
</Border>
<!-- Account 3 -->
<Border Background="{DynamicResource BgBase}" CornerRadius="{StaticResource RadiusInset}" Padding="14,12"
BorderBrush="{DynamicResource BorderSubtle}" BorderThickness="1">
<Grid ColumnDefinitions="Auto,*,Auto">
<Border Grid.Column="0" Background="{DynamicResource IconBgOrange}"
CornerRadius="{StaticResource RadiusIcon}" Width="36" Height="36" Margin="0,0,12,0">
<Svg Path="../Assets/Icons/credit-card.svg" Height="16" Width="16"
Css="{DynamicResource SvgOrange}" />
</Border>
<StackPanel Grid.Column="1" VerticalAlignment="Center">
<TextBlock Text="Credit Card" FontSize="{StaticResource FontSizeMeta}" FontWeight="SemiBold"
Foreground="{DynamicResource TextSecondary}" />
<TextBlock Text="•••• 9170" FontSize="{StaticResource FontSizeLabel}" Classes="muted" />
</StackPanel>
<TextBlock Grid.Column="2" Text="-$1,830" FontSize="{StaticResource FontSizeBody}" FontWeight="Bold"
Foreground="{DynamicResource AccentRed}" VerticalAlignment="Center" />
</Grid>
</Border>
<!-- Account 4 -->
<Border Background="{DynamicResource BgBase}" CornerRadius="{StaticResource RadiusInset}" Padding="14,12"
BorderBrush="{DynamicResource BorderSubtle}" BorderThickness="1">
<Grid ColumnDefinitions="Auto,*,Auto">
<Border Grid.Column="0" Background="{DynamicResource IconBgPurple}"
CornerRadius="{StaticResource RadiusIcon}" Width="36" Height="36" Margin="0,0,12,0">
<Svg Path="../Assets/Icons/chart-column-big.svg" Height="16" Width="16"
Css="{DynamicResource SvgPurple}" />
</Border>
<StackPanel Grid.Column="1" VerticalAlignment="Center">
<TextBlock Text="Investment" FontSize="{StaticResource FontSizeMeta}" FontWeight="SemiBold"
Foreground="{DynamicResource TextSecondary}" />
<TextBlock Text="Portfolio" FontSize="{StaticResource FontSizeLabel}" Classes="muted" />
</StackPanel>
<TextBlock Grid.Column="2" Text="$35,000" FontSize="{StaticResource FontSizeBody}" FontWeight="Bold"
Foreground="{DynamicResource AccentBlue}" VerticalAlignment="Center" />
</Grid>
</Border>
<!-- Total -->
<Separator />
<Grid ColumnDefinitions="*,Auto">
<TextBlock Grid.Column="0" Text="Total Balance" FontSize="{StaticResource FontSizeBody}" FontWeight="SemiBold"
Foreground="{DynamicResource TextMuted}" />
<TextBlock Grid.Column="1" Text="$84,320" FontSize="{StaticResource FontSizeSectionHeading}" FontWeight="Bold"
Foreground="{DynamicResource TextPrimary}" />
</Grid>
</StackPanel>
</Border>
</Grid>
</StackPanel>
</ScrollViewer>
</Grid>
</UserControl>

View File

@@ -0,0 +1,13 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
namespace Clario.Views;
public partial class DashboardView : UserControl
{
public DashboardView()
{
InitializeComponent();
}
}

View File

@@ -0,0 +1,94 @@
<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"
mc:Ignorable="d" d:DesignWidth="1400" d:DesignHeight="800"
x:Class="Clario.Views.LockscreenView">
<Panel>
<Border ZIndex="3" Background="#d11e1e2e" MinWidth="400" MinHeight="200" HorizontalAlignment="Left" VerticalAlignment="Top"
BorderBrush="{DynamicResource AccentBlue}" BorderThickness="2" Margin="4" CornerRadius="{StaticResource RadiusIcon}">
<Grid RowDefinitions="Auto,*" Margin="12" RowSpacing="12">
<TextBox Grid.Row="0" Height="48" Background="#d1181825" VerticalContentAlignment="Center" Watermark="Search..." Padding="20 0" FontSize="18"/>
<StackPanel Grid.Row="1" Spacing="8">
<Button Classes="nav" Classes.active="True" Content="📸 Camera" Margin="0" Foreground="{DynamicResource TextPrimary}"
HorizontalAlignment="Stretch" FontSize="18"
FontWeight="SemiBold" Padding="8 12" />
<Button Classes="nav" Content="🎵 Music" Margin="0" Foreground="{DynamicResource TextPrimary}" HorizontalAlignment="Stretch" FontSize="18"
FontWeight="SemiBold" Padding="8 12" />
<Button Classes="nav" Content="🌐 Browser" Margin="0" Foreground="{DynamicResource TextPrimary}" HorizontalAlignment="Stretch"
FontSize="18" FontWeight="SemiBold" Padding="8 12" />
<Button Classes="nav" Content="🎮 Game" Margin="0" Foreground="{DynamicResource TextPrimary}" HorizontalAlignment="Stretch" FontSize="18"
FontWeight="SemiBold" Padding="8 12" />
<Button Classes="nav" Content="☁️ Weather" Margin="0" Foreground="{DynamicResource TextPrimary}" HorizontalAlignment="Stretch"
FontSize="18" FontWeight="SemiBold" Padding="8 12" />
</StackPanel>
</Grid>
</Border>
<!-- here I have 2 image layers cuz the blur on 2nd one pulls the edges a bit inwards so the 1st one is there to cover that area -->
<Image ZIndex="-1" Source="../Assets/diner-lonely-road.jpg" Stretch="UniformToFill" />
<Image ZIndex="-1" Source="../Assets/diner-lonely-road.jpg" Stretch="UniformToFill">
<Image.Effect>
<BlurEffect Radius="25"></BlurEffect>
</Image.Effect>
</Image>
<!-- 70% tint -->
<Border Background="#1E2330" Opacity="0.7" />
<!-- Clock - Date -->
<StackPanel HorizontalAlignment="Center" Margin="0 40">
<TextBlock Text="23:31" FontSize="132" HorizontalAlignment="Center" FontWeight="Bold" />
<TextBlock Text="Wednesday - 10 March 2026" FontSize="13" FontWeight="SemiBold" HorizontalAlignment="Center" />
</StackPanel>
<!-- Login -->
<Border VerticalAlignment="Bottom" Width="300" Margin=" 0 80">
<StackPanel>
<!-- pfp with border -->
<Border CornerRadius="25" BorderBrush="#1A2240" BorderThickness="2" Height="54" Width="54">
<Image Source="../Assets/eddypfp.png" Height="50">
<Image.Clip>
<RectangleGeometry Rect="0,0,50,50" RadiusX="25" RadiusY="25"></RectangleGeometry>
</Image.Clip>
</Image>
</Border>
<!-- spacer -->
<Border Height="8" />
<!-- Password textbox + confirm button -->
<Grid ColumnDefinitions="*,Auto" ColumnSpacing="8">
<TextBox Grid.Column="0" Watermark="Password" FontSize="13" Height="36" Padding="12,0" VerticalContentAlignment="Center" Opacity="1" />
<Button Grid.Column="1" Height="36" Width="36" CornerRadius="{DynamicResource RadiusControl}" Background="#7B9CFF"
BorderThickness="1" BorderBrush="{DynamicResource BorderAccent}" Padding="6">
<Svg Path="../Assets/Icons/chevron-right.svg" Css="path { stroke: #0D0F14; }"></Svg>
</Button>
</Grid>
</StackPanel>
</Border>
<!-- Media -->
<Border Width="300" Height="50" Background="#13161E" CornerRadius="{DynamicResource RadiusControl}" VerticalAlignment="Bottom"
Margin="0 20">
<Grid ColumnDefinitions="Auto,*,Auto" Margin="10 0" ColumnSpacing="10">
<Svg Grid.Column="0" Path="../Assets/Icons/audio-lines.svg" Height="25" />
<Grid RowDefinitions="*,Auto" Grid.Column="1" VerticalAlignment="Center">
<TextBlock Grid.Row="0" Text="I just might - Bruno Mars" VerticalAlignment="Center" FontSize="13" />
<Grid Grid.Row="1" ColumnDefinitions="Auto,*,Auto" VerticalAlignment="Bottom" ColumnSpacing="4">
<!-- current time -->
<TextBlock Grid.Column="0" Text="0:52" FontSize="10" Foreground="#7A8090" />
<ProgressBar Grid.Column="1" Maximum="100" Minimum="0" Value="25" Height="3" VerticalAlignment="Center" MinWidth="0" />
<!-- total time -->
<TextBlock Grid.Column="2" Text="3:32" FontSize="10" Foreground="#7A8090" />
</Grid>
</Grid>
<!-- play/pause button -->
<Button Grid.Column="2" Height="30" Width="30" Classes="nav" Padding="6">
<Svg Path="../Assets/Icons/pause.svg" Css="path, rect { stroke: #7A8090; }" />
</Button>
</Grid>
</Border>
</Panel>
</UserControl>

View File

@@ -0,0 +1,13 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
namespace Clario.Views;
public partial class LockscreenView : UserControl
{
public LockscreenView()
{
InitializeComponent();
}
}

192
Clario/Views/MainView.axaml Normal file
View File

@@ -0,0 +1,192 @@
<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="using:Clario.ViewModels"
mc:Ignorable="d" d:DesignWidth="1400" d:DesignHeight="800"
MinWidth="1000" MinHeight="600"
x:Class="Clario.Views.MainView"
x:DataType="vm:MainViewModel">
<Design.DataContext>
<!-- This only sets the DataContext for the previewer in an IDE,
to set the actual DataContext for runtime, set the DataContext property in code (look at App.axaml.cs) -->
<vm:MainViewModel />
</Design.DataContext>
<Grid RowDefinitions="Auto,*">
<Border Grid.Row="0" Background="#7393B3" IsVisible="False">
<!-- Bar -->
<Border Height="30" Background="{DynamicResource BorderAccent}" BorderBrush="{DynamicResource BorderSubtle}" BorderThickness="2" Margin="4 6"
CornerRadius="15">
<!-- Definitions: Content width , Fill, Content width (Fill = full size - (ContentWidth1 + ContentWidth2) -->
<Grid ColumnDefinitions="Auto,*,Auto">
<!-- Menu Button -->
<Button Grid.Column="0" CornerRadius="15 5 5 15" Classes="nav" Padding="8 3">
<Button.Flyout>
<MenuFlyout>
<MenuItem Header="About this Device" Padding="12 4" />
<Separator Margin="4 0" />
<MenuItem Header="Settings" Padding="12 4" />
<Separator Margin="4 0" />
<MenuItem Header="Sleep" Padding="12 4" />
<MenuItem Header="Restart" Padding="12 4" />
<MenuItem Header="Shutdown" Padding="12 4" />
</MenuFlyout>
</Button.Flyout>
<Svg Path="../Assets/Icons/arch.svg" Width="18" Height="18" Margin="8 0" Css="{DynamicResource SvgFillBlue}" />
</Button>
<StackPanel Grid.Column="1" Orientation="Horizontal" Spacing="8">
<!-- Separator -->
<Border Width="1" Background="{DynamicResource BorderSubtle}" Margin="0 5" />
<!-- Window Title -->
<TextBlock Text="Expense Tracker - Dashboard" VerticalAlignment="Center" FontWeight="SemiBold"
Foreground="{DynamicResource TextSecondary}" />
</StackPanel>
<StackPanel Grid.Column="2" Orientation="Horizontal">
<Button CornerRadius="5" Classes="nav" Padding="8 3">
<!-- Media Button -->
<StackPanel Orientation="Horizontal" Spacing="6">
<Svg Path="../Assets/Icons/audio-lines.svg" Css="{DynamicResource SvgSecondary}" Height="16" />
<TextBlock Text="Risk it all - Bruno Mars" VerticalAlignment="Center" FontWeight="SemiBold" FontSize="13"
Foreground="{DynamicResource TextSecondary}" />
</StackPanel>
</Button>
<!-- Separator -->
<Border Width="1" Background="{DynamicResource BorderSubtle}" Margin="0 5" />
<!-- Control Panel -->
<Button CornerRadius="5" Classes="nav" Padding="8 3">
<StackPanel Orientation="Horizontal" Spacing="12">
<Svg Path="../Assets/Icons/battery-charging.svg" Height="20" Css="{DynamicResource SvgSecondary}" />
<Svg Path="../Assets/Icons/volume-2.svg" Height="18" Css="{DynamicResource SvgSecondary}" />
<Svg Path="../Assets/Icons/wifi.svg" Height="18" Css="{DynamicResource SvgSecondary}" />
</StackPanel>
</Button>
<!-- Separator -->
<Border Width="1" Background="{DynamicResource BorderSubtle}" Margin="0 5" />
<!-- Date Time Panel -->
<Button CornerRadius="5 15 15 5" Classes="nav" Padding="12 3">
<TextBlock Text="Tue Mar 10 - 10:23 AM" VerticalAlignment="Center" FontWeight="SemiBold" FontSize="13"
Foreground="{DynamicResource TextSecondary}" />
</Button>
</StackPanel>
<!-- Workspaces ( Center of bar, Regardless of content ) -->
<StackPanel Grid.Column="0" Grid.ColumnSpan="3" VerticalAlignment="Top" HorizontalAlignment="Center" Orientation="Horizontal" Margin="8 2"
Spacing="4">
<Border Width="35" Background="{DynamicResource AccentBlue}" Height="4" CornerRadius="2" /> <!-- Active Workspace -->
<Border Width="25" Background="{DynamicResource IconBgBlue}" Height="4" CornerRadius="2" />
<Border Width="25" Background="{DynamicResource IconBgBlue}" Height="4" CornerRadius="2" />
<Border Width="25" Background="{DynamicResource IconBgBlue}" Height="4" CornerRadius="2" />
<Border Width="25" Background="{DynamicResource IconBgBlue}" Height="4" CornerRadius="2" />
</StackPanel>
</Grid>
</Border>
</Border>
<Grid Grid.Row="1" ColumnDefinitions="220,*">
<!-- ───────────────────────────────────── SIDEBAR ───────────────────────────────────── -->
<Border Grid.Column="0" Background="{DynamicResource BgSidebar}" BorderBrush="{DynamicResource BorderSubtle}"
BorderThickness="0,0,1,0" Padding="16,28,16,24">
<DockPanel>
<!-- Logo / App Name -->
<StackPanel DockPanel.Dock="Top" Margin="0,0,0,36">
<StackPanel Orientation="Horizontal" Spacing="10">
<Border Background="{DynamicResource AccentBlue}" CornerRadius="{StaticResource RadiusIcon}" Width="32" Height="32">
<TextBlock Text="F" FontSize="16" FontWeight="Bold" Foreground="{DynamicResource BgBase}"
HorizontalAlignment="Center" VerticalAlignment="Center" />
</Border>
<StackPanel VerticalAlignment="Center">
<TextBlock Text="Clario" FontSize="17" FontWeight="Bold"
Foreground="{DynamicResource TextPrimary}" />
</StackPanel>
</StackPanel>
</StackPanel>
<!-- User Profile (bottom) -->
<Border DockPanel.Dock="Bottom" Background="{DynamicResource BgSurface}" CornerRadius="{StaticResource RadiusInset}"
Padding="12,10">
<Grid ColumnDefinitions="*,Auto">
<StackPanel Grid.Column="0" Orientation="Horizontal" Spacing="10">
<Border Background="{DynamicResource BorderAccent}" CornerRadius="{StaticResource RadiusPill}" Width="34"
Height="34">
<TextBlock Text="N" FontSize="{StaticResource FontSizeAmount}" FontWeight="Bold"
Foreground="{DynamicResource AccentBlue}" HorizontalAlignment="Center"
VerticalAlignment="Center" />
</Border>
<StackPanel VerticalAlignment="Center">
<TextBlock Text="{Binding Profile.DisplayName}" FontSize="{StaticResource FontSizeBody}" FontWeight="SemiBold"
Foreground="{DynamicResource TextSecondary}" />
</StackPanel>
</StackPanel>
<Button Grid.Column="1" Classes="base" Width="24" Height="24" Padding="2" Focusable="False"
Command="{Binding SwitchThemeCommand}" IsVisible="True">
<Panel>
<Svg Path="../Assets/Icons/sun.svg" Css="{DynamicResource SvgDisabled}"
IsVisible="{Binding !IsDarkTheme}" />
<Svg Path="../Assets/Icons/moon.svg" Css="{DynamicResource SvgDisabled}"
IsVisible="{Binding IsDarkTheme}" />
</Panel>
</Button>
<!-- <Button Grid.Column="1" Classes="base" Width="24" Height="24" Padding="2" Command="{Binding SignOutCommand}"> -->
<!-- <ToolTip.Tip> -->
<!-- signout -->
<!-- </ToolTip.Tip> -->
<!-- </Button> -->
</Grid>
</Border>
<!-- Navigation -->
<StackPanel DockPanel.Dock="Top" Spacing="4">
<TextBlock Classes="label" Text="MAIN" Margin="12,0,0,10" />
<Button Classes="nav" Classes.active="{Binding isOnDashboard}" HorizontalAlignment="Stretch" Command="{Binding GoToDashboardCommand}">
<StackPanel Orientation="Horizontal" Spacing="12">
<Svg Path="../Assets/Icons/layout-dashboard.svg" Height="14" Width="14" />
<TextBlock Text="Dashboard" FontSize="{StaticResource FontSizeBody}" FontWeight="SemiBold" VerticalAlignment="Center" />
</StackPanel>
</Button>
<Button Classes="nav"
Classes.active="{Binding isOnTransactions}"
HorizontalAlignment="Stretch" Command="{Binding GoToTransactionsCommand}">
<StackPanel Orientation="Horizontal" Spacing="12">
<Svg Path="../Assets/Icons/arrow-right-left.svg" Height="14" Width="14" />
<TextBlock Text="Transactions" FontSize="{StaticResource FontSizeBody}" VerticalAlignment="Center" />
</StackPanel>
</Button>
<Button Classes="nav" HorizontalAlignment="Stretch" Classes.active="{Binding isOnAccounts}" Command="{Binding GoToAccountsCommand}">
<StackPanel Orientation="Horizontal" Spacing="12">
<Svg Path="../Assets/Icons/chart-pie.svg" Height="14" Width="14" />
<TextBlock Text="Accounts" FontSize="{StaticResource FontSizeBody}" VerticalAlignment="Center" />
</StackPanel>
</Button>
<Button Classes="nav" HorizontalAlignment="Stretch" Classes.active="{Binding isOnBudget}" Command="{Binding GoToBudgetCommand}">
<StackPanel Orientation="Horizontal" Spacing="12">
<Svg Path="../Assets/Icons/wallet.svg" Height="14" Width="14" />
<TextBlock Text="Budget" FontSize="{StaticResource FontSizeBody}" VerticalAlignment="Center" />
</StackPanel>
</Button>
<TextBlock Classes="label" Text="REPORTS" Margin="12,20,0,10" />
<Button Classes="nav" HorizontalAlignment="Stretch">
<StackPanel Orientation="Horizontal" Spacing="12">
<Svg Path="../Assets/Icons/chart-no-axes-combined.svg" Height="14" Width="14" />
<TextBlock Text="Analytics" FontSize="{StaticResource FontSizeBody}" VerticalAlignment="Center" />
</StackPanel>
</Button>
<TextBlock Classes="label" Text="SYSTEM" Margin="12,20,0,10" />
<Button Classes="nav" HorizontalAlignment="Stretch">
<StackPanel Orientation="Horizontal" Spacing="12">
<Svg Path="../Assets/Icons/settings.svg" Height="14" Width="14" />
<TextBlock Text="Settings" FontSize="{StaticResource FontSizeBody}" VerticalAlignment="Center" />
</StackPanel>
</Button>
</StackPanel>
</DockPanel>
</Border>
<ContentControl Grid.Column="1" Content="{Binding CurrentView}" />
</Grid>
</Grid>
</UserControl>

View File

@@ -0,0 +1,11 @@
using Avalonia.Controls;
namespace Clario.Views;
public partial class MainView : UserControl
{
public MainView()
{
InitializeComponent();
}
}

View File

@@ -0,0 +1,23 @@
<Window xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="using:Clario.ViewModels"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:views="using:Clario.Views"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
MinWidth="1000" MinHeight="600"
x:Class="Clario.Views.MainWindow"
Icon="/Assets/avalonia-logo.ico"
Title="Clario"
x:CompileBindings="False">
<Window.DataTemplates>
<DataTemplate DataType="{x:Type vm:MainViewModel}">
<views:MainView />
</DataTemplate>
<DataTemplate DataType="{x:Type vm:AuthViewModel}">
<views:AuthView />
</DataTemplate>
</Window.DataTemplates>
<ContentControl Content="{Binding}" />
</Window>

View File

@@ -0,0 +1,11 @@
using Avalonia.Controls;
namespace Clario.Views;
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
}

View File

@@ -0,0 +1,640 @@
<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:model="clr-namespace:Clario.Models"
xmlns:cc="clr-namespace:Clario.CustomControls"
mc:Ignorable="d" d:DesignWidth="1180" d:DesignHeight="800"
x:Class="Clario.Views.TransactionsView"
x:DataType="vm:TransactionsViewModel"
x:Name="transactionsControl">
<Design.DataContext>
<vm:TransactionsViewModel />
</Design.DataContext>
<Grid ColumnDefinitions="Auto,*">
<!-- ═══════════════════════════════════════════════════
LEFT PANEL — Summary + Filters
═══════════════════════════════════════════════════ -->
<Border Grid.Column="0"
Width="260"
Background="{DynamicResource BgSurface}"
BorderBrush="{DynamicResource BorderSubtle}"
BorderThickness="0,0,1,0"
Padding="20,28,20,28">
<ScrollViewer VerticalScrollBarVisibility="Auto"
HorizontalScrollBarVisibility="Disabled">
<StackPanel Spacing="0">
<!-- Period header ─
REPLACE: bind TextBlock texts to SelectedPeriodLabel
-->
<TextBlock Text="MARCH 2026"
Classes="label"
Margin="0,0,0,4" />
<TextBlock Text="Summary"
FontSize="15"
FontWeight="SemiBold"
Foreground="{DynamicResource TextPrimary}"
Margin="0,0,0,16" />
<!-- Summary stats — left accent bar style ──
REPLACE: bind each amount + count Text
-->
<StackPanel Spacing="2">
<!-- Income row -->
<Grid ColumnDefinitions="3,*,Auto"
Height="48">
<Border Grid.Column="0"
Background="{DynamicResource AccentGreen}"
CornerRadius="2"
Margin="0,6,0,6" />
<StackPanel Grid.Column="1"
VerticalAlignment="Center"
Margin="12,0,0,0">
<TextBlock Text="Income"
FontSize="11"
Foreground="{DynamicResource TextMuted}" />
<!-- REPLACE: bind to PeriodIncomeFormatted -->
<TextBlock Text="{Binding TotalIncome,StringFormat='$0.00'}"
FontSize="15"
FontWeight="SemiBold"
Foreground="{DynamicResource AccentGreen}" />
</StackPanel>
<!-- REPLACE: bind to IncomeTransactionCount + " transactions" -->
<TextBlock Grid.Column="2"
Text="{Binding IncomeCount}"
FontSize="11"
Foreground="{DynamicResource TextDisabled}"
VerticalAlignment="Center" />
</Grid>
<!-- Expenses row -->
<Grid ColumnDefinitions="3,*,Auto"
Height="48">
<Border Grid.Column="0"
Background="{DynamicResource AccentRed}"
CornerRadius="2"
Margin="0,6,0,6" />
<StackPanel Grid.Column="1"
VerticalAlignment="Center"
Margin="12,0,0,0">
<TextBlock Text="Expenses"
FontSize="11"
Foreground="{DynamicResource TextMuted}" />
<!-- REPLACE: bind to PeriodExpensesFormatted -->
<TextBlock Text="{Binding TotalExpenses,StringFormat='$0.00'}"
FontSize="15"
FontWeight="SemiBold"
Foreground="{DynamicResource AccentRed}" />
</StackPanel>
<!-- REPLACE: bind to ExpenseTransactionCount -->
<TextBlock Grid.Column="2"
Text="{Binding ExpensesCount}"
FontSize="11"
Foreground="{DynamicResource TextDisabled}"
VerticalAlignment="Center" />
</Grid>
<!-- Net row -->
<Grid ColumnDefinitions="3,*"
Height="48">
<Border Grid.Column="0"
Background="{DynamicResource AccentBlue}"
CornerRadius="2"
Margin="0,6,0,6" />
<StackPanel Grid.Column="1"
VerticalAlignment="Center"
Margin="12,0,0,0">
<TextBlock Text="Net saved"
FontSize="11"
Foreground="{DynamicResource TextMuted}" />
<!-- REPLACE: bind to PeriodNetFormatted -->
<TextBlock
FontSize="15"
FontWeight="SemiBold"
Foreground="{DynamicResource AccentBlue}">
<TextBlock.Text>
<MultiBinding Converter="{StaticResource NetworthSumConverter}">
<Binding Path="TotalIncome" />
<Binding Path="TotalExpenses" />
</MultiBinding>
</TextBlock.Text>
</TextBlock>
</StackPanel>
</Grid>
</StackPanel>
<!-- Divider -->
<Separator Margin="0,20,0,20" />
<!-- Filters header + Reset link ──
REPLACE: Command="{Binding ResetFiltersCommand}" on the Button
-->
<Grid ColumnDefinitions="*,Auto" Margin="0,0,0,16">
<TextBlock Grid.Column="0"
Classes="label"
Text="FILTERS"
VerticalAlignment="Center" />
<!-- REPLACE: Command="{Binding ResetFiltersCommand}" -->
<Button Grid.Column="1"
Background="Transparent"
BorderThickness="0"
Padding="0"
Foreground="{DynamicResource AccentBlue}"
FontSize="12"
Cursor="Hand"
Content="Reset"
Command="{Binding ResetFiltersCommand}" />
</Grid>
<!-- Search ──
REPLACE: Text="{Binding SearchQuery, Mode=TwoWay}"
-->
<TextBox Watermark="Search transactions..."
Text="{Binding SearchText}"
FontSize="13"
Height="36"
Padding="12,0"
VerticalContentAlignment="Center"
Margin="0,0,0,14" />
<!-- Date range ─
REPLACE: SelectedIndex="{Binding SelectedDateRangeIndex}"
-->
<TextBlock Classes="label" Text="DATE RANGE" Margin="0,0,0,6" />
<ComboBox HorizontalAlignment="Stretch"
ItemsSource="{Binding DateRangeOptions}"
SelectedItem="{Binding SelectedDateRangeOption}"
Padding="10,8"
FontSize="13"
Margin="0,0,0,8">
</ComboBox>
<cc:DateRangePicker SelectionMode="SingleRange"
Padding="10,8"
HorizontalAlignment="Stretch"
FontSize="13"
SelectedDates="{Binding SelectedDates}"
Margin="0,0,0,14">
<cc:DateRangePicker.IsVisible>
<MultiBinding Converter="{StaticResource EqualValueConverter}">
<Binding Path="SelectedDateRangeOption" />
<Binding Source="Custom Range" />
</MultiBinding>
</cc:DateRangePicker.IsVisible>
</cc:DateRangePicker>
<!-- Type toggle
REPLACE: wire up to SelectedTypeIndex with ToggleButton group or RadioButtons
-->
<TextBlock Classes="label" Text="TYPE" Margin="0,0,0,6" />
<Border Background="{DynamicResource BgBase}"
BorderBrush="{DynamicResource BorderSubtle}"
BorderThickness="1"
CornerRadius="{DynamicResource RadiusControl}"
Padding="3"
Margin="0,0,0,14">
<Grid ColumnDefinitions="*,*,*">
<!-- Active pill -->
<Button Grid.Column="0"
Classes="nav"
Classes.accented="{Binding FilterTypeAll}"
HorizontalAlignment="Stretch"
HorizontalContentAlignment="Center"
Focusable="False"
CornerRadius="7"
Padding="0,6"
Command="{Binding SetTransactionTypeCommand}"
CommandParameter="all">
<TextBlock Text="All"
FontSize="12"
FontWeight="SemiBold"
HorizontalAlignment="Center" />
</Button>
<Button Grid.Column="1"
Classes="nav"
Classes.accented="{Binding FilterTypeIncome}"
HorizontalAlignment="Stretch"
HorizontalContentAlignment="Center"
Focusable="False"
CornerRadius="7"
Padding="0,6"
Command="{Binding SetTransactionTypeCommand}"
CommandParameter="income">
<TextBlock Text="Income"
FontSize="12" Focusable="False"
HorizontalAlignment="Center" />
</Button>
<Button Grid.Column="2"
Classes="nav"
Classes.accented="{Binding FilterTypeExpense}"
HorizontalAlignment="Stretch"
HorizontalContentAlignment="Center"
Focusable="False"
CornerRadius="7"
Padding="0,6"
Command="{Binding SetTransactionTypeCommand}"
CommandParameter="expense">
<TextBlock Text="Expense"
FontSize="12" Focusable="False"
HorizontalAlignment="Center" />
</Button>
</Grid>
</Border>
<!-- Category
REPLACE: ItemsSource="{Binding Categories}" SelectedItem="{Binding SelectedCategory}"
-->
<TextBlock Classes="label" Text="CATEGORY" Margin="0,0,0,6" />
<ComboBox HorizontalAlignment="Stretch"
SelectedItem="{Binding SelectedCategory}"
ItemsSource="{Binding Categories}"
DisplayMemberBinding="{Binding Name}"
Padding="10,8"
FontSize="13"
Margin="0,0,0,14">
</ComboBox>
<!-- Account ─
REPLACE: ItemsSource="{Binding Accounts}" SelectedItem="{Binding SelectedAccount}"
-->
<TextBlock Classes="label" Text="ACCOUNT" Margin="0,0,0,6" />
<ComboBox HorizontalAlignment="Stretch"
ItemsSource="{Binding Accounts}"
SelectedItem="{Binding SelectedAccount}"
DisplayMemberBinding="{Binding Name}"
SelectedIndex="0"
Padding="10,8"
FontSize="13"
Margin="0,0,0,14">
</ComboBox>
<!-- Sort
REPLACE: SelectedItem="{Binding SelectedSort}"
-->
<TextBlock Classes="label" Text="SORT BY" Margin="0,0,0,6" />
<ComboBox HorizontalAlignment="Stretch"
ItemsSource="{Binding SortOptions}"
SelectedItem="{Binding SelectedSortOption}"
SelectedIndex="0"
Padding="10,8"
FontSize="13"
Margin="0 0 0 18">
</ComboBox>
<Button Classes="accented"
Padding="16,9"
VerticalAlignment="Center"
HorizontalAlignment="Stretch"
Command="{Binding LoadPageStrCommand}" CommandParameter="1">
<TextBlock Text="Apply Filters"
FontSize="13"
FontWeight="SemiBold"
Foreground="{DynamicResource BgBase}"
VerticalAlignment="Center"
HorizontalAlignment="Center" />
</Button>
</StackPanel>
</ScrollViewer>
</Border>
<!-- ═══════════════════════════════════════════════════
RIGHT PANEL — Transaction List
═══════════════════════════════════════════════════ -->
<Grid Grid.Column="1" RowDefinitions="Auto,*">
<!-- Top Bar -->
<Grid Grid.Row="0"
ColumnDefinitions="*,Auto"
Margin="28,28,28,0">
<StackPanel Grid.Column="0">
<!-- REPLACE: bind to FilteredTransactionCount -->
<TextBlock Text="46 transactions"
Classes="muted" />
<TextBlock Text="Transactions"
FontSize="26"
FontWeight="Bold"
Foreground="{DynamicResource TextPrimary}"
Margin="0,2,0,0" />
</StackPanel>
<!-- REPLACE: Command="{Binding AddTransactionCommand}" -->
<Button Grid.Column="1"
Classes="accented"
Padding="16,9"
VerticalAlignment="Center">
<StackPanel Orientation="Horizontal" Spacing="8">
<Svg Path="../Assets/Icons/plus.svg"
Width="14" Height="14"
Css="{DynamicResource SvgBase}" />
<TextBlock Text="Add Transaction"
FontSize="13"
FontWeight="SemiBold"
Foreground="{DynamicResource BgBase}"
VerticalAlignment="Center" />
</StackPanel>
</Button>
</Grid>
<ScrollViewer Grid.Row="1" VerticalScrollBarVisibility="Disabled" HorizontalScrollBarVisibility="Auto">
<Grid RowDefinitions="Auto,*,Auto">
<!-- Column Headers -->
<Border Grid.Row="0"
Margin="28,16,28,0"
Background="{DynamicResource BgSurface}"
BorderBrush="{DynamicResource BorderSubtle}"
BorderThickness="1"
CornerRadius="12,12,0,0"
Padding="20,12">
<Grid ColumnDefinitions="44,*,160,120,100,100">
<TextBlock Grid.Column="0"
Classes="label"
Text=""
VerticalAlignment="Center" />
<TextBlock Grid.Column="1"
Classes="label"
Text="DESCRIPTION"
VerticalAlignment="Center" />
<TextBlock Grid.Column="2"
Classes="label"
Text="CATEGORY"
VerticalAlignment="Center"
HorizontalAlignment="Center" />
<TextBlock Grid.Column="3"
Classes="label"
Text="ACCOUNT"
VerticalAlignment="Center"
HorizontalAlignment="Center" />
<TextBlock Grid.Column="4"
Classes="label"
Text="DATE"
VerticalAlignment="Center"
HorizontalAlignment="Center" />
<TextBlock Grid.Column="5"
Classes="label"
Text="AMOUNT"
HorizontalAlignment="Right"
VerticalAlignment="Center" />
</Grid>
</Border>
<!-- Transaction List -->
<!-- REPLACE: ItemsSource="{Binding FilteredTransactions}" with DataTemplate -->
<ScrollViewer Grid.Row="1"
Margin="28,0,28,0"
VerticalScrollBarVisibility="Auto"
HorizontalScrollBarVisibility="Disabled" Name="TransactionsScrollViewer">
<Border Background="{DynamicResource BgSurface}"
BorderBrush="{DynamicResource BorderSubtle}"
BorderThickness="1,0,1,1"
CornerRadius="0,0,0,0">
<StackPanel>
<ItemsControl ItemsSource="{Binding PagedTransactions}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate x:DataType="model:Transaction">
<Panel>
<Border Padding="20,14,20,6" IsVisible="{Binding GroupHeader}">
<TextBlock Text="{Binding Description}"
Classes="label" />
</Border>
<Border Padding="20,12" IsVisible="{Binding !GroupHeader}"
BorderBrush="{DynamicResource BorderSubtle}"
BorderThickness="0,1,0,0">
<Grid ColumnDefinitions="44,*,160,120,100,100">
<Border Grid.Column="0"
CornerRadius="{DynamicResource RadiusIcon}"
Width="34" Height="34"
VerticalAlignment="Center">
<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}}"
Width="16" Height="16"
Css="{Binding Category.Color,Converter={StaticResource HexToColorConverter}, ConverterParameter=css}" />
</Border>
<StackPanel Grid.Column="1"
VerticalAlignment="Center"
Margin="0,0,16,0">
<!-- REPLACE: bind to Transaction.Description -->
<TextBlock Text="{Binding Description}"
FontSize="13"
FontWeight="SemiBold"
Foreground="{DynamicResource TextPrimary}" />
<!-- REPLACE: bind to Transaction.Note -->
<TextBlock Text="{Binding Note}"
FontSize="11"
Foreground="{DynamicResource TextMuted}" />
</StackPanel>
<!-- REPLACE: bind to Transaction.Category -->
<Border Grid.Column="2"
VerticalAlignment="Center"
HorizontalAlignment="Center"
Margin="0,0,0,0">
<StackPanel Orientation="Horizontal" Spacing="6">
<Border
CornerRadius="6"
Padding="6,3">
<Border.Background>
<SolidColorBrush Opacity="0.15"
Color="{Binding Category.Color, Converter={StaticResource HexToColorConverter}, ConverterParameter=color}">
</SolidColorBrush>
</Border.Background>
<StackPanel Orientation="Horizontal" Spacing="5">
<Svg Path="{Binding Category.Icon, Converter={StaticResource SvgPathFromName}}"
Width="11" Height="11"
Css="{Binding Category.Color,Converter={StaticResource HexToColorConverter}, ConverterParameter=css}" />
<TextBlock Text="{Binding Category.Name}"
FontSize="12"
Foreground="{Binding Category.Color, Converter={StaticResource HexToColorConverter}, ConverterParameter=brush}"
VerticalAlignment="Center" />
</StackPanel>
</Border>
</StackPanel>
</Border>
<!-- REPLACE: bind to Transaction.Account -->
<TextBlock Grid.Column="3"
Text="{Binding AccountId, Converter={StaticResource AccountFromIdConverter}}"
FontSize="12"
Foreground="{DynamicResource TextMuted}"
VerticalAlignment="Center"
HorizontalAlignment="Center"
Margin="0,0,0,0" />
<!-- REPLACE: bind to Transaction.DateFormatted -->
<TextBlock Grid.Column="4"
Text="{Binding Date, Converter={StaticResource DateFormatConverter}}"
FontSize="12"
Foreground="{DynamicResource TextMuted}"
VerticalAlignment="Center"
HorizontalAlignment="Center" />
<!-- REPLACE: bind to Transaction.AmountFormatted + AmountColor -->
<TextBlock Grid.Column="5"
Text="{Binding Amount,StringFormat='$0.00'}"
FontSize="13"
FontWeight="SemiBold"
HorizontalAlignment="Right"
Foreground="{Binding Type, Converter={StaticResource AmountColorConverter}}"
VerticalAlignment="Center">
</TextBlock>
</Grid>
</Border>
</Panel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<StackPanel HorizontalAlignment="Center"
VerticalAlignment="Center"
Spacing="12"
Margin="0,60"
IsVisible="{Binding HasNoTransactions}">
<Svg Path="../Assets/Icons/search.svg"
Css="{DynamicResource SvgPrimary}"
Height="40"
Width="40" />
<TextBlock Text="No transactions found"
FontSize="15"
FontWeight="SemiBold"
Foreground="{DynamicResource TextPrimary}"
HorizontalAlignment="Center" />
<TextBlock Text="Try adjusting your filters or search query."
FontSize="13"
Foreground="{DynamicResource TextMuted}"
HorizontalAlignment="Center" />
</StackPanel>
</StackPanel>
</Border>
</ScrollViewer>
<!-- Pagination Footer -->
<Border Grid.Row="2"
Margin="28,0,28,24"
Background="{DynamicResource BgSurface}"
BorderBrush="{DynamicResource BorderSubtle}"
BorderThickness="1"
CornerRadius="0,0,12,12"
Padding="20,12">
<Grid ColumnDefinitions="*,Auto,*">
<!-- Left: result count -->
<!-- REPLACE: bind to PaginationSummaryText -->
<TextBlock Grid.Column="0"
Text="{Binding PaginationSummaryText}"
FontSize="12"
Foreground="{DynamicResource TextMuted}"
VerticalAlignment="Center" />
<!-- Center: page buttons -->
<StackPanel Grid.Column="1"
Orientation="Horizontal"
Spacing="4">
<!-- REPLACE: Command="{Binding PreviousPageCommand}" IsEnabled="{Binding HasPreviousPage}" -->
<Button Classes="base"
Width="32" Height="32"
Padding="0"
HorizontalContentAlignment="Center"
Command="{Binding PreviousPageCommand}">
<Svg Path="../Assets/Icons/chevron-left.svg"
Width="14" Height="14"
Css="{DynamicResource SvgMuted}" />
</Button>
<!-- REPLACE: ItemsSource="{Binding PageNumbers}" — render dynamically -->
<ItemsControl ItemsSource="{Binding VisiblePageNumbers}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Panel>
<Button Background="{DynamicResource AccentBlue}"
CornerRadius="{DynamicResource RadiusSmall}"
Width="32" Height="32" Name="btnActive">
<Button.IsVisible>
<MultiBinding Converter="{StaticResource EqualValueConverter}">
<Binding Path="." />
<Binding Path="DataContext.CurrentPage" ElementName="transactionsControl" />
</MultiBinding>
</Button.IsVisible>
<TextBlock Text="{Binding .}"
FontSize="13"
FontWeight="SemiBold"
Foreground="{DynamicResource BgBase}"
HorizontalAlignment="Center"
VerticalAlignment="Center" />
</Button>
<Button Background="Transparent" IsVisible="{Binding !#btnActive.IsVisible}"
CornerRadius="{DynamicResource RadiusSmall}"
Width="32" Height="32"
Command="{Binding DataContext.LoadPageCommand, ElementName=transactionsControl}"
CommandParameter="{Binding .}">
<TextBlock Text="{Binding .}"
FontSize="13"
Foreground="{DynamicResource TextMuted}"
HorizontalAlignment="Center"
VerticalAlignment="Center" />
</Button>
</Panel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<!-- REPLACE: Command="{Binding NextPageCommand}" IsEnabled="{Binding HasNextPage}" -->
<Button Classes="base"
Width="32" Height="32"
Padding="0"
HorizontalContentAlignment="Center"
Command="{Binding NextPageCommand}">
<Svg Path="../Assets/Icons/chevron-right.svg"
Width="14" Height="14"
Css="{DynamicResource SvgMuted}" />
</Button>
</StackPanel>
<!-- Right: per-page selector -->
<StackPanel Grid.Column="2"
Orientation="Horizontal"
Spacing="8"
HorizontalAlignment="Right"
VerticalAlignment="Center">
<TextBlock Text="Rows per page"
FontSize="12"
Foreground="{DynamicResource TextMuted}"
VerticalAlignment="Center" />
<!-- REPLACE: SelectedItem="{Binding PageSize}" -->
<ComboBox SelectedIndex="{Binding PageSizeIndex}"
Padding="8,4"
FontSize="12"
Width="64">
<ComboBoxItem Content="25" />
<ComboBoxItem Content="50" />
<ComboBoxItem Content="100" />
</ComboBox>
</StackPanel>
</Grid>
</Border>
</Grid>
</ScrollViewer>
</Grid>
</Grid>
</UserControl>

View File

@@ -0,0 +1,19 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
using Clario.Messages;
using CommunityToolkit.Mvvm.Messaging;
namespace Clario.Views;
public partial class TransactionsView : UserControl
{
public TransactionsView()
{
InitializeComponent();
WeakReferenceMessenger.Default.Register<TransactionsScrollToTop>(this, (s, m) =>
{
TransactionsScrollViewer.ScrollToHome();
});
}
}