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

439 lines
24 KiB
XML

<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:cc="clr-namespace:Clario.CustomControls"
xmlns:behaviors="clr-namespace:Clario.Behaviors"
mc:Ignorable="d"
x:Class="Clario.Views.TransactionFormView"
x:DataType="vm:TransactionFormViewModel">
<Design.DataContext>
<vm:TransactionFormViewModel />
</Design.DataContext>
<!-- ── Dim overlay ───────────────────────── -->
<Grid>
<Border Background="#70000000" />
<!-- ── Modal card ────────────────────────── -->
<Border HorizontalAlignment="Center"
VerticalAlignment="Center"
Background="{DynamicResource BgSurface}"
BorderBrush="{DynamicResource BorderSubtle}"
BorderThickness="1"
CornerRadius="18"
Padding="28"
Width="460"
BoxShadow="0 24 72 0 #60000000">
<StackPanel Spacing="0">
<!-- ── Header ──────────────────────── -->
<Grid ColumnDefinitions="Auto,*,Auto" Margin="0,0,0,24">
<Border Grid.Column="0"
CornerRadius="10"
Width="42" Height="42"
Margin="0,0,14,0">
<Border.Background>
<!-- changes with type: red for expense, green for income -->
<SolidColorBrush
Color="{Binding IsExpense, Converter={StaticResource BoolToColorConverter}, ConverterParameter='#FF2A0D0D|#0D2A1A'}" />
</Border.Background>
<Svg Path="../Assets/Icons/arrow-left-right.svg"
Width="18" Height="18"
Css="{Binding IsExpense, Converter={StaticResource BoolToCssConverter}, ConverterParameter='#FF5E5E|#2ECC8A'}" />
</Border>
<StackPanel Grid.Column="1" VerticalAlignment="Center" Spacing="2">
<!-- switches between "New Transaction" / "Edit Transaction" -->
<TextBlock Text="{Binding FormTitle}"
FontSize="16"
FontWeight="Bold"
Foreground="{DynamicResource TextPrimary}" />
<TextBlock Text="{Binding FormSubtitle}"
FontSize="11"
Foreground="{DynamicResource TextMuted}" />
</StackPanel>
<Button Grid.Column="2"
Background="Transparent"
BorderThickness="0"
Padding="6"
VerticalAlignment="Top"
Cursor="Hand"
Command="{Binding CancelCommand}">
<Svg Path="../Assets/Icons/x.svg"
Width="15" Height="15"
Css="{DynamicResource SvgMuted}" />
</Button>
</Grid>
<!-- ── Type toggle ─────────────────── -->
<TextBlock Text="TYPE" Classes="label" Margin="0,0,0,6" />
<Border Background="{DynamicResource BgBase}"
BorderBrush="{DynamicResource BorderSubtle}"
BorderThickness="1"
CornerRadius="{DynamicResource RadiusControl}"
Padding="3"
Margin="0,0,0,20">
<Grid ColumnDefinitions="*,*">
<!-- Expense -->
<Button Grid.Column="0"
Classes="nav"
Classes.accented="{Binding IsExpense}"
HorizontalAlignment="Stretch"
HorizontalContentAlignment="Center"
CornerRadius="7"
Padding="0,8"
Focusable="False"
Command="{Binding SetTypeCommand}"
CommandParameter="expense">
<StackPanel Orientation="Horizontal" Spacing="6">
<Svg Path="../Assets/Icons/arrow-up-right.svg"
Width="13" Height="13" />
<TextBlock Text="Expense"
FontSize="13"
FontWeight="SemiBold"
VerticalAlignment="Center" />
</StackPanel>
</Button>
<!-- Income -->
<Button Grid.Column="1"
Classes="nav"
Classes.accented="{Binding IsIncome}"
HorizontalAlignment="Stretch"
HorizontalContentAlignment="Center"
CornerRadius="7"
Padding="0,8"
Focusable="False"
Command="{Binding SetTypeCommand}"
CommandParameter="income">
<StackPanel Orientation="Horizontal" Spacing="6">
<Svg Path="../Assets/Icons/arrow-down-left.svg"
Width="13" Height="13" />
<TextBlock Text="Income"
FontSize="13"
VerticalAlignment="Center" />
</StackPanel>
</Button>
</Grid>
</Border>
<!-- ── Amount ──────────────────────── -->
<TextBlock Text="AMOUNT" Classes="label" Margin="0,0,0,6" />
<Border Background="{DynamicResource BgBase}"
BorderBrush="{DynamicResource BorderSubtle}"
BorderThickness="1"
CornerRadius="{DynamicResource RadiusControl}"
Padding="14,0"
Margin="0,0,0,16">
<Grid ColumnDefinitions="Auto,*,Auto">
<TextBlock Grid.Column="0"
Text="$"
FontSize="22"
FontWeight="Bold"
Foreground="{DynamicResource TextMuted}"
VerticalAlignment="Center"
Margin="0,0,8,0" />
<TextBox Grid.Column="1"
Classes="ghost"
Text="{Binding Amount, Mode=TwoWay}"
Watermark="0.00"
FontSize="22"
FontWeight="Bold"
Foreground="{DynamicResource TextPrimary}"
Height="54"
Padding="0"
VerticalContentAlignment="Center">
<Interaction.Behaviors>
<behaviors:NumericInputBehavior />
</Interaction.Behaviors>
</TextBox>
<TextBlock Grid.Column="2"
Text="{Binding Currency}"
FontSize="12"
Foreground="{DynamicResource TextDisabled}"
VerticalAlignment="Center" />
</Grid>
</Border>
<!-- ── Description ─────────────────── -->
<TextBlock Text="DESCRIPTION" Classes="label" Margin="0,0,0,6" />
<TextBox Text="{Binding Description, Mode=TwoWay}"
Watermark="e.g. Grocery Shopping"
FontSize="13"
Height="38"
Padding="12,0"
VerticalContentAlignment="Center"
Margin="0,0,0,16" />
<!-- ── Category + Account ──────────── -->
<Grid ColumnDefinitions="*,14,*" Margin="0,0,0,16">
<!-- Category -->
<StackPanel Grid.Column="0" Spacing="6">
<StackPanel Orientation="Horizontal">
<TextBlock Text="CATEGORY" Classes="label" />
<Button Classes="nav" Padding="2 0">
<Svg Path="../Assets/Icons/plus.svg" Height="11" Width="11"></Svg>
</Button>
</StackPanel>
<Border Background="{DynamicResource BgBase}"
BorderBrush="{DynamicResource BorderSubtle}"
BorderThickness="1"
CornerRadius="{DynamicResource RadiusControl}">
<Grid ColumnDefinitions="Auto,*">
<Border Grid.Column="0"
CornerRadius="7"
Width="30" Height="30"
Margin="8,0,0,0"
VerticalAlignment="Center">
<Border.Background>
<SolidColorBrush
Color="{Binding SelectedCategory.Color, Converter={StaticResource HexToColorConverter}, ConverterParameter=color}"
Opacity="0.15" />
</Border.Background>
<Svg Path="{Binding SelectedCategory.Icon, Converter={StaticResource SvgPathFromName}}"
Width="14" Height="14"
Css="{Binding SelectedCategory.Color, Converter={StaticResource HexToColorConverter}, ConverterParameter=css}" />
</Border>
<ComboBox Grid.Column="1"
ItemsSource="{Binding Categories}"
SelectedItem="{Binding SelectedCategory, Mode=TwoWay}"
DisplayMemberBinding="{Binding Name}"
Background="Transparent"
BorderThickness="0"
Padding="8,10"
FontSize="13"
HorizontalAlignment="Stretch" />
</Grid>
</Border>
</StackPanel>
<!-- Account -->
<StackPanel Grid.Column="2" Spacing="6">
<TextBlock Text="ACCOUNT" Classes="label" />
<Border Background="{DynamicResource BgBase}"
BorderBrush="{DynamicResource BorderSubtle}"
BorderThickness="1"
CornerRadius="{DynamicResource RadiusControl}">
<Grid ColumnDefinitions="Auto,*">
<Border Grid.Column="0"
CornerRadius="7"
Width="30" Height="30"
Margin="8,0,0,0"
VerticalAlignment="Center">
<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="14" Height="14"
Css="{Binding SelectedAccount.Color, Converter={StaticResource HexToColorConverter}, ConverterParameter=css}" />
</Border>
<ComboBox Grid.Column="1"
ItemsSource="{Binding Accounts}"
SelectedItem="{Binding SelectedAccount, Mode=TwoWay}"
DisplayMemberBinding="{Binding Name}"
Background="Transparent"
BorderThickness="0"
Padding="8,10"
FontSize="13"
HorizontalAlignment="Stretch" />
</Grid>
</Border>
</StackPanel>
</Grid>
<!-- ── Date ────────────────────────── -->
<TextBlock Text="DATE" Classes="label" Margin="0,0,0,6" />
<Border Background="{DynamicResource BgBase}"
BorderBrush="{DynamicResource BorderSubtle}"
BorderThickness="1"
CornerRadius="{DynamicResource RadiusControl}"
Margin="0,0,0,16">
<Grid ColumnDefinitions="*,Auto">
<cc:DateRangePicker Grid.Column="0"
Classes="ghost"
SelectionMode="SingleDate"
SelectedDates="{Binding Dates}"
HorizontalAlignment="Stretch"
Padding="12,10" />
<Button Grid.Column="1"
Background="Transparent"
BorderThickness="0"
Padding="8,0"
Cursor="Hand"
VerticalAlignment="Center"
Command="{Binding SetTodayCommand}">
<TextBlock Text="Today"
FontSize="11"
Foreground="{DynamicResource AccentBlue}" />
</Button>
</Grid>
</Border>
<!-- ── Note ────────────────────────── -->
<TextBlock Text="NOTE (OPTIONAL)" Classes="label" Margin="0,0,0,6" />
<TextBox Text="{Binding Note, Mode=TwoWay}"
Watermark="Add a note..."
FontSize="13"
Height="38"
Padding="12,0"
VerticalContentAlignment="Center"
Margin="0,0,0,8" />
<!-- ── Validation error ─────────────── -->
<Border Background="{DynamicResource BadgeBgRed}"
BorderBrush="{DynamicResource AccentRed}"
BorderThickness="1"
CornerRadius="10"
Padding="12,8"
Margin="0,8,0,16"
IsVisible="{Binding HasError}">
<StackPanel Orientation="Horizontal" Spacing="8">
<Svg Path="../Assets/Icons/circle-alert.svg"
Width="13" Height="13"
Css="path, circle, rect, ellipse, line, polyline, polygon, text, use { stroke: #FF5E5E; }" />
<TextBlock Text="{Binding ErrorMessage}"
FontSize="12"
Foreground="{DynamicResource AccentRed}"
VerticalAlignment="Center" />
</StackPanel>
</Border>
<!-- ── Delete button (edit mode only) ── -->
<Button HorizontalAlignment="Stretch"
HorizontalContentAlignment="Center"
Background="#1A0808"
BorderBrush="#3A1515"
BorderThickness="1"
CornerRadius="{DynamicResource RadiusControl}"
Padding="0,10"
Margin="0,0,0,10"
IsVisible="{Binding IsEditMode}"
Command="{Binding RequestDeleteCommand}">
<StackPanel Orientation="Horizontal" Spacing="8">
<Svg Path="../Assets/Icons/trash-2.svg"
Width="13" Height="13"
Css="path, circle, rect, ellipse, line, polyline, polygon, text, use { stroke: #FF5E5E; }" />
<TextBlock Text="Delete Transaction"
FontSize="13"
FontWeight="SemiBold"
Foreground="#FF5E5E"
VerticalAlignment="Center" />
</StackPanel>
</Button>
<!-- ── Actions ──────────────────────── -->
<UniformGrid Rows="1">
<Button Classes="base"
Margin="0,0,6,0"
Padding="0,11"
HorizontalAlignment="Stretch"
HorizontalContentAlignment="Center"
FontSize="13"
Content="Cancel"
Command="{Binding CancelCommand}" />
<Button Classes="accented"
Margin="6,0,0,0"
Padding="0,11"
HorizontalAlignment="Stretch"
HorizontalContentAlignment="Center"
IsEnabled="{Binding IsValid}"
Command="{Binding SaveCommand}">
<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="{Binding SaveButtonLabel}"
FontSize="13"
FontWeight="SemiBold"
Foreground="{DynamicResource BgBase}"
VerticalAlignment="Center" />
</StackPanel>
</Button>
</UniformGrid>
</StackPanel>
</Border>
<!-- DELETE CONFIRM MODAL -->
<!-- ── Delete confirm modal ──────────────── -->
<Grid IsVisible="{Binding ShowDeleteConfirm}">
<Border Background="#50000000" />
<Border HorizontalAlignment="Center"
VerticalAlignment="Center"
Background="{DynamicResource BgSurface}"
BorderBrush="{DynamicResource AccentRed}"
BorderThickness="1"
CornerRadius="18"
Padding="28"
Width="340"
BoxShadow="0 24 72 0 #60000000">
<StackPanel Spacing="0">
<!-- Icon -->
<Border Background="#2A0D0D"
CornerRadius="14"
Width="52" Height="52"
HorizontalAlignment="Center"
Margin="0,0,0,16">
<Svg Path="../Assets/Icons/trash-2.svg"
Width="22" Height="22"
Css="path, circle, rect, ellipse, line, polyline, polygon, text, use { stroke: #FF5E5E; }" />
</Border>
<!-- Title -->
<TextBlock Text="Delete Transaction"
FontSize="16"
FontWeight="Bold"
Foreground="{DynamicResource TextPrimary}"
HorizontalAlignment="Center"
Margin="0,0,0,8" />
<!-- Description -->
<TextBlock Text="This action cannot be undone. The transaction will be permanently removed from your records."
FontSize="13"
Foreground="{DynamicResource TextMuted}"
TextWrapping="Wrap"
TextAlignment="Center"
HorizontalAlignment="Center"
Margin="0,0,0,24" />
<!-- Actions -->
<UniformGrid Rows="1">
<Button Classes="base"
Margin="0,0,6,0"
Padding="0,11"
HorizontalAlignment="Stretch"
HorizontalContentAlignment="Center"
FontSize="13"
Content="Cancel"
Command="{Binding CancelDeleteCommand}" />
<Button Margin="6,0,0,0"
Padding="0,11"
HorizontalAlignment="Stretch"
HorizontalContentAlignment="Center"
Background="#FF5E5E"
BorderThickness="0"
CornerRadius="{DynamicResource RadiusControl}"
Command="{Binding ConfirmDeleteCommand}">
<StackPanel Orientation="Horizontal" Spacing="8">
<Svg Path="../Assets/Icons/trash-2.svg"
Width="13" Height="13"
Css="path, circle, rect, ellipse, line, polyline, polygon, text, use { stroke: #FFFFFF; }" />
<TextBlock Text="Delete"
FontSize="13"
FontWeight="SemiBold"
Foreground="#FFFFFF"
VerticalAlignment="Center" />
</StackPanel>
</Button>
</UniformGrid>
</StackPanel>
</Border>
</Grid>
</Grid>
</UserControl>