Skip to content

Commit

Permalink
chore: refactor customer scheduling process and UI improvements
Browse files Browse the repository at this point in the history
  - Updated EditCustomersView and AddCustomersView with adjusted font size and weight for improved visibility and refined user interface.

  - Extended observable collections in AppointmentViewModel for better data management.

  - Added functionalities in DialogService to create a selection dialog, aiding proper customer selection.

  - Inserted a new AppointmentCustomerSelectionListCardTemplate view for better customer selection in appointments.

  - Developed a new SelectCustomerView to facilitate customer selection during appointment booking, enhancing user experience and system functionality.

Signed-off-by: Russell Camo <[email protected]>
  • Loading branch information
russkyc committed Sep 1, 2023
1 parent 554b712 commit 2c6d541
Show file tree
Hide file tree
Showing 16 changed files with 368 additions and 24 deletions.
77 changes: 72 additions & 5 deletions GroomWise.Application/ViewModels/AppointmentViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,19 @@ public partial class AppointmentViewModel
: IEventSubscriber<CreateGroomingServiceEvent>,
IEventSubscriber<DeleteGroomingServiceEvent>,
IEventSubscriber<ScheduleAppointmentEvent>,
IEventSubscriber<DeleteCustomerEvent>
IEventSubscriber<DeleteCustomerEvent>,
IEventSubscriber<CreateCustomerEvent>,
IEventSubscriber<UpdateCustomerEvent>
{
[Property]
private ObservableAppointment _activeAppointment;

[Property]
private ConcurrentObservableCollection<ObservableAppointment> _appointments;

[Property]
private ConcurrentObservableCollection<ObservableCustomer> _customers;

[Property]
private ConcurrentObservableCollection<ObservableGroomingService> _groomingServices;

Expand All @@ -61,6 +66,12 @@ private async void PopulateCollections()
.GetAll()
.Select(GroomingServiceMapper.ToObservable);
var customers = GroomWiseDbContext!.Customers
.GetAll()
.Select(CustomerMapper.ToObservable)
.OrderBy(customer => customer.FullName);
Customers = new ConcurrentObservableCollection<ObservableCustomer>(customers);
Appointments = new ConcurrentObservableCollection<ObservableAppointment>(appointments);
GroomingServices = new ConcurrentObservableCollection<ObservableGroomingService>(
services
Expand All @@ -69,19 +80,66 @@ private async void PopulateCollections()
}

[Command]
private async Task CreateAppointment()
private async Task CreateAppointment(object param)
{
await Task.Run(() =>
{
DialogService.CreateAddAppointmentsDialog(this, NavigationService);
if (param is ObservableCustomer customer)
{
ActiveAppointment.Customer = customer;
DialogService.CreateAddAppointmentsDialog(this, NavigationService);
return;
}
ActiveAppointment = new ObservableAppointment { Date = DateTime.Today };
DialogService.CreateCustomerSelectionDialog(this, NavigationService);
});
}

[Command]
private async Task SelectCustomer(object param)
{
if (param is ObservableCustomer customer)
{
await Task.Run(async () =>
{
ActiveAppointment.Customer = customer;
DialogService.CloseDialogs(NavigationService);
await Task.Delay(100);
DialogService.CreateAddAppointmentsDialog(this, NavigationService);
});
}
}

[Command]
private async Task SaveAppointment()
{
await Task.Run(() =>
{
if (ActiveAppointment.Customer is null)
{
EventAggregator.Publish(
new PublishNotificationEvent(
"Appointment should be scheduled to a customer.",
NotificationType.Danger
)
);
return;
}
if (
ActiveAppointment.Services is null
|| ActiveAppointment.Services.Any(service => service is null)
)
{
EventAggregator.Publish(
new PublishNotificationEvent(
"Cannot create an appointment if there are no services.",
NotificationType.Danger
)
);
return;
}
var dialogResult = DialogService.Create(
"GroomWise",
"Create Appointment?",
Expand Down Expand Up @@ -134,8 +192,7 @@ public void OnEvent(DeleteGroomingServiceEvent eventData)

public void OnEvent(ScheduleAppointmentEvent eventData)
{
ActiveAppointment.Customer = eventData.Customer;
CreateAppointment();
CreateAppointment(eventData.Customer);
}

public void OnEvent(DeleteCustomerEvent eventData)
Expand All @@ -145,4 +202,14 @@ public void OnEvent(DeleteCustomerEvent eventData)
);
PopulateCollections();
}

public void OnEvent(CreateCustomerEvent eventData)
{
PopulateCollections();
}

public void OnEvent(UpdateCustomerEvent eventData)
{
PopulateCollections();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ public interface IDialogService
{
bool? Create(string messageBoxText, string caption, INavigationService navigationService);
void CloseDialogs(INavigationService navigationService);

void CreateCustomerSelectionDialog(
object viewModel,
INavigationService navigationService
);

void CreateAddAppointmentsDialog(object viewModel, INavigationService navigationService);
void CreateAddCustomersDialog(object viewModel, INavigationService navigationService);
void CreateEditCustomersDialog(object viewModel, INavigationService navigationService);
Expand Down
2 changes: 1 addition & 1 deletion GroomWise.WPF/App.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public App()
scope.AddContainer(container);

#if DEBUG
ResetDatabase(scope);
// ResetDatabase(scope);
#endif
RegisterNavigationViews(scope);
LoadThemeDefaults(scope);
Expand Down
22 changes: 22 additions & 0 deletions GroomWise.WPF/Services/DialogService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,28 @@ public void CloseDialogs(INavigationService navigationService)
});
}

public void CreateCustomerSelectionDialog(
object viewModel,
INavigationService navigationService
)
{
Task.Run(async () =>
{
await App.Current.Dispatcher.InvokeAsync(() =>
{
if (!App.Current.Windows.OfType<SelectCustomerView>().Any())
{
new SelectCustomerView(viewModel)
{
ShowInTaskbar = false,
WindowStartupLocation = WindowStartupLocation.CenterOwner,
Owner = (Window)navigationService.CurrentWindow!
}.Show();
}
});
});
}

public void CreateAddAppointmentsDialog(object viewModel, INavigationService navigationService)
{
Task.Run(async () =>
Expand Down
14 changes: 7 additions & 7 deletions GroomWise.WPF/Views/Dialogs/AddCustomersView.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,18 +25,18 @@
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<TextBlock
Grid.Row="0"
Grid.Column="0"
Margin="20,16,0,12"
HorizontalAlignment="Left"
FontSize="16"
Text="New Customer" />


<StackPanel
Grid.Row="1"
Margin="20,0,16,20"
HorizontalAlignment="Stretch"
VerticalAlignment="Top">
<TextBlock
Margin="0,16,0,12"
FontSize="18"
FontWeight="Medium"
Text="New Customer" />
<Grid>
<russkyc:ModernTextBox
Name="FullNameTextBox"
Expand Down
8 changes: 3 additions & 5 deletions GroomWise.WPF/Views/Dialogs/EditCustomersView.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,10 @@
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<TextBlock
Grid.Row="0"
Grid.Column="0"
Margin="20,16,0,12"
HorizontalAlignment="Left"
FontSize="16"
Text="Edit Customer" />
FontSize="18"
FontWeight="Medium"
Text="Update Customer" />
<StackPanel
Grid.Row="1"
Margin="20,0,16,20"
Expand Down
88 changes: 88 additions & 0 deletions GroomWise.WPF/Views/Dialogs/SelectCustomerView.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
<russkyc:ModernWindow
x:Class="GroomWise.Views.Dialogs.SelectCustomerView"
xmlns="http:https://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http:https://schemas.microsoft.com/winfx/2006/xaml"
xmlns:b="http:https://schemas.microsoft.com/xaml/behaviors"
xmlns:d="http:https://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http:https://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:russkyc="clr-namespace:org.russkyc.moderncontrols;assembly=Russkyc.ModernControls.WPF"
xmlns:templates="clr-namespace:GroomWise.Views.Templates"
xmlns:viewModels="clr-namespace:GroomWise.Application.ViewModels;assembly=GroomWise.Application"
Title="AddCustomersView"
Width="600"
Height="400"
d:DataContext="{d:DesignInstance viewModels:AppointmentViewModel,
IsDesignTimeCreatable=True}"
FocusManager.FocusedElement="{Binding ElementName=FullNameTextBox}"
NoDecorations="True"
ResizeMode="NoResize"
SizeToContent="Height"
TitleBarHeight="0"
WindowStartupLocation="CenterOwner"
mc:Ignorable="d">
<Grid Margin="16" Style="{StaticResource FadeInAnimation}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBlock
Grid.Row="0"
Margin="0,0,0,12"
FontSize="18"
FontWeight="Medium"
Text="Select Customer" />
<ItemsControl Grid.Row="1" ItemsSource="{Binding Customers.EditableCollectionView, UpdateSourceTrigger=PropertyChanged}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<templates:AppointmentCustomerSelectionListCardTemplate />
</DataTemplate>
</ItemsControl.ItemTemplate>

<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel IsVirtualizing="True" VirtualizationMode="Recycling" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>

<ItemsControl.ItemContainerStyle>
<Style TargetType="{x:Type FrameworkElement}">
<Setter Property="Margin" Value="0,0,0,10" />
</Style>
</ItemsControl.ItemContainerStyle>

<ItemsControl.Template>
<ControlTemplate TargetType="ItemsControl">
<Border
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<ScrollViewer
Padding="{TemplateBinding Padding}"
CanContentScroll="True"
Focusable="False">
<ItemsPresenter />
</ScrollViewer>
</Border>
</ControlTemplate>
</ItemsControl.Template>
</ItemsControl>
<russkyc:ModernButton
Grid.Row="2"
HorizontalAlignment="Right"
Content="Cancel"
CornerRadius="5"
DefaultBackground="{DynamicResource bg-000}"
FontWeight="Medium"
Foreground="{DynamicResource fg-600}"
HoverBackground="{DynamicResource bg-000}"
PressedBackground="{DynamicResource bg-100}">
<b:Interaction.Triggers>
<b:EventTrigger EventName="Click">
<b:CallMethodAction MethodName="Close" TargetObject="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=russkyc:ModernWindow}}" />
</b:EventTrigger>
</b:Interaction.Triggers>
</russkyc:ModernButton>
</Grid>
</russkyc:ModernWindow>

26 changes: 26 additions & 0 deletions GroomWise.WPF/Views/Dialogs/SelectCustomerView.xaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Copyright (C) 2023 Russell Camo (Russkyc).- All Rights Reserved
//
// Unauthorized copying or redistribution of all files, in source and binary forms via any medium
// without written, signed consent from the author is strictly prohibited.

using System;
using System.ComponentModel;
using System.Linq;

namespace GroomWise.Views.Dialogs;

public partial class SelectCustomerView
{
public SelectCustomerView(object vm)
{
DataContext = vm;
InitializeComponent();
}

protected override void OnClosing(CancelEventArgs e)
{
var parent = App.Current.Windows.OfType<MainView>().FirstOrDefault();
parent.Focus();
base.OnClosing(e);
}
}
3 changes: 2 additions & 1 deletion GroomWise.WPF/Views/Pages/CustomersView.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@
<TextBlock
Grid.Column="0"
VerticalAlignment="Center"
FontSize="16"
FontSize="18"
FontWeight="Medium"
Text="Customers" />
<russkyc:ModernTextBox
Grid.Column="2"
Expand Down
2 changes: 2 additions & 0 deletions GroomWise.WPF/Views/Pages/InventoryView.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,7 @@
<TextBlock
HorizontalAlignment="Center"
VerticalAlignment="Center"
FontSize="18"
FontWeight="Medium"
Text="Inventory" />
</UserControl>
6 changes: 6 additions & 0 deletions GroomWise.WPF/Views/Pages/PetsView.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,12 @@
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>

<ItemsControl.ItemContainerStyle>
<Style TargetType="{x:Type FrameworkElement}">
<Setter Property="Margin" Value="0,0,0,10" />
</Style>
</ItemsControl.ItemContainerStyle>

<ItemsControl.Template>
<ControlTemplate TargetType="ItemsControl">
<Border
Expand Down
3 changes: 2 additions & 1 deletion GroomWise.WPF/Views/Pages/ServicesView.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@
<TextBlock
Grid.Column="0"
VerticalAlignment="Center"
FontSize="16"
FontSize="18"
FontWeight="Medium"
Text="Services" />
<russkyc:ModernTextBox
Grid.Column="2"
Expand Down
Loading

0 comments on commit 2c6d541

Please sign in to comment.