This commit is contained in:
Gerald Versluis 2024-04-03 15:59:11 +02:00
Родитель 4e7af4bc93
Коммит 9492e91e27
35 изменённых файлов: 672 добавлений и 167 удалений

Просмотреть файл

@ -7,6 +7,7 @@ languages:
- xaml
products:
- dotnet-maui
- dotnet-core
urlFragment: apps-pointofsale
---
@ -30,4 +31,4 @@ This app demonstrates various techniques for building a desktop and mobile appli
* CommunityToolkit.Maui: https://github.com/CommunityToolkit/Maui
* SkiaSharp & Lottie: https://mono.github.io/SkiaSharp.Extended/api/ui-maui/#sklottieview
* MicroCharts: https://github.com/microcharts-dotnet/Microcharts
* Ril.BlazorSignatureCanvas: https://github.com/ResourceWare/Ril.BlazorSignatureCanvas
* Ril.BlazorSignatureCanvas: https://github.com/ResourceWare/Ril.BlazorSignatureCanvas

Просмотреть файл

@ -5,6 +5,8 @@ VisualStudioVersion = 17.0.31611.283
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PointOfSale", "PointOfSale\PointOfSale.csproj", "{88F24BAD-E7CD-4D00-87F4-702FE9AA7077}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PointOfSale.API", "PointOfSale.API\PointOfSale.API.csproj", "{E093156C-2134-4AE3-8C14-96CE94725BBF}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -17,6 +19,10 @@ Global
{88F24BAD-E7CD-4D00-87F4-702FE9AA7077}.Release|Any CPU.ActiveCfg = Release|Any CPU
{88F24BAD-E7CD-4D00-87F4-702FE9AA7077}.Release|Any CPU.Build.0 = Release|Any CPU
{88F24BAD-E7CD-4D00-87F4-702FE9AA7077}.Release|Any CPU.Deploy.0 = Release|Any CPU
{E093156C-2134-4AE3-8C14-96CE94725BBF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E093156C-2134-4AE3-8C14-96CE94725BBF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E093156C-2134-4AE3-8C14-96CE94725BBF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E093156C-2134-4AE3-8C14-96CE94725BBF}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

Просмотреть файл

@ -1,14 +0,0 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Debug",
"type": "comet",
"request": "launch",
"preLaunchTask": "comet: Build"
}
]
}

Просмотреть файл

@ -3,6 +3,7 @@
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:pages="clr-namespace:PointOfSale.Pages"
xmlns:mct="http://schemas.microsoft.com/dotnet/2022/maui/toolkit"
xmlns:b="clr-namespace:PointOfSale.Common.Behaviors"
xmlns:v="clr-namespace:PointOfSale.Pages.Views"
x:Class="PointOfSale.AppShell"
FlyoutWidth="104"
@ -84,20 +85,18 @@
Margin="0,15,0,15"/>
<RadioButton Value="home" IsChecked="True" Grid.Row="1"
ToolTipProperties.Text="Home"
b:CursorBehavior.AttachBehavior="True"
CheckedChanged="OnMenuItemChanged">
<RadioButton.Content>
<Image Source="home.png">
<!--<Image.Behaviors>
<mct:IconTintColorBehavior
TintColor="{Binding IsChecked,
Source={RelativeSource AncestorType={x:Type RadioButton}, AncestorLevel=1,Mode=TemplatedParent},
Converter={StaticResource CheckedColorConverter}}"/>
</Image.Behaviors>-->
</Image>
</RadioButton.Content>
</RadioButton>
<RadioButton Value="dashboard" Grid.Row="2"
ToolTipProperties.Text="Dashboard"
CheckedChanged="OnMenuItemChanged">
<RadioButton.Content>
<Image Source="graph.png">
@ -113,6 +112,7 @@
</RadioButton>
<RadioButton Value="settings" Grid.Row="3"
ToolTipProperties.Text="Settings"
CheckedChanged="OnMenuItemChanged">
<RadioButton.Content>
<Image Source="setting.png">
@ -128,6 +128,7 @@
</RadioButton>
<RadioButton Value="discount" Grid.Row="4"
ToolTipProperties.Text="Discount"
CheckedChanged="OnMenuItemChanged">
<RadioButton.Content>
<Image Source="discount.png">
@ -143,6 +144,7 @@
</RadioButton>
<RadioButton Value="message" Grid.Row="5"
ToolTipProperties.Text="Messages"
CheckedChanged="OnMenuItemChanged">
<RadioButton.Content>
<Image Source="message.png">
@ -158,13 +160,16 @@
</RadioButton>
<RadioButton Value="notification" Grid.Row="6"
ToolTipProperties.Text="Notifications"
CheckedChanged="OnMenuItemChanged">
<RadioButton.Content>
<Image Source="notification.png" />
</RadioButton.Content>
</RadioButton>
<Image Source="logout.png" Margin="0,15,0,15" Grid.Row="7"/>
<Image Source="logout.png"
ToolTipProperties.Text="Logout"
Margin="0,15,0,15" Grid.Row="7"/>
</Grid>
</DataTemplate>
</Shell.FlyoutContentTemplate>

Просмотреть файл

@ -4,5 +4,7 @@
xmlns:p="clr-namespace:PointOfSale.Pages.Handheld"
x:Class="PointOfSale.AppShellMobile"
Title="AppShellMobile">
<ShellContent ContentTemplate="{DataTemplate p:MobileLoginPage}" Route="login"/>
<ShellContent ContentTemplate="{DataTemplate p:OrdersPage}" Route="orders"/>
</Shell>

Просмотреть файл

@ -18,5 +18,6 @@ public partial class AppShellMobile : Shell
Routing.RegisterRoute(nameof(PayPage), typeof(PayPage));
Routing.RegisterRoute(nameof(SignaturePage), typeof(SignaturePage));
Routing.RegisterRoute(nameof(ReceiptPage), typeof(ReceiptPage));
Routing.RegisterRoute(nameof(ScanPage), typeof(ScanPage));
}
}

Просмотреть файл

@ -1,7 +0,0 @@
global using System.Collections.ObjectModel;
global using System.Diagnostics;
global using CommunityToolkit.Mvvm;
global using CommunityToolkit.Mvvm.ComponentModel;
global using CommunityToolkit.Mvvm.Input;
global using PointOfSale.Models;
global using CommunityToolkit.Mvvm.Messaging;

Просмотреть файл

@ -1,7 +1,11 @@
using CommunityToolkit.Maui;
using Microsoft.Maui.LifecycleEvents;
using Microsoft.Maui.Platform;
using MonkeyCache;
using MonkeyCache.FileStore;
using Plugin.Maui.KeyListener;
using SkiaSharp.Views.Maui.Controls.Hosting;
using ZXing.Net.Maui;
#if WINDOWS
using Microsoft.UI;
@ -22,8 +26,10 @@ public static class MauiProgram
var builder = MauiApp.CreateBuilder();
builder
.UseMauiApp<App>()
.UseBarcodeReader()
.UseMauiCommunityToolkit()
.UseSkiaSharp()
.UseKeyListener()
.ConfigureFonts(fonts =>
{
fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
@ -58,6 +64,8 @@ public static class MauiProgram
ModifyEntry();
Barrel.ApplicationId = "com.simplyprofound.pointofsale";
return builder.Build();
}

Просмотреть файл

@ -18,6 +18,7 @@ public static class AppData
new Item(){ Title = "Hot Tea", Price = 4.00, Quantity = 1, Category = ItemCategory.Beverages, Image = "tea.png"},
new Item(){ Title = "Coffee", Price = 4.00, Quantity = 1, Category = ItemCategory.Beverages, Image = "coffee.png"},
new Item(){ Title = "Milk", Price = 5.00, Quantity = 1, Category = ItemCategory.Beverages, Image = "milk.png"},
new Item(){ Title = "Juice", Price = 50.00, Quantity = 1, Category = ItemCategory.Beverages, Image = "juice.png"},
};
public static List<Order> Orders { get; set; } = GenerateOrders();

Просмотреть файл

@ -11,14 +11,14 @@
<handheld:OrderDetailsViewModel/>
</ContentPage.BindingContext>
<Grid RowDefinitions="120, *, 66" Margin="20">
<VerticalStackLayout VerticalOptions="Center" Spacing="8">
<Grid RowDefinitions="Auto, 400, 66" Margin="20">
<VerticalStackLayout VerticalOptions="Start" Spacing="8">
<Label Text="Current Order" Style="{StaticResource LargeTitle}"/>
<Label Text="{Binding Order.Table, StringFormat='TABLE {0}'}"/>
<BoxView Style="{StaticResource HRule}"/>
</VerticalStackLayout>
<CollectionView Grid.Row="1" ItemsSource="{Binding Order.Items}">
<CollectionView Grid.Row="1" ItemsSource="{Binding Order.Items}" VerticalScrollBarVisibility="Never" Background="Transparent">
<CollectionView.ItemTemplate>
<DataTemplate x:DataType="models:Item">
<Grid ColumnDefinitions="160,60,*" ColumnSpacing="8" Margin="0,8" HeightRequest="70">
@ -38,9 +38,8 @@
</CollectionView.Header>
</CollectionView>
<Grid ColumnSpacing="20" ColumnDefinitions="*,*" Grid.Row="2">
<Button Text="Add" Grid.Column="0" Command="{Binding AddCommand}" Style="{StaticResource PrimaryButtonOutline}" HorizontalOptions="Fill"/>
<Button Text="Pay" Grid.Column="1" Command="{Binding PayCommand}" HorizontalOptions="Fill"/>
<Grid Grid.Row="2">
<Button Text="Pay" Command="{Binding PayCommand}" HorizontalOptions="Fill"/>
</Grid>
</Grid>

Просмотреть файл

@ -27,10 +27,4 @@ public partial class OrderDetailsViewModel
Debug.WriteLine(ex.Message);
}
}
[RelayCommand]
async Task Add()
{
// await Shell.Current.GoToAsync($"{nameof(ScanPage)}");
}
}

Просмотреть файл

@ -4,57 +4,148 @@
xmlns:models="clr-namespace:PointOfSale.Models"
xmlns:handheld="clr-namespace:PointOfSale.Pages.Handheld"
xmlns:system="clr-namespace:System;assembly=System.Runtime"
xmlns:toolkit="http://schemas.microsoft.com/dotnet/2022/maui/toolkit"
xmlns:ak="clr-namespace:AlohaKit.Animations;assembly=AlohaKit.Animations"
x:Class="PointOfSale.Pages.Handheld.OrdersPage"
Shell.NavBarIsVisible="False"
x:DataType="handheld:OrdersViewModel"
Title="OrdersPage">
<ContentPage.BindingContext>
<handheld:OrdersViewModel/>
</ContentPage.BindingContext>
<Grid RowDefinitions="120, *, 66" Margin="20">
<VerticalStackLayout VerticalOptions="Center" Spacing="8">
<Grid RowDefinitions="Auto, *, 66" Margin="20,20,20,0">
<VerticalStackLayout VerticalOptions="Start" Spacing="4">
<Label Text="Orders" Style="{StaticResource LargeTitle}"/>
<Label Text="{Binding Source={x:Static system:DateTime.Today}, StringFormat=Date: {0:dddd, MMMM dd yyyy}, FallbackValue='Hello'}"/>
<BoxView Style="{StaticResource HRule}"/>
</VerticalStackLayout>
<CollectionView Grid.Row="1" Grid.RowSpan="2" ItemsSource="{Binding Orders}">
<CollectionView.ItemTemplate>
<DataTemplate x:DataType="models:Order">
<Grid ColumnDefinitions="80,100,*" ColumnSpacing="8" Margin="0,8" HeightRequest="70">
<Grid.GestureRecognizers>
<TapGestureRecognizer Command="{Binding PayCommand}"/>
</Grid.GestureRecognizers>
<Border Stroke="Transparent" StrokeThickness="1" VerticalOptions="Center" HorizontalOptions="Start"
HeightRequest="60" WidthRequest="60" Background="{x:Static models:Order.RandomBrush}"
>
<Border.StrokeShape>
<Ellipse Frame="0,0,60,60" />
</Border.StrokeShape>
<Grid>
<Label Text="{Binding Table}" TextColor="White" VerticalOptions="Center" HorizontalOptions="Center"/>
</Grid>
</Border>
<Label Text="{Binding Total, StringFormat='${0}'}" Grid.Column="1" VerticalOptions="Center"/>
<Label Text="{Binding Status}" Grid.Column="2" VerticalOptions="Center" HorizontalOptions="Start"/>
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
<CollectionView.Header>
<Grid ColumnDefinitions="80,100,*" Margin="0,8" HeightRequest="40" ColumnSpacing="8">
<Grid Grid.Row="1"
ColumnDefinitions="Auto"
toolkit:StateContainer.CurrentState="{Binding PageCurrentState}">
<toolkit:StateContainer.StateViews>
<Grid ColumnDefinitions="80,100,*"
RowDefinitions="40,*"
Margin="0,8"
ColumnSpacing="8"
toolkit:StateView.StateKey="Loading">
<Label Text="Table" Grid.Column="0" VerticalOptions="Center" FontAttributes="Bold"/>
<Label Text="Total" Grid.Column="1" VerticalOptions="Center" FontAttributes="Bold"/>
<Label Text="Status" Grid.Column="2" VerticalOptions="Center" HorizontalOptions="Start" FontAttributes="Bold"/>
</Grid>
</CollectionView.Header>
</CollectionView>
<FlexLayout Grid.Row="2" AlignContent="SpaceAround" JustifyContent="SpaceAround"
<VerticalStackLayout Grid.Row="1" Grid.ColumnSpan="3" x:Name="ListPreview">
<BindableLayout.ItemsSource>
<x:Array Type="{x:Type x:String}">
<x:String>one</x:String>
<x:String>one</x:String>
<x:String>one</x:String>
<x:String>one</x:String>
<x:String>one</x:String>
<x:String>one</x:String>
<x:String>one</x:String>
<x:String>one</x:String>
</x:Array>
</BindableLayout.ItemsSource>
<BindableLayout.ItemTemplate>
<DataTemplate>
<Grid ColumnDefinitions="80,100,*" ColumnSpacing="8" Margin="0,8" HeightRequest="70">
<Border Stroke="Transparent" StrokeThickness="1" VerticalOptions="Center" HorizontalOptions="Start"
HeightRequest="60" WidthRequest="60" Background="{StaticResource NeutralLighter}">
<Border.StrokeShape>
<Ellipse Frame="0,0,60,60" />
</Border.StrokeShape>
<Grid>
<BoxView HeightRequest="30" HorizontalOptions="Fill" VerticalOptions="Center" Color="{StaticResource NeutralLighter}"/>
</Grid>
</Border>
<BoxView HeightRequest="30" Grid.Column="1" HorizontalOptions="Fill" VerticalOptions="Center" Color="{StaticResource NeutralLighter}"/>
<BoxView HeightRequest="30" Grid.Column="2" HorizontalOptions="Fill" VerticalOptions="Center" Color="{StaticResource NeutralLighter}"/>
</Grid>
</DataTemplate>
</BindableLayout.ItemTemplate>
<VerticalStackLayout.Resources>
<ak:StoryBoard x:Key="LoadingBoard" Target="{x:Reference ListPreview}">
<ak:FadeToAnimation Opacity="0.5" Duration="500"/>
<ak:FadeToAnimation Opacity="1" Duration="500"/>
<ak:FadeToAnimation Opacity="0.5" Duration="500"/>
<ak:FadeToAnimation Opacity="1" Duration="500"/>
<ak:FadeToAnimation Opacity="0.5" Duration="500"/>
<ak:FadeToAnimation Opacity="1" Duration="500"/>
</ak:StoryBoard>
</VerticalStackLayout.Resources>
<VerticalStackLayout.Triggers>
<DataTrigger
TargetType="VerticalStackLayout"
Binding="{Binding PageCurrentState}"
Value="Loading">
<DataTrigger.EnterActions>
<ak:BeginAnimation
Animation="{StaticResource LoadingBoard}" />
</DataTrigger.EnterActions>
</DataTrigger>
</VerticalStackLayout.Triggers>
</VerticalStackLayout>
</Grid>
<CollectionView ItemsSource="{Binding Orders}"
VerticalOptions="Start"
HeightRequest="600"
VerticalScrollBarVisibility="Never"
toolkit:StateView.StateKey="Loaded">
<CollectionView.ItemTemplate>
<DataTemplate x:DataType="models:Order">
<Grid ColumnDefinitions="80,100,*" ColumnSpacing="8" Margin="0,8" HeightRequest="70" >
<Grid.GestureRecognizers>
<TapGestureRecognizer Command="{Binding PayCommand}"/>
</Grid.GestureRecognizers>
<Border Stroke="Transparent" StrokeThickness="1" VerticalOptions="Center" HorizontalOptions="Start"
HeightRequest="60" WidthRequest="60" Background="{x:Static models:Order.RandomBrush}">
<Border.StrokeShape>
<Ellipse Frame="0,0,60,60" />
</Border.StrokeShape>
<Grid>
<Label Text="{Binding Table}" TextColor="White" VerticalOptions="Center" HorizontalOptions="Center"/>
</Grid>
</Border>
<Label Text="{Binding Total, StringFormat='${0}'}" Grid.Column="1" VerticalOptions="Center"/>
<Label Text="{Binding Status}" Grid.Column="2" VerticalOptions="Center" HorizontalOptions="Start"/>
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
<CollectionView.Header>
<Grid ColumnDefinitions="80,100,*" Margin="0,8" HeightRequest="40" ColumnSpacing="8">
<Label Text="Table" Grid.Column="0" VerticalOptions="Center" FontAttributes="Bold"/>
<Label Text="Total" Grid.Column="1" VerticalOptions="Center" FontAttributes="Bold"/>
<Label Text="Status" Grid.Column="2" VerticalOptions="Center" HorizontalOptions="Start" FontAttributes="Bold"/>
</Grid>
</CollectionView.Header>
<CollectionView.Footer>
<Grid HeightRequest="66" ColumnSpacing="8">
<!-- buffer for the content to flow behind but above the tabs-->
</Grid>
</CollectionView.Footer>
</CollectionView>
</toolkit:StateContainer.StateViews>
</Grid>
<FlexLayout Grid.Row="2"
AlignContent="SpaceAround"
JustifyContent="SpaceAround"
Background="{StaticResource DarkBg1Transparent}">
<Image Source="home.png"/>
<Image Source="logout.png"/>
<ImageButton Source="logout.png"
Command="{Binding LogOutCommand}"
/>
</FlexLayout>
</Grid>

Просмотреть файл

@ -1,9 +1,11 @@
namespace PointOfSale.Pages.Handheld;

namespace PointOfSale.Pages.Handheld;
public partial class OrdersPage : ContentPage
{
public OrdersPage()
{
InitializeComponent();
}
}
}

Просмотреть файл

@ -1,3 +1,8 @@
using Microsoft.Extensions.Configuration;
using System.Net.Http.Headers;
using System.Reflection;
namespace PointOfSale.Pages.Handheld;
[INotifyPropertyChanged]
@ -6,8 +11,38 @@ public partial class OrdersViewModel
[ObservableProperty]
private ObservableCollection<Order> _orders;
[ObservableProperty]
private string displayName;
[ObservableProperty]
private string displayEmail;
[ObservableProperty]
private ImageSource profilePhoto;
[ObservableProperty]
private string pageCurrentState = "Loading";
[RelayCommand]
public async Task LogOut()
{
var result = await App.Current.MainPage.DisplayAlert("", "Do you want to logout?", "Yes", "Ooops, no");
if (!result)
return;
await Shell.Current.GoToAsync("//login");
}
public OrdersViewModel()
{
_orders = new ObservableCollection<Order>(AppData.Orders);
DelayedLoad().ConfigureAwait(false);
}
private async Task DelayedLoad()
{
await Task.Delay(4000);
PageCurrentState = "Loaded";
}
}

Просмотреть файл

@ -13,7 +13,7 @@
<handheld:PayViewModel/>
</ContentPage.BindingContext>
<Grid RowDefinitions="120,*"
<Grid RowDefinitions="Auto,*"
RowSpacing="20"
Margin="20"
RadioButtonGroup.GroupName="PaymentMethod"
@ -21,7 +21,7 @@
<Grid.GestureRecognizers>
<TapGestureRecognizer Command="{Binding PayCommand}"/>
</Grid.GestureRecognizers>
<VerticalStackLayout VerticalOptions="Center" Spacing="8" Grid.ColumnSpan="2">
<VerticalStackLayout VerticalOptions="Start" Spacing="8" Grid.ColumnSpan="2">
<Label Text="Insert, Tap, Swipe" Style="{StaticResource LargeTitle}"/>
<BoxView Style="{StaticResource HRule}"/>
</VerticalStackLayout>

Просмотреть файл

@ -22,14 +22,14 @@
</ContentPage.Resources>
<Grid RowDefinitions="120,180,40,120,120,*,66"
<Grid RowDefinitions="Auto,180,40,120,120,*,66"
RowSpacing="20"
ColumnDefinitions="*,*"
ColumnSpacing="20"
Margin="20"
RadioButtonGroup.GroupName="ReceiptOption"
>
<VerticalStackLayout VerticalOptions="Center" Spacing="8" Grid.ColumnSpan="2">
<VerticalStackLayout VerticalOptions="Start" Spacing="8" Grid.ColumnSpan="2">
<Label Text="Payment Successful" Style="{StaticResource LargeTitle}"/>
<Label Text="{Binding Order.Total, StringFormat='Your Bill: ${0}'}"/>
<BoxView Style="{StaticResource HRule}"/>

Просмотреть файл

@ -10,11 +10,11 @@
<handheld:SignatureViewModel/>
</ContentPage.BindingContext>
<Grid RowDefinitions="120,180,60,*,66"
<Grid RowDefinitions="Auto,180,60,*,66"
RowSpacing="20"
Margin="20">
<VerticalStackLayout VerticalOptions="Center" Spacing="8">
<VerticalStackLayout VerticalOptions="Start" Spacing="8">
<Label Text="Add Signature" Style="{StaticResource LargeTitle}"/>
<BoxView Style="{StaticResource HRule}"/>
</VerticalStackLayout>

Просмотреть файл

@ -19,7 +19,7 @@
</Style>
</ContentPage.Resources>
<Grid RowDefinitions="120,160,160,160,*,66"
<Grid RowDefinitions="Auto,160,160,160,*,66"
RowSpacing="20"
ColumnDefinitions="*,*"
ColumnSpacing="20"
@ -27,7 +27,7 @@
RadioButtonGroup.GroupName="TipAmount"
RadioButtonGroup.SelectedValue="{Binding Tip}"
>
<VerticalStackLayout VerticalOptions="Center" Spacing="8" Grid.ColumnSpan="2">
<VerticalStackLayout VerticalOptions="Start" Spacing="8" Grid.ColumnSpan="2">
<Label Text="Add a Tip" Style="{StaticResource LargeTitle}"/>
<Label Text="{Binding Order.Total, StringFormat='Your Bill: ${0}'}"/>
<BoxView Style="{StaticResource HRule}"/>
@ -112,7 +112,8 @@
</Label>
</RadioButton.Content>
</RadioButton>
<Button Grid.Row="5" HorizontalOptions="Fill" Grid.ColumnSpan="2" Text="Continue" Command="{Binding ContinueCommand}"/>
<Button Grid.Row="5" HorizontalOptions="Fill" Grid.Column="0" Text="Add Coupon" Command="{Binding AddCommand}" Style="{StaticResource SecondaryButtonOutline}"/>
<Button Grid.Row="5" HorizontalOptions="Fill" Grid.Column="1" Text="Continue" Command="{Binding ContinueCommand}"/>
</Grid>
</ContentPage>

Просмотреть файл

@ -25,4 +25,10 @@ public partial class TipViewModel
};
await Shell.Current.GoToAsync($"{nameof(PayPage)}", navigationParameter);
}
[RelayCommand]
async Task Add()
{
await Shell.Current.GoToAsync($"{nameof(ScanPage)}");
}
}

Просмотреть файл

@ -6,6 +6,7 @@
xmlns:pages="clr-namespace:PointOfSale.Pages"
xmlns:m="clr-namespace:PointOfSale.Models"
xmlns:l="clr-namespace:CustomLayouts"
xmlns:b="clr-namespace:PointOfSale.Common.Behaviors"
xmlns:system="clr-namespace:System;assembly=System.Runtime"
x:DataType="pages:HomeViewModel"
x:Class="PointOfSale.Pages.HomePage"
@ -19,24 +20,34 @@
<ContentPage.MenuBarItems>
<MenuBarItem Text="File">
<MenuFlyoutItem Text="Preferences"
ParentChanged="MenuFlyoutItem_ParentChanged"
Command="{Binding PreferencesCommand}" />
</MenuBarItem>
<MenuBarItem Text="Products">
<MenuFlyoutItem Text="Add Product" Command="{Binding AddProductCommand}"
ParentChanged="MenuFlyoutItem_ParentChanged"/>
<MenuFlyoutItem Text="Add Product Category"/>
<MenuFlyoutItem Text="Add Product"
Command="{Binding AddProductCommand}">
<MenuFlyoutItem.KeyboardAccelerators>
<KeyboardAccelerator Key="A" Modifiers="Cmd,Shift"/>
<KeyboardAccelerator Key="A" Modifiers="Ctrl"/>
</MenuFlyoutItem.KeyboardAccelerators>
<MenuFlyoutItem.IconImageSource>
<FontImageSource Glyph="&#xECDC;"
Size="12"
Color="Black"
FontFamily="Fabric" />
</MenuFlyoutItem.IconImageSource>
</MenuFlyoutItem>
<MenuFlyoutItem Text="Add Product Category"
IconImageSource="{FontImage &#xF12B;, FontFamily=Fabric, Color=Black, Size=12}"
/>
</MenuBarItem>
</ContentPage.MenuBarItems>
<Grid RowDefinitions="100,70,*"
ColumnDefinitions="*,400"
Margin="24,24,0,0"
x:Name="PageGrid">
Margin="24,24,0,0"
x:Name="PageGrid">
<ScrollView Grid.Row="2">
<Grid RowDefinitions="70,*">
<Label Text="Choose Dishes" Style="{StaticResource Title1}"/>
@ -47,34 +58,72 @@
<BindableLayout.ItemTemplate>
<DataTemplate x:DataType="m:Item">
<Grid RowDefinitions="30,230" WidthRequest="200">
<Grid.Behaviors>
<b:CursorBehavior/>
</Grid.Behaviors>
<Grid.GestureRecognizers>
<DragGestureRecognizer
DragStarting="OnDragStarting"
DropCompleted="OnDropCompleted"
/>
</Grid.GestureRecognizers>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="DefaultStates">
<VisualState x:Name="PointerOver">
<VisualState.Setters>
<Setter
TargetName="CardBg"
Property="Border.Background"
Value="{StaticResource Primary}"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Normal">
<VisualState.Setters>
<Setter
TargetName="CardBg"
Property="Border.Background"
Value="{StaticResource DarkBg2Brush}"/>
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<FlyoutBase.ContextFlyout>
<MenuFlyout>
<MenuFlyoutItem Text="Edit Details"
CommandParameter="docs" />
<MenuFlyoutItem Text="Remove"
CommandParameter="eng" />
</MenuFlyout>
</FlyoutBase.ContextFlyout>
<Border Background="{StaticResource DarkBg2Brush}"
Stroke="{StaticResource DarkBg2Brush}"
StrokeThickness="1"
Grid.Row="1"
x:Name="CardBg"
>
<Border.StrokeShape>
<RoundRectangle CornerRadius="16"/>
</Border.StrokeShape>
</Border>
<VerticalStackLayout Grid.RowSpan="2" Margin="20,0,20,20"
<VerticalStackLayout Grid.RowSpan="2" Margin="20,0,20,10"
VerticalOptions="End"
Spacing="6">
<Label Text="{Binding Title}" HorizontalOptions="Center" Style="{StaticResource Title2}" HorizontalTextAlignment="Center"/>
<Label Text="{Binding Price, StringFormat='${0}'}" HorizontalOptions="Center"/>
<!--<Label Text="20 Bowls available" HorizontalOptions="Center" Style="{StaticResource Subhead}"/>-->
<Label Text="{Binding Price, StringFormat='{0:C}'}" HorizontalOptions="Center"/>
</VerticalStackLayout>
<Image
Grid.RowSpan="2" VerticalOptions="Start"
Source="{Binding Image, FallbackValue=food_01.png}" HorizontalOptions="Center"/>
Margin="0,-20,0,0"
Source="{Binding Image, FallbackValue=food_01.png}"
HorizontalOptions="Center"/>
</Grid>
</DataTemplate>
</BindableLayout.ItemTemplate>
</l:HorizontalWrapLayout>
</Grid>
</ScrollView>
@ -122,9 +171,7 @@
/>
<HorizontalStackLayout Spacing="20"
RadioButtonGroup.GroupName="MenuCategories"
RadioButtonGroup.SelectedValue="{Binding Category}"
>
RadioButtonGroup.SelectedValue="{Binding Category}">
<BindableLayout.ItemsSource>
<x:Array Type="{x:Type x:String}">
<x:String>Noodles</x:String>
@ -140,6 +187,9 @@
<RadioButton.ControlTemplate>
<ControlTemplate>
<Grid RowDefinitions="30,4">
<Grid.Behaviors>
<b:CursorBehavior/>
</Grid.Behaviors>
<VisualStateManager.VisualStateGroups>
<VisualStateGroupList>
<VisualStateGroup x:Name="CheckedStates">
@ -168,6 +218,32 @@
Value="Transparent"/>
</VisualState.Setters>
</VisualState>
<!-- <VisualState x:Name="PointerOver">
<VisualState.Setters>
<Setter
TargetName="TextLabel"
Property="Label.TextColor"
Value="{StaticResource Primary}"/>
<Setter
TargetName="Indicator"
Property="BoxView.Color"
Value="{StaticResource Primary}"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Normal">
<VisualState.Setters>
<Setter
TargetName="TextLabel"
Property="Label.TextColor"
Value="White"/>
<Setter
TargetName="Indicator"
Property="BoxView.Color"
Value="Transparent"/>
</VisualState.Setters>
</VisualState> -->
</VisualStateGroup>
</VisualStateGroupList>
</VisualStateManager.VisualStateGroups>
@ -181,11 +257,26 @@
</DataTemplate>
</BindableLayout.ItemTemplate>
</HorizontalStackLayout>
</Grid>
<v:OrderCartView Grid.Column="1" Grid.RowSpan="3"/>
<BoxView Color="Black"
Opacity="0"
Grid.RowSpan="3" Grid.ColumnSpan="2"
HorizontalOptions="Fill"
VerticalOptions="Fill"
Margin="-24"
InputTransparent="True"
x:Name="BlockScreen"
/>
<v:OrderCartView Grid.Column="1" Grid.RowSpan="3">
<v:OrderCartView.GestureRecognizers>
<DropGestureRecognizer
DragOver="OnDragOver"
Drop="OnDrop"/>
</v:OrderCartView.GestureRecognizers>
</v:OrderCartView>
</Grid>
</ContentPage>

Просмотреть файл

@ -1,21 +1,29 @@
using Microsoft.Maui.Controls.Platform;
using Microsoft.Maui.Platform;
using PointOfSale.Messages;
#if IOS || MACCATALYST
using UIKit;
#endif
namespace PointOfSale.Pages;
public partial class HomePage : ContentPage
{
public HomePage()
{
InitializeComponent();
}
WeakReferenceMessenger.Default.Register<AddProductMessage>(this, (r, m) =>
{
protected override void OnNavigatedTo(NavigatedToEventArgs args)
{
base.OnNavigatedTo(args);
WeakReferenceMessenger.Default.Register<AddProductMessage>(this, (r, m) =>
{
NavSubContent(m.Value);
});
});
}
void MenuFlyoutItem_ParentChanged(System.Object sender, System.EventArgs e)
@ -26,7 +34,7 @@ public partial class HomePage : ContentPage
public void NavSubContent(bool show)
public async void NavSubContent(bool show)
{
var displayWidth = DeviceDisplay.Current.MainDisplayInfo.Width;
@ -37,8 +45,12 @@ public partial class HomePage : ContentPage
Grid.SetRowSpan(addForm, 3);
// translate off screen right
addForm.TranslationX = displayWidth - addForm.X;
addForm.TranslateTo(0, 0, 800, easing: Easing.CubicOut);
}
_ = addForm.TranslateTo(0, 0, 800, easing: Easing.CubicOut);
_ = BlockScreen.FadeTo(0.8, 800, easing: Easing.CubicOut);
BlockScreen.InputTransparent = false;
}
else
{
// remove the product window
@ -46,11 +58,91 @@ public partial class HomePage : ContentPage
var view = (AddProductView)PageGrid.Children.Where(v => v.GetType() == typeof(AddProductView)).SingleOrDefault();
var x = DeviceDisplay.Current.MainDisplayInfo.Width;
view.TranslateTo(displayWidth - view.X, 0, 800, easing: Easing.CubicIn);
_ = view.TranslateTo(displayWidth - view.X, 0, 800, easing: Easing.CubicIn);
if (view != null)
PageGrid.Children.Remove(view);
_ = BlockScreen.FadeTo(0, 800, easing: Easing.CubicOut);
BlockScreen.InputTransparent = true;
await Task.Delay(800);
if (view != null){
PageGrid.Children.Remove(view);
}
}
}
void OnDragStarting(object sender, DragStartingEventArgs e)
{
WeakReferenceMessenger.Default.Send<DragProductMessage>(new DragProductMessage(true));
Item item = (Item)(sender as Element).Parent.BindingContext;
e.Data.Properties.Add("Product", item);
var previewImage = string.Empty;
if(item.Title == "Soda") {
previewImage = "hunter.png";
} else if(item.Title == "Hot Tea") {
previewImage = "maddy.png";
} else if(item.Title == "Milk") {
previewImage = "sweeky.png";
} else if(item.Title == "Coffee") {
previewImage = "david.png";
} else if(item.Title == "Iced Tea") {
previewImage = "beth.png";
} else if(item.Title == "Juice") {
previewImage = "rachel.png";
} else {
return;
}
#if IOS || MACCATALYST
Func<UIKit.UIDragPreview> action = () =>
{
var image = UIImage.FromBundle(previewImage);
UIKit.UIImageView imageView = new UIKit.UIImageView(image);
imageView.ContentMode = UIKit.UIViewContentMode.Center;
imageView.Frame = new CoreGraphics.CGRect(0, 0, 250, 250);
return new UIKit.UIDragPreview(imageView);
};
e.PlatformArgs.SetPreviewProvider(action);
#endif
}
void OnDragOver(object sender, DragEventArgs e)
{
#if IOS || MACCATALYST
e.PlatformArgs.SetDropProposal(new UIKit.UIDropProposal(UIKit.UIDropOperation.Copy));
#endif
}
void OnDropCompleted(object sender, DropCompletedEventArgs e)
{
WeakReferenceMessenger.Default.Send<DragProductMessage>(new DragProductMessage(false));
}
void OnDrop(object sender, DropEventArgs e)
{
Item product = (Item)e.Data.Properties["Product"];
Debug.WriteLine($"{product.Title}");
WeakReferenceMessenger.Default.Send<AddToOrderMessage>(new AddToOrderMessage(product));
// Perform logic to take action based on retrieved value.
}
IDispatcherTimer timer;
void OnPointerPressed(object sender, PointerEventArgs e)
{
timer = Dispatcher.CreateTimer();
timer.Interval = TimeSpan.FromMilliseconds(2000);
timer.Tick += (s, e) =>
{
timer.Stop();
WeakReferenceMessenger.Default.Send<AddProductMessage>(new AddProductMessage(true));
};
}
void OnPointerReleased(object sender, PointerEventArgs e)
{
timer.Stop();
}
}

Просмотреть файл

@ -1,4 +1,6 @@
using System;
using PointOfSale.Messages;
namespace PointOfSale.Pages;
[INotifyPropertyChanged]
@ -35,6 +37,6 @@ public partial class HomeViewModel
[RelayCommand]
async Task AddProduct()
{
MessagingCenter.Send<HomeViewModel, string>(this, "action", "add");
WeakReferenceMessenger.Default.Send<AddProductMessage>(new AddProductMessage(true));
}
}

Просмотреть файл

@ -17,8 +17,8 @@
</Style>
</ContentView.Resources>
<Grid RowDefinitions="*,108">
<ScrollView>
<Grid RowDefinitions="*,108" ColumnDefinitions="*,*" ColumnSpacing="0">
<ScrollView Grid.ColumnSpan="2">
<VerticalStackLayout Spacing="20" Margin="24">
<Label Text="Add a Product" Style="{StaticResource Title1}" />
<BoxView Style="{StaticResource HRule}"/>
@ -96,7 +96,14 @@
</VerticalStackLayout>
</ScrollView>
<Button Text="Save" Grid.Row="1" Margin="24" Command="{Binding SaveCommand}"
<Button Text="Cancel"
Grid.Row="1" Grid.Column="0"
Margin="24,24,12,24"
Style="{StaticResource SecondaryButtonOutline}"
HorizontalOptions="Fill"
Command="{Binding CancelCommand}" />
<Button Text="Save" Grid.Row="1" Grid.Column="1" Margin="12,24,24,24" Command="{Binding SaveCommand}"
HorizontalOptions="Fill"
/>
</Grid>

Просмотреть файл

@ -1,9 +1,32 @@
namespace PointOfSale.Pages;
using System.Security.Cryptography;
using Plugin.Maui.KeyListener;
using PointOfSale.Messages;
public partial class AddProductView
namespace PointOfSale.Pages;
public partial class AddProductView : ContentView, IDisposable
{
KeyboardBehavior kb = new KeyboardBehavior();
public AddProductView()
{
InitializeComponent();
this.Behaviors.Add(kb);
kb.KeyUp += Kb_KeyUp;
}
private void Kb_KeyUp(object sender, KeyPressedEventArgs e)
{
if(e.Keys == KeyboardKeys.Escape)
{
(this.BindingContext as AddProductViewModel).CancelCommand.Execute(null);
}
}
public void Dispose()
{
kb.KeyUp -= Kb_KeyUp;
this.Behaviors.Remove(kb);
}
}

Просмотреть файл

@ -1,4 +1,6 @@
using System;
using PointOfSale.Messages;
namespace PointOfSale.Pages;
[INotifyPropertyChanged]
@ -17,16 +19,22 @@ public partial class AddProductViewModel
ImageSource image;
[RelayCommand]
async void Save()
void Save()
{
ItemCategory cat = (ItemCategory)Enum.Parse(typeof(ItemCategory), category);
item.Category = cat;
AppData.Items.Add(item);
MessagingCenter.Send<AddProductViewModel, string>(this, "action", "done");
WeakReferenceMessenger.Default.Send<AddProductMessage>(new AddProductMessage(false));
}
[RelayCommand]
void Cancel()
{
WeakReferenceMessenger.Default.Send<AddProductMessage>(new AddProductMessage(false));
}
[RelayCommand]
async Task ChangeImage()
{
PickOptions options = new()

Просмотреть файл

@ -12,19 +12,64 @@
<views:OrderCartViewModel/>
</ContentView.BindingContext>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="DefaultStates">
<VisualState x:Name="AcceptDrop">
<VisualState.Setters>
<Setter
Property="Background"
Value="{StaticResource Primary}"/>
<Setter
TargetName="PlaceOrderButton"
Property="Button.IsEnabled"
Value="False"/>
<Setter
TargetName="OrderTypes"
Property="HorizontalStackLayout.IsVisible"
Value="False"/>
<Setter
TargetName="AddItemIcon"
Property="Image.IsVisible"
Value="True"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Normal">
<VisualState.Setters>
<Setter
Property="Background"
Value="{StaticResource DarkBg2Brush}"/>
<Setter
TargetName="PlaceOrderButton"
Property="Button.IsEnabled"
Value="True"/>
<Setter
TargetName="OrderTypes"
Property="HorizontalStackLayout.IsVisible"
Value="True"/>
<Setter
TargetName="AddItemIcon"
Property="Image.IsVisible"
Value="False"/>
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Grid RowDefinitions="*,108">
<ScrollView>
<VerticalStackLayout Margin="24" Spacing="20">
<Label
Text="Order #4773"
Style="{StaticResource Title1}" />
<HorizontalStackLayout Spacing="12">
<HorizontalStackLayout.Resources>
<HorizontalStackLayout Spacing="12"
x:Name="OrderTypes">
<HorizontalStackLayout.Resources>
<Style TargetType="RadioButton">
<Setter Property="ControlTemplate" Value="{StaticResource ButtonRadioTemplate}"/>
</Style>
</HorizontalStackLayout.Resources>
<RadioButton Content="Dine In" IsChecked="True"/>
<RadioButton Content="Carry Out"/>
@ -39,7 +84,7 @@
<BoxView Style="{StaticResource HRule}"/>
<VerticalStackLayout Spacing="12"
BindableLayout.ItemsSource="{Binding Order.Items}">
BindableLayout.ItemsSource="{Binding Items}">
<BindableLayout.ItemTemplate>
<DataTemplate x:DataType="m:Item">
<Grid ColumnDefinitions="60*,20*,20*">
@ -53,7 +98,7 @@
<FormattedString>
<Span Text="{Binding Title}"/>
<Span Text="{x:Static system:Environment.NewLine}"/>
<Span TextColor="{StaticResource TextSecondary}" FontSize="12" Text="{Binding Price, StringFormat='${0}'}"/>
<Span TextColor="{StaticResource TextSecondary}" FontSize="12" Text="{Binding Price, StringFormat='{0:C}'}"/>
</FormattedString>
</Label.FormattedText>
</Label>
@ -92,8 +137,17 @@
</VerticalStackLayout>
</VerticalStackLayout>
</ScrollView>
<Button Text="Place Order" HorizontalOptions="Fill" Margin="24" Grid.Row="1"
<Button Text="Place Order"
x:Name="PlaceOrderButton"
HorizontalOptions="Fill" Margin="24" Grid.Row="1"
Command="{Binding PlaceOrderCommand}"/>
<Image x:Name="AddItemIcon"
Source="{FontImage &#xEAEE;, FontFamily=Fabric, Size=48}"
Aspect="AspectFit"
HorizontalOptions="Center"
VerticalOptions="End"
Margin="0,-100,0,0"
Grid.Row="0"/>
</Grid>
</ContentView>

Просмотреть файл

@ -1,9 +1,19 @@
namespace PointOfSale.Pages.Views;
using PointOfSale.Messages;
namespace PointOfSale.Pages.Views;
public partial class OrderCartView : ContentView
{
public OrderCartView()
{
InitializeComponent();
WeakReferenceMessenger.Default.Register<DragProductMessage>(this, (r, m) =>
{
if(m.Value)
VisualStateManager.GoToState(this, "AcceptDrop");
else
VisualStateManager.GoToState(this, "Normal");
});
}
}

Просмотреть файл

@ -1,20 +1,52 @@
using System;
namespace PointOfSale.Pages.Views;
[INotifyPropertyChanged]
[INotifyPropertyChanged]
public partial class OrderCartViewModel
{
[ObservableProperty]
Order order;
[ObservableProperty]
ObservableCollection<Item> items;
int index = 0;
public OrderCartViewModel()
{
Order = AppData.Orders.First();
Items = new ObservableCollection<Item>(Order.Items);
WeakReferenceMessenger.Default.Register<AddToOrderMessage>(this, (r, m) =>
{
AddToOrder(m.Value);
Items = new ObservableCollection<Item>(Order.Items);
OnPropertyChanged(nameof(Items));
});
}
private void AddToOrder(Item item)
{
//if item is in the order alread, increment the quantity
var existing = Order.Items.Where(x => x.Title == item.Title).SingleOrDefault();
if (existing != null)
{
existing.Quantity++;
}
else
{
Order.Items.Add(item);
}
}
[RelayCommand]
async Task PlaceOrder()
{
await App.Current.MainPage.DisplayAlert("Not Implemented", "Wouldn't it be cool tho?", "Okay");
if(index < (AppData.Orders.Count - 1))
index++;
else
index = 0;
Order = AppData.Orders[index];
}
}

Просмотреть файл

@ -1,6 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application android:allowBackup="true" android:icon="@mipmap/appicon" android:roundIcon="@mipmap/appicon_round" android:supportsRtl="true"></application>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="net.dot.pointofsale" android:versionCode="1" android:versionName="1.0.0">
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="33" />
<application android:allowBackup="true" android:icon="@mipmap/appicon" android:roundIcon="@mipmap/appicon_round" android:supportsRtl="true" android:label="Food">
<activity android:name="microsoft.identity.client.BrowserTabActivity" android:configChanges="orientation|screenSize" android:exported="true">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="msale8b7e84c-1cb6-4619-bee9-ace98d4211e5" android:host="auth" />
</intent-filter>
</activity>
<activity android:name="MauiAppBasic.Platforms.Android.Resources.MsalActivity" android:configChanges="orientation|screenSize" android:exported="true">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="msale8b7e84c-1cb6-4619-bee9-ace98d4211e5" android:host="auth" />
</intent-filter>
</activity>
</application>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
</manifest>

Просмотреть файл

@ -1,10 +1,17 @@
using Android.App;
using Android.Content;
using Android.Content.PM;
using Android.OS;
using Android.Runtime;
using PointOfSale.Data;
namespace PointOfSale;
[Activity(Theme = "@style/Maui.SplashTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation | ConfigChanges.UiMode | ConfigChanges.ScreenLayout | ConfigChanges.SmallestScreenSize)]
public class MainActivity : MauiAppCompatActivity
{
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
}
}

Просмотреть файл

@ -1,4 +1,5 @@
using Foundation;
using UIKit;
namespace PointOfSale;
@ -6,4 +7,14 @@ namespace PointOfSale;
public class AppDelegate : MauiUIApplicationDelegate
{
protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
public override void BuildMenu(IUIMenuBuilder builder)
{
base.BuildMenu(builder);
var formatMenuIdentifier = UIMenuIdentifier.Format.GetConstant();
builder.RemoveMenu(formatMenuIdentifier);
var editIdentifier = UIMenuIdentifier.Edit.GetConstant();
builder.RemoveMenu(editIdentifier);
}
}

Просмотреть файл

@ -30,5 +30,7 @@
<string>Assets.xcassets/appicon.appiconset</string>
<key>NSCameraUsageDescription</key>
<string>Barcode Scanning</string>
<key>UIRequiresPersistentWiFi</key>
<true/>
</dict>
</plist>

Просмотреть файл

@ -2,28 +2,22 @@
<PropertyGroup>
<TargetFrameworks>net8.0-android;net8.0-ios;net8.0-maccatalyst</TargetFrameworks>
<TargetFrameworks Condition="$([MSBuild]::IsOSPlatform('windows'))">$(TargetFrameworks);net8.0-windows10.0.19041.0</TargetFrameworks>
<!-- Note for MacCatalyst:
The default runtime is maccatalyst-x64, except in Release config, in which case the default is maccatalyst-x64;maccatalyst-arm64.
When specifying both architectures, use the plural <RuntimeIdentifiers> instead of the singular <RuntimeIdentifer>.
The Mac App Store will NOT accept apps with ONLY maccatalyst-arm64 indicated;
either BOTH runtimes must be indicated or ONLY macatalyst-x64. -->
<!-- For example: <RuntimeIdentifiers>maccatalyst-x64;maccatalyst-arm64</RuntimeIdentifiers> -->
<TargetFrameworks Condition="$([MSBuild]::IsOSPlatform('windows')) and '$(MSBuildRuntimeType)' == 'Full'">$(TargetFrameworks);net8.0-windows10.0.19041</TargetFrameworks>
<OutputType>Exe</OutputType>
<RootNamespace>PointOfSale</RootNamespace>
<UseMaui>true</UseMaui>
<SingleProject>true</SingleProject>
<ImplicitUsings>enable</ImplicitUsings>
<EnablePreviewMsixTooling>true</EnablePreviewMsixTooling>
<WarningsAsErrors>false</WarningsAsErrors>
<!-- Display name -->
<ApplicationTitle>Food</ApplicationTitle>
<!-- App Identifier -->
<ApplicationId>net.dot.pointofsale</ApplicationId>
<ApplicationId>com.simplyprofound.pointofsale</ApplicationId>
<ApplicationIdGuid>919dc1f9-17a9-48b3-81f8-0b8016bdfbf7</ApplicationIdGuid>
<!-- Versions -->
<ApplicationVersion>1</ApplicationVersion>
@ -40,18 +34,29 @@
<AssemblyName>Food</AssemblyName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Debug|net8.0-ios|AnyCPU'">
<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Debug|net6.0-ios|AnyCPU'">
<CodesignProvision>dPOSDev</CodesignProvision>
<CodesignKey>Apple Development: Created via API (2NJFZDD9ZM)</CodesignKey>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Release|net8.0-ios|AnyCPU'">
<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Release|net6.0-ios|AnyCPU'">
<CodesignProvision>Automatic</CodesignProvision>
<CodesignKey>iPhone Developer</CodesignKey>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Debug|net7.0-ios|AnyCPU'">
<CreatePackage>false</CreatePackage>
<CodesignProvision>Automatic</CodesignProvision>
<CodesignKey>iPhone Developer</CodesignKey>
<CodesignEntitlements>Platforms\iOS\Entitlements.plist</CodesignEntitlements>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Release|net7.0-ios|AnyCPU'">
<CreatePackage>false</CreatePackage>
</PropertyGroup>
<ItemGroup>
<!-- App Icon -->
<MauiIcon Include="Resources\appicon.svg" ForegroundFile="Resources\appiconfg.svg" Color="#252836" />
@ -60,7 +65,7 @@
<MauiSplashScreen Include="Resources\Images\food_01.png" Color="#252836" />
<!-- Images -->
<MauiImage Include="Resources\Images\*" />
<MauiImage Include="Resources\Images\*" Exclude="$(DefaultItemExcludes)"/>
<!-- Custom Fonts -->
<MauiFont Include="Resources\Fonts\*" />
@ -76,11 +81,19 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="CommunityToolkit.Maui" Version="6.0.0" />
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.2.1" />
<PackageReference Include="Microcharts.Maui" Version="1.0.0" />
<PackageReference Include="SkiaSharp.Extended.UI.Maui" Version="2.0.0-preview.86" />
<PackageReference Include="CommunityToolkit.Maui" Version="3.0.0" />
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.1.0-preview1" />
<PackageReference Include="Microcharts" Version="0.9.5.9" />
<PackageReference Include="Redth.ZXing.Net.Maui" Version="0.1.0-preview.4" />
<PackageReference Include="SkiaSharp.Extended.UI.Maui" Version="2.0.0-preview.61" />
<PackageReference Include="Ril.BlazorSignatureCanvas" Version="0.1.0-alpha" />
<PackageReference Include="Microsoft.Identity.Client" Version="4.48.1" />
<PackageReference Include="MonkeyCache" Version="2.0.0-beta" />
<PackageReference Include="MonkeyCache.FileStore" Version="2.0.0-beta" />
<PackageReference Include="AlohaKit.Animations" Version="1.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="7.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="7.0.0" />
<PackageReference Include="AsyncAwaitBestPractices" Version="6.0.6" />
<PackageReference Include="Plugin.Maui.KeyListener" Version="1.0.0-preview1" />
</ItemGroup>
</Project>

Просмотреть файл

@ -1,12 +1,12 @@
@inherits LayoutComponentBase
<div class="page">
<main>
<SignatureCanvas class="my-special-styling-class"
@ref=signatureCanvas
width="400" height="200" />
</main>
</div>
@inherits LayoutComponentBase
<div class="page">
<main>
<SignatureCanvas class="my-special-styling-class"
@ref=signatureCanvas
width="400" height="200" />
</main>
</div>
@code {
private SignatureCanvas signatureCanvas;

Просмотреть файл

@ -4,6 +4,10 @@
flex-direction: column;
}
.my-special-styling-class {
background-color: #0a58ca;
}
main {
flex: 1;
}