Skip to content

Commit

Permalink
feat: Enhance UI/UX, add appointment scheduling and customer update e…
Browse files Browse the repository at this point in the history
…vent

Signed-off-by: Russell Camo <[email protected]>
  • Loading branch information
russkyc committed Sep 1, 2023
1 parent eae079d commit 554b712
Show file tree
Hide file tree
Showing 25 changed files with 234 additions and 54 deletions.
6 changes: 4 additions & 2 deletions GroomWise.Application/Events/DeleteCustomerEvent.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
// 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 GroomWise.Application.Observables;

namespace GroomWise.Application.Events;

public record DeleteCustomerEvent();
public record DeleteCustomerEvent(ObservableCustomer Customer);
10 changes: 10 additions & 0 deletions GroomWise.Application/Events/ScheduleAppointmentEvent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// 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 GroomWise.Application.Observables;

namespace GroomWise.Application.Events;

public record ScheduleAppointmentEvent(ObservableCustomer Customer);
8 changes: 8 additions & 0 deletions GroomWise.Application/Events/UpdateCustomerEvent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// 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.

namespace GroomWise.Application.Events;

public record UpdateCustomerEvent();
18 changes: 17 additions & 1 deletion GroomWise.Application/ViewModels/AppointmentViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@ namespace GroomWise.Application.ViewModels;
[RegisterSingleton]
public partial class AppointmentViewModel
: IEventSubscriber<CreateGroomingServiceEvent>,
IEventSubscriber<DeleteGroomingServiceEvent>
IEventSubscriber<DeleteGroomingServiceEvent>,
IEventSubscriber<ScheduleAppointmentEvent>,
IEventSubscriber<DeleteCustomerEvent>
{
[Property]
private ObservableAppointment _activeAppointment;
Expand Down Expand Up @@ -129,4 +131,18 @@ public void OnEvent(DeleteGroomingServiceEvent eventData)
{
PopulateCollections();
}

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

public void OnEvent(DeleteCustomerEvent eventData)
{
GroomWiseDbContext.Appointments.DeleteMultiple(
apppintment => apppintment.Customer.Id == eventData.Customer.Id
);
PopulateCollections();
}
}
58 changes: 51 additions & 7 deletions GroomWise.Application/ViewModels/CustomerViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using GroomWise.Application.Observables;
using GroomWise.Domain.Enums;
using GroomWise.Infrastructure.Database;
using GroomWise.Infrastructure.IoC.Interfaces;
using GroomWise.Infrastructure.Logging.Interfaces;
using GroomWise.Infrastructure.Navigation.Interfaces;
using GroomWise.Infrastructure.Storage.Interfaces;
Expand All @@ -25,6 +26,7 @@ namespace GroomWise.Application.ViewModels;
[Inject(typeof(IEventAggregator))]
[Inject(typeof(IDialogService))]
[Inject(typeof(INavigationService))]
[Inject(typeof(IAppServicesContainer))]
[Inject(typeof(GroomWiseDbContext))]
[RegisterSingleton]
public partial class CustomerViewModel
Expand Down Expand Up @@ -119,21 +121,30 @@ private async Task SelectCustomer(object param)
[Command]
private async Task AddCustomerPet()
{
ActiveCustomer.Pets.Insert(0, new ObservablePet());
await Task.Run(() =>
{
ActiveCustomer.Pets.Insert(0, new ObservablePet());
});
}

[Command]
private async Task AddSelectedCustomerPet()
{
SelectedCustomer.Pets.Insert(0, new ObservablePet());
await Task.Run(() =>
{
SelectedCustomer.Pets.Insert(0, new ObservablePet());
});
}

[Command]
private async Task RemoveCustomerPet(object param)
{
if (param is ObservablePet pet)
{
ActiveCustomer.Pets.Remove(pet);
await Task.Run(() =>
{
ActiveCustomer.Pets.Remove(pet);
});
}
}

Expand All @@ -142,8 +153,24 @@ private async Task RemoveSelectedCustomerPet(object param)
{
if (param is ObservablePet pet)
{
SelectedCustomer.Pets.Remove(pet);
GroomWiseDbContext.Customers.Update(SelectedCustomer.Id, SelectedCustomer.ToEntity());
await Task.Run(() =>
{
var dialogResult = DialogService.Create(
$"{SelectedCustomer.FullName.Split(" ")[0]}'s Pets",
$"Are you sure you want to remove {pet.Name}?",
NavigationService
);
if (dialogResult is true)
{
SelectedCustomer.Pets.Remove(pet);
GroomWiseDbContext.Customers.Update(
SelectedCustomer.Id,
SelectedCustomer.ToEntity()
);
EventAggregator.Publish(new UpdateCustomerEvent());
}
});
}
}

Expand All @@ -163,6 +190,7 @@ private async Task UpdateCustomer()
SelectedCustomer.Id,
SelectedCustomer.ToEntity()
);
EventAggregator.Publish(new UpdateCustomerEvent());
DialogService.CloseDialogs(NavigationService);
}
});
Expand All @@ -171,7 +199,10 @@ private async Task UpdateCustomer()
[Command]
private async Task EditCustomer()
{
DialogService.CreateEditCustomersDialog(this, NavigationService);
await Task.Run(() =>
{
DialogService.CreateEditCustomersDialog(this, NavigationService);
});
}

[Command]
Expand All @@ -193,13 +224,26 @@ private async Task RemoveCustomer(object param)
SelectedCustomer = null!;
}
GroomWiseDbContext.Customers.Delete(observableCustomer.Id);
EventAggregator.Publish(new DeleteCustomerEvent());
EventAggregator.Publish(new DeleteCustomerEvent(observableCustomer));
PopulateCollections();
}
});
}
}

[Command]
private async Task ScheduleAppointment(object param)
{
if (param is ObservableCustomer customer)
{
var appointmentsViewModel = AppServicesContainer.GetService<AppointmentViewModel>();
if (appointmentsViewModel is not null)
{
EventAggregator.Publish(new ScheduleAppointmentEvent(customer));
}
}
}

[Command]
private async Task CloseDialogs()
{
Expand Down
2 changes: 1 addition & 1 deletion GroomWise.Application/ViewModels/DashboardViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ private async void PopulateCollections()
await Task.Run(() =>
{
var appointments = GroomWiseDbContext.Appointments
.GetMultiple(appointment => appointment.Date == DateTime.Now)
.GetMultiple(appointment => appointment.Date == DateTime.Today)
.Select(AppointmentMapper.ToObservable)
.OrderBy(appointment => appointment.Date);
Appointments = new ConcurrentObservableCollection<ObservableAppointment>(appointments);
Expand Down
8 changes: 7 additions & 1 deletion GroomWise.Application/ViewModels/PetViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ namespace GroomWise.Application.ViewModels;
[Inject(typeof(IEventAggregator))]
public partial class PetViewModel
: IEventSubscriber<CreateCustomerEvent>,
IEventSubscriber<DeleteCustomerEvent>
IEventSubscriber<DeleteCustomerEvent>,
IEventSubscriber<UpdateCustomerEvent>
{
[Property]
private ObservablePet _activePet = new();
Expand Down Expand Up @@ -58,4 +59,9 @@ public void OnEvent(DeleteCustomerEvent eventData)
{
PopulateCollections();
}

public void OnEvent(UpdateCustomerEvent eventData)
{
PopulateCollections();
}
}
17 changes: 17 additions & 0 deletions GroomWise.WPF/App.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using GroomWise.Application.Enums;
using GroomWise.Application.Extensions;
using GroomWise.Infrastructure.Configuration.Interfaces;
using GroomWise.Infrastructure.Database;
using GroomWise.Infrastructure.IoC.Interfaces;
using GroomWise.Infrastructure.Navigation.Interfaces;
using GroomWise.Infrastructure.Theming.Interfaces;
Expand Down Expand Up @@ -37,6 +38,10 @@ public App()

var scope = container.GetService<IAppServicesContainer>()!;
scope.AddContainer(container);

#if DEBUG
ResetDatabase(scope);
#endif
RegisterNavigationViews(scope);
LoadThemeDefaults(scope);
StartApp(scope);
Expand Down Expand Up @@ -72,6 +77,18 @@ private void LoadThemeDefaults(IAppServicesContainer scope)
}
}

private void ResetDatabase(IAppServicesContainer scope)
{
var context = scope.GetService<GroomWiseDbContext>();
context?.Appointments.DeleteMultiple(t => true);
context?.Customers.DeleteMultiple(t => true);
context?.Employees.DeleteMultiple(t => true);
context?.Products.DeleteMultiple(t => true);
context?.Roles.DeleteMultiple(t => true);
context?.GroomingServices.DeleteMultiple(t => true);
context?.Pets.DeleteMultiple(t => true);
}

private void StartApp(IAppServicesContainer scope)
{
MainWindow = scope.GetService<LoginView>();
Expand Down
14 changes: 8 additions & 6 deletions GroomWise.WPF/Services/DialogService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
using GroomWise.Infrastructure.Navigation.Interfaces;
using GroomWise.Views.Dialogs;
using Injectio.Attributes;
using Swordfish.NET.Collections.Auxiliary;

namespace GroomWise.Services;

Expand Down Expand Up @@ -40,14 +41,15 @@ public void CloseDialogs(INavigationService navigationService)
if (
App.Current.Windows
.OfType<Window>()
.FirstOrDefault(
dialog => dialog.Owner == navigationService.CurrentWindow
) is
{ } window
.Where(dialog => dialog.Owner == navigationService.CurrentWindow) is
{ } windows
)
{
var owner = navigationService.CurrentWindow as Window;
window.Close();
windows.ForEach(window =>
{
window.Close();
});
owner!.Focus();
}
});
Expand Down Expand Up @@ -91,7 +93,7 @@ public void CreateAddCustomersDialog(object viewModel, INavigationService naviga
});
});
}

public void CreateEditCustomersDialog(object viewModel, INavigationService navigationService)
{
Task.Run(async () =>
Expand Down
2 changes: 2 additions & 0 deletions GroomWise.WPF/Views/Dialogs/DialogView.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
// 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.ComponentModel;
using System.Linq;
using System.Windows;

namespace GroomWise.Views.Dialogs;
Expand Down
9 changes: 9 additions & 0 deletions GroomWise.WPF/Views/Dialogs/EditCustomersView.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
// 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.ComponentModel;
using System.Linq;

namespace GroomWise.Views.Dialogs;

public partial class EditCustomersView
Expand All @@ -12,4 +15,10 @@ public EditCustomersView(object vm)
DataContext = vm;
InitializeComponent();
}
protected override void OnClosing(CancelEventArgs e)
{
var parent = App.Current.Windows.OfType<MainView>().FirstOrDefault();
parent.Focus();
base.OnClosing(e);
}
}
2 changes: 1 addition & 1 deletion GroomWise.WPF/Views/MainView.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@
Tooltip="Appointments" />
<templates:NavItemTemplate
Margin="8,8,8,0"
Icon="{icons:MaterialIconExt Shower}"
Icon="{icons:MaterialIconExt Scissors}"
PageContext="{x:Type viewModels:GroomingServiceViewModel}"
Selected="{Binding PageContext, Converter={x:Static converters:PageContextToSelectionConverter.Instance}, ConverterParameter={x:Type viewModels:GroomingServiceViewModel}, Mode=OneWay}"
Tooltip="Services" />
Expand Down
2 changes: 1 addition & 1 deletion GroomWise.WPF/Views/Pages/AppointmentsView.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
<russkyc:ModernButton
HorizontalAlignment="Right"
Command="{Binding CreateAppointmentCommand}"
Content="Add Appointment"
Content="Schedule Appointment"
CornerRadius="5"
FontWeight="Medium"
IconSize="18"
Expand Down
2 changes: 1 addition & 1 deletion GroomWise.WPF/Views/Templates/AppNotificationTemplate.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
d:DesignWidth="200"
Background="Transparent"
IsTabStop="False"
Style="{StaticResource FadeInFromBottomAnimation}"
Style="{StaticResource FadeInAnimation}"
mc:Ignorable="d">
<Border CornerRadius="5">
<Border.Style>
Expand Down
9 changes: 6 additions & 3 deletions GroomWise.WPF/Views/Templates/AppointmentCardTemplate.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
d:DataContext="{d:DesignInstance observables:ObservableAppointment,
IsDesignTimeCreatable=True}"
d:DesignWidth="300"
Style="{StaticResource FadeInFromBottomAnimation}"
Style="{StaticResource FadeInAnimation}"
mc:Ignorable="d">
<Grid>
<russkyc:ModernRadioButton
Expand Down Expand Up @@ -64,15 +64,18 @@
</Border>
<StackPanel
Grid.Column="1"
Margin="12"
Margin="12,0"
HorizontalAlignment="Stretch"
VerticalAlignment="Center">
<TextBlock
FontSize="14"
FontWeight="Medium"
Foreground="{DynamicResource fg-000}"
Text="{Binding Customer.FullName, UpdateSourceTrigger=PropertyChanged}" />
<ItemsControl VerticalAlignment="Center" ItemsSource="{Binding Services.EditableCollectionView, UpdateSourceTrigger=PropertyChanged}">
<ItemsControl
Margin="0,8,0,0"
VerticalAlignment="Center"
ItemsSource="{Binding Services.EditableCollectionView, UpdateSourceTrigger=PropertyChanged}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
Background="Transparent"
IsTabStop="False"
mc:Ignorable="d">
<Grid Style="{StaticResource FadeInFromBottomAnimation}">
<Grid Style="{StaticResource FadeInAnimation}">
<Border
Padding="5"
HorizontalAlignment="Stretch"
Expand Down
Loading

0 comments on commit 554b712

Please sign in to comment.