complete basic report page
This commit is contained in:
@ -41,6 +41,7 @@
|
||||
<ContentPage.Resources>
|
||||
<ui:NegativeConverter x:Key="negativeConverter"/>
|
||||
<ui:MoneyConverter x:Key="moneyConverter" Absolute="True"/>
|
||||
<ui:MoneyConverter x:Key="moneyRawConverter"/>
|
||||
<ui:BalanceColorConverter x:Key="colorConverter"/>
|
||||
<ui:TimeConverter x:Key="timeConverter" IncludeDate="True"/>
|
||||
<ui:IconConverter x:Key="iconConverter"/>
|
||||
@ -59,52 +60,89 @@
|
||||
</Style>
|
||||
</ContentPage.Resources>
|
||||
|
||||
<ScrollView x:Name="scroller">
|
||||
<StackLayout>
|
||||
<Label Text="{r:Text TrackingChart}" Style="{StaticResource titleLabel}"/>
|
||||
<chart:ChartView HeightRequest="240" Chart="{Binding Chart}"
|
||||
IsVisible="{Binding NoResultChart, Converter={StaticResource negativeConverter}}"/>
|
||||
<Label Text="{r:Text NoResult}" Style="{StaticResource promptLabel}"
|
||||
IsVisible="{Binding NoResultChart}"/>
|
||||
<Grid>
|
||||
<ScrollView x:Name="scroller">
|
||||
<StackLayout>
|
||||
<Grid Margin="0, 10, 0, 0" Padding="8" ColumnSpacing="8" ColumnDefinitions="*, Auto" HeightRequest="24"
|
||||
BackgroundColor="{DynamicResource PromptBackgroundColor}">
|
||||
<StackLayout Grid.Column="1" Orientation="Horizontal" Spacing="6">
|
||||
<Label Text="{r:Text Income}" TextColor="{DynamicResource GreenColor}"
|
||||
VerticalOptions="Center" FontSize="12"/>
|
||||
<Label Text="{Binding Income, Converter={StaticResource moneyConverter}}"
|
||||
TextColor="{DynamicResource TextColor}"
|
||||
VerticalOptions="Center" FontSize="12"/>
|
||||
<Label Text="{r:Text Spending}" TextColor="{DynamicResource RedColor}"
|
||||
VerticalOptions="Center" FontSize="12" Margin="10, 0, 0, 0"/>
|
||||
<Label Text="{Binding Spending, Converter={StaticResource moneyConverter}}"
|
||||
TextColor="{DynamicResource TextColor}"
|
||||
VerticalOptions="Center" FontSize="12"/>
|
||||
<Label Text="{r:Text Balance}"
|
||||
VerticalOptions="Center" FontSize="12" Margin="10, 0, 0, 0"/>
|
||||
<Label Text="{Binding Balance, Converter={StaticResource moneyRawConverter}}"
|
||||
TextColor="{DynamicResource TextColor}"
|
||||
VerticalOptions="Center" FontSize="12"/>
|
||||
</StackLayout>
|
||||
</Grid>
|
||||
<Label Text="{r:Text TrackingChart}" Style="{StaticResource titleLabel}"/>
|
||||
<chart:ChartView HeightRequest="240" Chart="{Binding Chart}"
|
||||
IsVisible="{Binding NoResultChart, Converter={StaticResource negativeConverter}}"/>
|
||||
<Label Text="{r:Text NoResult}" Style="{StaticResource promptLabel}"
|
||||
IsVisible="{Binding NoResultChart}"/>
|
||||
|
||||
<Label Text="{r:Text CategoryRank}" Style="{StaticResource titleLabel}"/>
|
||||
<chart:ChartView HeightRequest="240" Chart="{Binding CategoryChart}"
|
||||
IsVisible="{Binding NoResultCategoryChart, Converter={StaticResource negativeConverter}}"/>
|
||||
<Label Text="{r:Text NoResult}" Style="{StaticResource promptLabel}"
|
||||
IsVisible="{Binding NoResultCategoryChart}"/>
|
||||
<Label Text="{r:Text CategoryRank}" Style="{StaticResource titleLabel}"/>
|
||||
<chart:ChartView HeightRequest="240" Chart="{Binding CategoryChart}"
|
||||
IsVisible="{Binding NoResultCategoryChart, Converter={StaticResource negativeConverter}}"/>
|
||||
<Label Text="{r:Text NoResult}" Style="{StaticResource promptLabel}"
|
||||
IsVisible="{Binding NoResultCategoryChart}"/>
|
||||
|
||||
<Label Text="{r:Text Top10}" Style="{StaticResource titleLabel}"/>
|
||||
<ui:GroupStackLayout IsVisible="{Binding NoResultTopBills, Converter={StaticResource negativeConverter}}"
|
||||
ItemsSource="{Binding TopBills}" RowHeight="50">
|
||||
<Label Text="{r:Text Top10}" Style="{StaticResource titleLabel}"/>
|
||||
<ui:GroupStackLayout IsVisible="{Binding NoResultTopBills, Converter={StaticResource negativeConverter}}"
|
||||
ItemsSource="{Binding TopBills}" RowHeight="50">
|
||||
|
||||
<ui:GroupStackLayout.ItemTemplate>
|
||||
<DataTemplate x:DataType="v:UIBill">
|
||||
<Grid Padding="20, 0" ColumnSpacing="10"
|
||||
ColumnDefinitions="Auto, *, Auto" RowDefinitions="Auto, Auto">
|
||||
<Grid.GestureRecognizers>
|
||||
<TapGestureRecognizer Command="{Binding EditBilling, Source={x:Reference rankPage}}"
|
||||
CommandParameter="{Binding .}"/>
|
||||
</Grid.GestureRecognizers>
|
||||
<ui:TintImage Source="{Binding Icon, Converter={StaticResource iconConverter}}"
|
||||
WidthRequest="26" HeightRequest="20" VerticalOptions="Center"/>
|
||||
<Label Grid.Column="1" Text="{Binding Name}" TextColor="{DynamicResource TextColor}"
|
||||
VerticalOptions="Center"
|
||||
FontSize="Default" FontAttributes="Bold"/>
|
||||
<Label Grid.Column="2" Text="{Binding Amount, Converter={StaticResource moneyConverter}}"
|
||||
TextColor="{Binding Amount, Converter={StaticResource colorConverter}}"
|
||||
VerticalOptions="Center"/>
|
||||
<StackLayout Grid.Row="1" Grid.Column="1" Spacing="6" Orientation="Horizontal">
|
||||
<Label Text="{Binding DateCreation, Converter={StaticResource timeConverter}}"
|
||||
FontSize="10" TextColor="{DynamicResource SecondaryTextColor}"/>
|
||||
<Label Text="{Binding Wallet}"
|
||||
FontSize="10" TextColor="{DynamicResource SecondaryTextColor}"/>
|
||||
</StackLayout>
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
</ui:GroupStackLayout.ItemTemplate>
|
||||
</ui:GroupStackLayout>
|
||||
<Label Text="{r:Text NoResult}" Style="{StaticResource promptLabel}"
|
||||
IsVisible="{Binding NoResultTopBills}"/>
|
||||
</StackLayout>
|
||||
</ScrollView>
|
||||
<ui:GroupStackLayout.ItemTemplate>
|
||||
<DataTemplate x:DataType="v:UIBill">
|
||||
<Grid Padding="20, 0" ColumnSpacing="10"
|
||||
ColumnDefinitions="Auto, *, Auto" RowDefinitions="Auto, Auto">
|
||||
<Grid.GestureRecognizers>
|
||||
<TapGestureRecognizer Command="{Binding EditBilling, Source={x:Reference rankPage}}"
|
||||
CommandParameter="{Binding .}"/>
|
||||
</Grid.GestureRecognizers>
|
||||
<ui:TintImage Source="{Binding Icon, Converter={StaticResource iconConverter}}"
|
||||
WidthRequest="26" HeightRequest="20" VerticalOptions="Center"/>
|
||||
<Label Grid.Column="1" Text="{Binding Name}" TextColor="{DynamicResource TextColor}"
|
||||
VerticalOptions="Center"
|
||||
FontSize="Default" FontAttributes="Bold"/>
|
||||
<Label Grid.Column="2" Text="{Binding Amount, Converter={StaticResource moneyConverter}}"
|
||||
TextColor="{Binding Amount, Converter={StaticResource colorConverter}}"
|
||||
VerticalOptions="Center"/>
|
||||
<StackLayout Grid.Row="1" Grid.Column="1" Spacing="6" Orientation="Horizontal">
|
||||
<Label Text="{Binding DateCreation, Converter={StaticResource timeConverter}}"
|
||||
FontSize="10" TextColor="{DynamicResource SecondaryTextColor}"/>
|
||||
<Label Text="{Binding Wallet}"
|
||||
FontSize="10" TextColor="{DynamicResource SecondaryTextColor}"/>
|
||||
</StackLayout>
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
</ui:GroupStackLayout.ItemTemplate>
|
||||
</ui:GroupStackLayout>
|
||||
<Label Text="{r:Text NoResult}" Style="{StaticResource promptLabel}"
|
||||
IsVisible="{Binding NoResultTopBills}"/>
|
||||
</StackLayout>
|
||||
</ScrollView>
|
||||
|
||||
<ui:BlurryPanel x:Name="panelFilter" VerticalOptions="Start" Opacity="0"
|
||||
BackgroundColor="{DynamicResource WindowBackgroundColor}"
|
||||
HeightRequest="{Binding Height, Source={x:Reference gridFilter}}"/>
|
||||
<Grid x:Name="gridFilter" VerticalOptions="Start" Opacity="0" Padding="10">
|
||||
<ui:SegmentedControl Margin="6, 6, 6, 3" VerticalOptions="Center"
|
||||
SelectedSegmentIndex="{Binding SegmentType, Mode=TwoWay}"
|
||||
SelectedTextColor="{DynamicResource TextColor}"
|
||||
TintColor="{DynamicResource PromptBackgroundColor}">
|
||||
<ui:SegmentedControl.Children>
|
||||
<ui:SegmentedControlOption Text="{r:Text Spending}"/>
|
||||
<ui:SegmentedControlOption Text="{r:Text Income}"/>
|
||||
</ui:SegmentedControl.Children>
|
||||
</ui:SegmentedControl>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</ui:BillingPage>
|
@ -16,13 +16,33 @@ namespace Billing.Views
|
||||
{
|
||||
public partial class RankPage : BillingPage
|
||||
{
|
||||
private static readonly BindableProperty SegmentTypeProperty = Helper.Create<int, RankPage>(nameof(SegmentType), defaultValue: 0, propertyChanged: OnSegmentTypeChanged);
|
||||
private static readonly BindableProperty ChartProperty = Helper.Create<Chart, RankPage>(nameof(Chart));
|
||||
private static readonly BindableProperty CategoryChartProperty = Helper.Create<Chart, RankPage>(nameof(CategoryChart));
|
||||
private static readonly BindableProperty TopBillsProperty = Helper.Create<IList<UIBill>, RankPage>(nameof(TopBills));
|
||||
private static readonly BindableProperty NoResultChartProperty = Helper.Create<bool, RankPage>(nameof(NoResultChart));
|
||||
private static readonly BindableProperty NoResultCategoryChartProperty = Helper.Create<bool, RankPage>(nameof(NoResultCategoryChart));
|
||||
private static readonly BindableProperty NoResultTopBillsProperty = Helper.Create<bool, RankPage>(nameof(NoResultTopBills));
|
||||
private static readonly BindableProperty IncomeProperty = Helper.Create<decimal, RankPage>(nameof(Income));
|
||||
private static readonly BindableProperty SpendingProperty = Helper.Create<decimal, RankPage>(nameof(Spending));
|
||||
private static readonly BindableProperty BalanceProperty = Helper.Create<decimal, RankPage>(nameof(Balance));
|
||||
|
||||
private static void OnSegmentTypeChanged(RankPage page, int old, int @new)
|
||||
{
|
||||
page.type = @new switch
|
||||
{
|
||||
1 => CategoryType.Income,
|
||||
_ => CategoryType.Spending
|
||||
};
|
||||
page.OnFilterCommand(false);
|
||||
page.SetMonth(page.current);
|
||||
}
|
||||
|
||||
public int SegmentType
|
||||
{
|
||||
get => (int)GetValue(SegmentTypeProperty);
|
||||
set => SetValue(SegmentTypeProperty, value);
|
||||
}
|
||||
public Chart Chart
|
||||
{
|
||||
get => (Chart)GetValue(ChartProperty);
|
||||
@ -53,6 +73,9 @@ namespace Billing.Views
|
||||
get => (bool)GetValue(NoResultTopBillsProperty);
|
||||
set => SetValue(NoResultTopBillsProperty, value);
|
||||
}
|
||||
public decimal Income => (decimal)GetValue(IncomeProperty);
|
||||
public decimal Spending => (decimal)GetValue(SpendingProperty);
|
||||
public decimal Balance => (decimal)GetValue(BalanceProperty);
|
||||
|
||||
public Command LeftCommand { get; }
|
||||
public Command RightCommand { get; }
|
||||
@ -63,6 +86,7 @@ namespace Billing.Views
|
||||
private DateTime end;
|
||||
private IEnumerable<Bill> bills;
|
||||
private CategoryType type = CategoryType.Spending;
|
||||
private bool isFilterToggled;
|
||||
|
||||
private readonly SKTypeface font;
|
||||
|
||||
@ -70,6 +94,7 @@ namespace Billing.Views
|
||||
{
|
||||
LeftCommand = new Command(OnLeftCommand);
|
||||
RightCommand = new Command(OnRightCommand);
|
||||
FilterCommand = new Command(OnFilterCommand);
|
||||
EditBilling = new Command(OnEditBilling);
|
||||
|
||||
var style = SKFontManager.Default.GetFontStyles("PingFang SC");
|
||||
@ -79,6 +104,9 @@ namespace Billing.Views
|
||||
}
|
||||
|
||||
InitializeComponent();
|
||||
|
||||
gridFilter.TranslationY = -60;
|
||||
panelFilter.TranslationY = -60;
|
||||
}
|
||||
|
||||
public override void OnLoaded()
|
||||
@ -104,6 +132,36 @@ namespace Billing.Views
|
||||
SetMonth(current.AddMonths(1));
|
||||
}
|
||||
|
||||
private async void OnFilterCommand(object o)
|
||||
{
|
||||
if (o is bool flag)
|
||||
{
|
||||
isFilterToggled = flag;
|
||||
}
|
||||
else
|
||||
{
|
||||
isFilterToggled = !isFilterToggled;
|
||||
}
|
||||
ViewExtensions.CancelAnimations(gridFilter);
|
||||
ViewExtensions.CancelAnimations(panelFilter);
|
||||
if (isFilterToggled)
|
||||
{
|
||||
await Task.WhenAll(
|
||||
gridFilter.TranslateTo(0, 0, easing: Easing.CubicOut),
|
||||
gridFilter.FadeTo(1, easing: Easing.CubicOut),
|
||||
panelFilter.TranslateTo(0, 0, easing: Easing.CubicOut),
|
||||
panelFilter.FadeTo(1, easing: Easing.CubicOut));
|
||||
}
|
||||
else
|
||||
{
|
||||
await Task.WhenAll(
|
||||
gridFilter.TranslateTo(0, -60, easing: Easing.CubicIn),
|
||||
gridFilter.FadeTo(0, easing: Easing.CubicIn),
|
||||
panelFilter.TranslateTo(0, -60, easing: Easing.CubicIn),
|
||||
panelFilter.FadeTo(0, easing: Easing.CubicIn));
|
||||
}
|
||||
}
|
||||
|
||||
private async void OnEditBilling(object o)
|
||||
{
|
||||
if (Tap.IsBusy)
|
||||
@ -130,6 +188,16 @@ namespace Billing.Views
|
||||
bill.Wallet = App.Accounts.FirstOrDefault(a => a.Id == bill.Bill.WalletId)?.Name;
|
||||
}
|
||||
|
||||
private async void RefreshBalance()
|
||||
{
|
||||
var bills = await Task.Run(() => App.Bills.Where(b => b.CreateTime >= current && b.CreateTime <= end));
|
||||
var income = bills.Where(b => b.Amount > 0).Sum(b => b.Amount);
|
||||
var spending = -bills.Where(b => b.Amount < 0).Sum(b => b.Amount);
|
||||
SetValue(IncomeProperty, income);
|
||||
SetValue(SpendingProperty, spending);
|
||||
SetValue(BalanceProperty, income - spending);
|
||||
}
|
||||
|
||||
private void OnBillChecked(object sender, Bill e)
|
||||
{
|
||||
var bill = TopBills.FirstOrDefault(b => b.Bill == e);
|
||||
@ -137,6 +205,7 @@ namespace Billing.Views
|
||||
{
|
||||
UpdateBill(bill);
|
||||
}
|
||||
RefreshBalance();
|
||||
|
||||
Task.Run(App.WriteBills);
|
||||
}
|
||||
@ -158,6 +227,8 @@ namespace Billing.Views
|
||||
_ = Task.Run(() => LoadReportChart(primaryColor, textColor));
|
||||
_ = Task.Run(() => LoadCategoryChart(primaryColor, textColor));
|
||||
_ = Task.Run(LoadTopBills);
|
||||
|
||||
RefreshBalance();
|
||||
}
|
||||
|
||||
private void LoadReportChart(SKColor primaryColor, SKColor textColor)
|
||||
|
Reference in New Issue
Block a user