440 lines
24 KiB
XML
440 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}"
|
|
SelectedDate="{Binding}"
|
|
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> |