Compare commits
69 Commits
homepage-0
...
master
@ -0,0 +1,13 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net7.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\LibraryDTO\LibraryDTO.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
@ -0,0 +1,17 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net7.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\LibraryDTO\LibraryDTO.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
@ -0,0 +1,9 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net7.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
</Project>
|
Before Width: | Height: | Size: 56 KiB |
After Width: | Height: | Size: 2.5 KiB |
@ -1,22 +1,28 @@
|
|||||||
using LivreLand.Model;
|
using LivreLand.Model;
|
||||||
|
using LivreLand.ViewModel;
|
||||||
|
|
||||||
namespace LivreLand.View;
|
namespace LivreLand.View;
|
||||||
|
|
||||||
public partial class ALirePlusTardView : ContentPage
|
public partial class ALirePlusTardView : ContentPage
|
||||||
{
|
{
|
||||||
public List<BookModel> ALirePlusTardBooks { get; set; } = new List<BookModel>()
|
#region Properties
|
||||||
{
|
|
||||||
new BookModel("La horde du contrevent","Alain Damasio","Non lu", 0),
|
|
||||||
};
|
|
||||||
|
|
||||||
public ALirePlusTardView()
|
public ALirePlusTardVM ALirePlusTardVM { get; set; }
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Constructor
|
||||||
|
|
||||||
|
public ALirePlusTardView(ALirePlusTardVM aLirePlusTardVM)
|
||||||
{
|
{
|
||||||
BindingContext = this;
|
ALirePlusTardVM = aLirePlusTardVM;
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
|
BindingContext = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnSelectionChanged(object sender, SelectionChangedEventArgs e)
|
#endregion
|
||||||
{
|
|
||||||
App.Current.MainPage.Navigation.PushAsync(new DetailsLivreView());
|
#region Methods
|
||||||
}
|
|
||||||
|
#endregion
|
||||||
}
|
}
|
@ -1,69 +1,36 @@
|
|||||||
|
using LivreLand.ViewModel;
|
||||||
using System.Windows.Input;
|
using System.Windows.Input;
|
||||||
|
|
||||||
namespace LivreLand.View;
|
namespace LivreLand.View;
|
||||||
|
|
||||||
public partial class BibliothequeView : ContentPage
|
public partial class BibliothequeView : ContentPage
|
||||||
{
|
{
|
||||||
public ICommand TousNavigationCommand { get; }
|
#region Properties
|
||||||
public ICommand EmpruntsPretsNavigationCommand { get; }
|
|
||||||
public ICommand ALirePlusTardNavigationCommand { get; }
|
|
||||||
public ICommand StatutLectureNavigationCommand { get; }
|
|
||||||
public ICommand FavorisNavigationCommand { get; }
|
|
||||||
public ICommand AuteurNavigationCommand { get; }
|
|
||||||
public ICommand DatePublicationNavigationCommand { get; }
|
|
||||||
public ICommand NoteNavigationCommand { get; }
|
|
||||||
|
|
||||||
public BibliothequeView()
|
public BibliothequeVM BibliothequeVM { get; set; }
|
||||||
{
|
|
||||||
TousNavigationCommand = new Command(TousNavigation);
|
|
||||||
EmpruntsPretsNavigationCommand = new Command(EmpruntsPretsNavigation);
|
|
||||||
ALirePlusTardNavigationCommand = new Command(ALirePlusTardNavigation);
|
|
||||||
StatutLectureNavigationCommand = new Command(StatutLectureNavigation);
|
|
||||||
FavorisNavigationCommand = new Command(FavorisNavigation);
|
|
||||||
AuteurNavigationCommand = new Command(AuteurNavigation);
|
|
||||||
DatePublicationNavigationCommand = new Command(DatePublicationNavigation);
|
|
||||||
NoteNavigationCommand = new Command(NoteNavigation);
|
|
||||||
InitializeComponent();
|
|
||||||
}
|
|
||||||
|
|
||||||
//Gestion de la navigation temporaire
|
#endregion
|
||||||
private async void TousNavigation()
|
|
||||||
{
|
|
||||||
await App.Current.MainPage.Navigation.PushAsync(new TousView());
|
|
||||||
}
|
|
||||||
|
|
||||||
private async void EmpruntsPretsNavigation()
|
#region Constructor
|
||||||
{
|
|
||||||
await App.Current.MainPage.Navigation.PushAsync(new EmpruntsPretsView());
|
|
||||||
}
|
|
||||||
|
|
||||||
private async void ALirePlusTardNavigation()
|
public BibliothequeView(BibliothequeVM bibliothequeVM)
|
||||||
{
|
{
|
||||||
await App.Current.MainPage.Navigation.PushAsync(new ALirePlusTardView());
|
BibliothequeVM = bibliothequeVM;
|
||||||
|
InitializeComponent();
|
||||||
|
BindingContext = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void StatutLectureNavigation()
|
#endregion
|
||||||
{
|
|
||||||
await App.Current.MainPage.Navigation.PushAsync(new StatutLectureView());
|
|
||||||
}
|
|
||||||
|
|
||||||
private async void AuteurNavigation()
|
#region Methods
|
||||||
{
|
|
||||||
await App.Current.MainPage.Navigation.PushAsync(new FiltrageAuteurView());
|
|
||||||
}
|
|
||||||
|
|
||||||
private async void FavorisNavigation()
|
protected override void OnAppearing()
|
||||||
{
|
{
|
||||||
await App.Current.MainPage.Navigation.PushAsync(new FavorisView());
|
base.OnAppearing();
|
||||||
}
|
|
||||||
|
|
||||||
private async void DatePublicationNavigation()
|
BibliothequeVM.Manager.GetBooksFromCollectionCommand.Execute(null);
|
||||||
{
|
|
||||||
await App.Current.MainPage.Navigation.PushAsync(new FiltrageDateView());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void NoteNavigation()
|
#endregion
|
||||||
{
|
|
||||||
await App.Current.MainPage.Navigation.PushAsync(new FiltrageNoteView());
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -0,0 +1,115 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
|
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||||
|
xmlns:view="clr-namespace:LivreLand.View"
|
||||||
|
xmlns:contentView="clr-namespace:LivreLand.View.ContentViews"
|
||||||
|
xmlns:viewModel="clr-namespace:ViewModels;assembly=ViewModels"
|
||||||
|
x:Class="LivreLand.View.ContactsView"
|
||||||
|
Title="ContactsView">
|
||||||
|
|
||||||
|
<Grid>
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="auto"/>
|
||||||
|
<RowDefinition Height="10"/>
|
||||||
|
<RowDefinition Height="*"/>
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
|
<view:HeaderPage HeaderTitle="Contacts"
|
||||||
|
HeaderBackButtonText="Mes livres"
|
||||||
|
HeaderPlusButtonVisible="True"
|
||||||
|
HeaderSwitchButtonVisible="True"
|
||||||
|
ButtonPlusTappedCommand="{Binding ContactsVM.Navigator.PopupHomePlusNavigationCommand}"
|
||||||
|
ButtonBackTappedCommand="{Binding ContactsVM.Navigator.PopupBackButtonNavigationCommand}"
|
||||||
|
Grid.Row="0"/>
|
||||||
|
<ScrollView Grid.Row="2">
|
||||||
|
<Grid>
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="40"/>
|
||||||
|
<RowDefinition Height="*"/>
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="5*"/>
|
||||||
|
<ColumnDefinition Width="5*"/>
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
<Grid BackgroundColor="{AppThemeBinding Light={StaticResource HeaderGray}, Dark={StaticResource Gray900}}"
|
||||||
|
Grid.Row="0"
|
||||||
|
Grid.ColumnSpan="2">
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="10"/>
|
||||||
|
<ColumnDefinition Width="auto"/>
|
||||||
|
<ColumnDefinition Width="*"/>
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
|
||||||
|
<Label Text="Contacts"
|
||||||
|
VerticalOptions="Center"
|
||||||
|
Style="{StaticResource HeaderCollectionViewText}"
|
||||||
|
Grid.Column="1"/>
|
||||||
|
</Grid>
|
||||||
|
<Grid HorizontalOptions="Center"
|
||||||
|
Grid.Row="1"
|
||||||
|
Grid.Column="0">
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="auto"/>
|
||||||
|
<RowDefinition Height="5"/>
|
||||||
|
<RowDefinition Height="*"/>
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
<Label Text="+ Add new contact"
|
||||||
|
Grid.Row="0"/>
|
||||||
|
<VerticalStackLayout IsVisible="{Binding ContactsVM.DataFormIsVisible}"
|
||||||
|
Grid.Row="2">
|
||||||
|
<Label Text="Prénom :" />
|
||||||
|
<Entry Placeholder="Saisissez le prénom"
|
||||||
|
Text="{Binding ContactsVM.Manager.GivenFirstName}"/>
|
||||||
|
<Label Text="Nom :"/>
|
||||||
|
<Entry Placeholder="Saisissez le nom"
|
||||||
|
Text="{Binding ContactsVM.Manager.GivenLastName}"/>
|
||||||
|
<Button Text="Enregistrer"
|
||||||
|
BackgroundColor="Transparent"
|
||||||
|
Command="{Binding ContactsVM.Manager.AddContactCommand}">
|
||||||
|
<Button.BorderColor>
|
||||||
|
<AppThemeBinding Light="{StaticResource Black}" Dark="{StaticResource White}" />
|
||||||
|
</Button.BorderColor>
|
||||||
|
<Button.TextColor>
|
||||||
|
<AppThemeBinding Light="{StaticResource Black}" Dark="{StaticResource White}" />
|
||||||
|
</Button.TextColor>
|
||||||
|
</Button>
|
||||||
|
</VerticalStackLayout>
|
||||||
|
<Grid.GestureRecognizers>
|
||||||
|
<TapGestureRecognizer Command="{Binding ContactsVM.AddContactDataFormCommand}"/>
|
||||||
|
</Grid.GestureRecognizers>
|
||||||
|
</Grid>
|
||||||
|
<CollectionView ItemsSource="{Binding ContactsVM.Manager.AllContacts}"
|
||||||
|
SelectedItem="{Binding ContactsVM.Manager.SelectedContact}"
|
||||||
|
SelectionChangedCommand="{Binding ContactsVM.BookLendedCommand}"
|
||||||
|
SelectionChangedCommandParameter="{Binding ContactsVM.Manager.SelectedContact}"
|
||||||
|
SelectionMode="Single"
|
||||||
|
Grid.Row="1"
|
||||||
|
Grid.Column="1">
|
||||||
|
<CollectionView.ItemTemplate>
|
||||||
|
<DataTemplate x:DataType="viewModel:ContactVM">
|
||||||
|
<VerticalStackLayout>
|
||||||
|
<Grid HorizontalOptions="Center">
|
||||||
|
<Label>
|
||||||
|
<Label.Text>
|
||||||
|
<MultiBinding StringFormat="{}{0} {1}">
|
||||||
|
<Binding Path="FirstName" />
|
||||||
|
<Binding Path="LastName" />
|
||||||
|
</MultiBinding>
|
||||||
|
</Label.Text>
|
||||||
|
</Label>
|
||||||
|
</Grid>
|
||||||
|
<contentView:SeparatorEntireView/>
|
||||||
|
</VerticalStackLayout>
|
||||||
|
</DataTemplate>
|
||||||
|
</CollectionView.ItemTemplate>
|
||||||
|
</CollectionView>
|
||||||
|
</Grid>
|
||||||
|
</ScrollView>
|
||||||
|
<Grid HorizontalOptions="End"
|
||||||
|
VerticalOptions="Center"
|
||||||
|
Grid.RowSpan="3">
|
||||||
|
<contentView:AlphabetVerticalMenuView/>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
</ContentPage>
|
@ -0,0 +1,27 @@
|
|||||||
|
using LivreLand.ViewModel;
|
||||||
|
|
||||||
|
namespace LivreLand.View;
|
||||||
|
|
||||||
|
public partial class ContactsView : ContentPage
|
||||||
|
{
|
||||||
|
#region Properties
|
||||||
|
|
||||||
|
public ContactsVM ContactsVM { get; set; }
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Constructor
|
||||||
|
|
||||||
|
public ContactsView(ContactsVM contactsVM)
|
||||||
|
{
|
||||||
|
ContactsVM = contactsVM;
|
||||||
|
InitializeComponent();
|
||||||
|
BindingContext = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Methods
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
@ -1,46 +1,61 @@
|
|||||||
|
using LivreLand.ViewModel;
|
||||||
|
using System.Windows.Input;
|
||||||
|
|
||||||
namespace LivreLand.View.ContentViews;
|
namespace LivreLand.View.ContentViews;
|
||||||
|
|
||||||
public partial class EmpruntsPretsButtonView : ContentView
|
public partial class EmpruntsPretsButtonView : ContentView
|
||||||
{
|
{
|
||||||
public EmpruntsPretsButtonView()
|
#region Properties
|
||||||
{
|
|
||||||
InitializeComponent();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnPretsClicked(object sender, EventArgs e)
|
public static readonly BindableProperty PretButtonBackgroundColorProperty = BindableProperty.Create(nameof(PretButtonBackgroundColor), typeof(Color), typeof(EmpruntsPretsButtonView));
|
||||||
{
|
public Color PretButtonBackgroundColor
|
||||||
if (App.Current.PlatformAppTheme == AppTheme.Light)
|
{
|
||||||
{
|
get => (Color)GetValue(EmpruntsPretsButtonView.PretButtonBackgroundColorProperty);
|
||||||
pretsClicked.BackgroundColor = Colors.Transparent;
|
set => SetValue(EmpruntsPretsButtonView.PretButtonBackgroundColorProperty, value);
|
||||||
pretsClicked.IsEnabled = false;
|
}
|
||||||
empruntsButton.BackgroundColor = Colors.White;
|
|
||||||
empruntsButton.IsEnabled = true;
|
public static readonly BindableProperty PretButtonIsEnabledProperty = BindableProperty.Create(nameof(PretButtonIsEnabled), typeof(bool), typeof(EmpruntsPretsButtonView));
|
||||||
}
|
public bool PretButtonIsEnabled
|
||||||
else
|
{
|
||||||
{
|
get => (bool)GetValue(EmpruntsPretsButtonView.PretButtonIsEnabledProperty);
|
||||||
pretsClicked.BackgroundColor = Colors.Transparent;
|
set => SetValue(EmpruntsPretsButtonView.PretButtonIsEnabledProperty, value);
|
||||||
pretsClicked.IsEnabled = false;
|
}
|
||||||
empruntsButton.BackgroundColor = Colors.Black;
|
|
||||||
empruntsButton.IsEnabled = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnEmpruntsClicked(object sender, EventArgs e)
|
public static readonly BindableProperty PretsButtonCommandProperty = BindableProperty.Create(nameof(PretsButtonCommand), typeof(ICommand), typeof(EmpruntsPretsButtonView));
|
||||||
|
public ICommand PretsButtonCommand
|
||||||
{
|
{
|
||||||
if (App.Current.PlatformAppTheme == AppTheme.Light)
|
get { return (ICommand)GetValue(PretsButtonCommandProperty); }
|
||||||
{
|
set { SetValue(PretsButtonCommandProperty, value); }
|
||||||
pretsClicked.BackgroundColor = Colors.White;
|
}
|
||||||
pretsClicked.IsEnabled = true;
|
|
||||||
empruntsButton.BackgroundColor = Colors.Transparent;
|
|
||||||
empruntsButton.IsEnabled = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
pretsClicked.BackgroundColor = Colors.Black;
|
|
||||||
pretsClicked.IsEnabled = true;
|
|
||||||
empruntsButton.BackgroundColor = Colors.Transparent;
|
|
||||||
empruntsButton.IsEnabled = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
public static readonly BindableProperty EmpruntButtonBackgroundColorProperty = BindableProperty.Create(nameof(EmpruntButtonBackgroundColor), typeof(Color), typeof(EmpruntsPretsButtonView));
|
||||||
|
public Color EmpruntButtonBackgroundColor
|
||||||
|
{
|
||||||
|
get => (Color)GetValue(EmpruntsPretsButtonView.EmpruntButtonBackgroundColorProperty);
|
||||||
|
set => SetValue(EmpruntsPretsButtonView.EmpruntButtonBackgroundColorProperty, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static readonly BindableProperty EmpruntButtonIsEnabledProperty = BindableProperty.Create(nameof(EmpruntButtonIsEnabled), typeof(bool), typeof(EmpruntsPretsButtonView));
|
||||||
|
public bool EmpruntButtonIsEnabled
|
||||||
|
{
|
||||||
|
get => (bool)GetValue(EmpruntsPretsButtonView.EmpruntButtonIsEnabledProperty);
|
||||||
|
set => SetValue(EmpruntsPretsButtonView.EmpruntButtonIsEnabledProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly BindableProperty EmpruntsButtonCommandProperty = BindableProperty.Create(nameof(EmpruntsButtonCommand), typeof(ICommand), typeof(EmpruntsPretsButtonView));
|
||||||
|
public ICommand EmpruntsButtonCommand
|
||||||
|
{
|
||||||
|
get { return (ICommand)GetValue(EmpruntsButtonCommandProperty); }
|
||||||
|
set { SetValue(EmpruntsButtonCommandProperty, value); }
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Constructor
|
||||||
|
|
||||||
|
public EmpruntsPretsButtonView()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
}
|
}
|
@ -1,12 +1,27 @@
|
|||||||
using CommunityToolkit.Maui.Views;
|
using CommunityToolkit.Maui.Views;
|
||||||
|
using LivreLand.ViewModel;
|
||||||
|
|
||||||
namespace LivreLand.View.ContentViews;
|
namespace LivreLand.View.ContentViews;
|
||||||
|
|
||||||
public partial class PopupHomePlusButtonView : Popup
|
public partial class PopupHomePlusButtonView : Popup
|
||||||
{
|
{
|
||||||
public PopupHomePlusButtonView()
|
|
||||||
|
#region Properties
|
||||||
|
|
||||||
|
public NavigatorVM Navigator { get; private set; }
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
#region Constructor
|
||||||
|
|
||||||
|
public PopupHomePlusButtonView(NavigatorVM navigatorVM)
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
Navigator = navigatorVM;
|
||||||
|
InitializeComponent();
|
||||||
Size = new Size(0.8 * (DeviceDisplay.Current.MainDisplayInfo.Width / DeviceDisplay.Current.MainDisplayInfo.Density), 0.5 * (DeviceDisplay.Current.MainDisplayInfo.Width / DeviceDisplay.Current.MainDisplayInfo.Density));
|
Size = new Size(0.8 * (DeviceDisplay.Current.MainDisplayInfo.Width / DeviceDisplay.Current.MainDisplayInfo.Density), 0.5 * (DeviceDisplay.Current.MainDisplayInfo.Width / DeviceDisplay.Current.MainDisplayInfo.Density));
|
||||||
}
|
BindingContext = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
}
|
}
|
@ -0,0 +1,36 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
|
<toolkit:Popup xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||||
|
xmlns:contentView="clr-namespace:LivreLand.View.ContentViews"
|
||||||
|
xmlns:toolkit="http://schemas.microsoft.com/dotnet/2022/maui/toolkit"
|
||||||
|
x:Class="LivreLand.View.ContentViews.PopupISBNView"
|
||||||
|
HorizontalOptions="Center"
|
||||||
|
VerticalOptions="Center"
|
||||||
|
Color="Transparent">
|
||||||
|
|
||||||
|
<Border>
|
||||||
|
<Grid BackgroundColor="{AppThemeBinding Light={StaticResource PopupBackground}, Dark={StaticResource Black}}">
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="auto"/>
|
||||||
|
<RowDefinition Height="auto"/>
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
|
<Grid Grid.Row="0"
|
||||||
|
Margin="5">
|
||||||
|
<Label Text="Saisir l'ISBN"
|
||||||
|
Style="{StaticResource MasterStateBookText}"/>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
<Grid Grid.Row="1"
|
||||||
|
Margin="5">
|
||||||
|
<Entry Text="{Binding Manager.EntryText}"
|
||||||
|
ReturnCommand="{Binding AddBookCommand}"
|
||||||
|
ReturnCommandParameter="{Binding Manager.EntryText}"/>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
<Border.StrokeShape>
|
||||||
|
<RoundRectangle CornerRadius="10" />
|
||||||
|
</Border.StrokeShape>
|
||||||
|
</Border>
|
||||||
|
|
||||||
|
</toolkit:Popup>
|
@ -0,0 +1,14 @@
|
|||||||
|
using CommunityToolkit.Maui.Views;
|
||||||
|
using LivreLand.ViewModel;
|
||||||
|
|
||||||
|
namespace LivreLand.View.ContentViews;
|
||||||
|
|
||||||
|
public partial class PopupISBNView : Popup
|
||||||
|
{
|
||||||
|
public PopupISBNView(PopupISBNVM popupISBNVM)
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
BindingContext = popupISBNVM;
|
||||||
|
Size = new Size(0.8 * (DeviceDisplay.Current.MainDisplayInfo.Width / DeviceDisplay.Current.MainDisplayInfo.Density), 0.5 * (DeviceDisplay.Current.MainDisplayInfo.Width / DeviceDisplay.Current.MainDisplayInfo.Density));
|
||||||
|
}
|
||||||
|
}
|
@ -1,9 +1,23 @@
|
|||||||
|
using LivreLand.ViewModel;
|
||||||
|
|
||||||
namespace LivreLand.View;
|
namespace LivreLand.View;
|
||||||
|
|
||||||
public partial class DetailsLivreView : ContentPage
|
public partial class DetailsLivreView : ContentPage
|
||||||
{
|
{
|
||||||
public DetailsLivreView()
|
#region Properties
|
||||||
|
|
||||||
|
public DetailsLivreVM DetailsLivreVM { get; set; }
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Constructor
|
||||||
|
|
||||||
|
public DetailsLivreView(DetailsLivreVM detailsLivreVM)
|
||||||
{
|
{
|
||||||
|
DetailsLivreVM = detailsLivreVM;
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
|
BindingContext = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
}
|
}
|
@ -1,27 +1,28 @@
|
|||||||
using LivreLand.Model;
|
using LivreLand.Model;
|
||||||
|
using LivreLand.ViewModel;
|
||||||
|
|
||||||
namespace LivreLand.View;
|
namespace LivreLand.View;
|
||||||
|
|
||||||
public partial class EmpruntsPretsView : ContentPage
|
public partial class EmpruntsPretsView : ContentPage
|
||||||
{
|
{
|
||||||
public List<BookModel> AntoineBooks { get; set; } = new List<BookModel>()
|
#region Properties
|
||||||
{
|
|
||||||
new BookModel("The Wake","Scott Snyder","Terminé", 0),
|
|
||||||
};
|
|
||||||
|
|
||||||
public List<BookModel> AudreyPoucletBooks { get; set; } = new List<BookModel>()
|
public EmpruntsPretsVM EmpruntsPretsVM { get; set; }
|
||||||
{
|
|
||||||
new BookModel("Les feux de Cibola","James S. A. Corey","Terminé", 0),
|
|
||||||
};
|
|
||||||
|
|
||||||
public EmpruntsPretsView()
|
#endregion
|
||||||
|
|
||||||
|
#region Constructor
|
||||||
|
|
||||||
|
public EmpruntsPretsView(EmpruntsPretsVM empruntsPretsVM)
|
||||||
{
|
{
|
||||||
BindingContext = this;
|
EmpruntsPretsVM = empruntsPretsVM;
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
|
BindingContext = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnSelectionChanged(object sender, SelectionChangedEventArgs e)
|
#endregion
|
||||||
{
|
|
||||||
App.Current.MainPage.Navigation.PushAsync(new DetailsLivreView());
|
#region Methods
|
||||||
}
|
|
||||||
|
#endregion
|
||||||
}
|
}
|
@ -1,23 +1,28 @@
|
|||||||
using LivreLand.Model;
|
using LivreLand.Model;
|
||||||
|
using LivreLand.ViewModel;
|
||||||
|
|
||||||
namespace LivreLand.View;
|
namespace LivreLand.View;
|
||||||
|
|
||||||
public partial class FavorisView : ContentPage
|
public partial class FavorisView : ContentPage
|
||||||
{
|
{
|
||||||
public List<BookModel> FavorisBooks { get; set; } = new List<BookModel>()
|
#region Properties
|
||||||
{
|
|
||||||
new BookModel("La zone du dehors","Alain Damasio","Terminé", 0),
|
|
||||||
new BookModel("Le problème à trois corps","Cixin Liu","Terminé", 0)
|
|
||||||
};
|
|
||||||
|
|
||||||
public FavorisView()
|
public FavorisVM FavorisVM { get; set; }
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Constructor
|
||||||
|
|
||||||
|
public FavorisView(FavorisVM favorisVM)
|
||||||
{
|
{
|
||||||
BindingContext = this;
|
FavorisVM = favorisVM;
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
}
|
BindingContext = this;
|
||||||
|
|
||||||
void OnSelectionChanged(object sender, SelectionChangedEventArgs e)
|
|
||||||
{
|
|
||||||
App.Current.MainPage.Navigation.PushAsync(new DetailsLivreView());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Methods
|
||||||
|
|
||||||
|
#endregion
|
||||||
}
|
}
|
@ -1,9 +1,27 @@
|
|||||||
|
using LivreLand.ViewModel;
|
||||||
|
|
||||||
namespace LivreLand.View;
|
namespace LivreLand.View;
|
||||||
|
|
||||||
public partial class FiltrageAuteurView : ContentPage
|
public partial class FiltrageAuteurView : ContentPage
|
||||||
{
|
{
|
||||||
public FiltrageAuteurView()
|
#region Properties
|
||||||
|
|
||||||
|
public FiltrageAuteurVM FiltrageAuteurVM { get; set; }
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Constructor
|
||||||
|
|
||||||
|
public FiltrageAuteurView(FiltrageAuteurVM filtrageAuteurVM)
|
||||||
{
|
{
|
||||||
|
FiltrageAuteurVM = filtrageAuteurVM;
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
|
BindingContext = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Methods
|
||||||
|
|
||||||
|
#endregion
|
||||||
}
|
}
|
@ -1,9 +1,27 @@
|
|||||||
|
using LivreLand.ViewModel;
|
||||||
|
|
||||||
namespace LivreLand.View;
|
namespace LivreLand.View;
|
||||||
|
|
||||||
public partial class FiltrageDateView : ContentPage
|
public partial class FiltrageDateView : ContentPage
|
||||||
{
|
{
|
||||||
public FiltrageDateView()
|
#region Properties
|
||||||
{
|
|
||||||
InitializeComponent();
|
public FiltrageDateVM FiltrageDateVM { get; set; }
|
||||||
}
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Constructor
|
||||||
|
|
||||||
|
public FiltrageDateView(FiltrageDateVM filtrageDateVM)
|
||||||
|
{
|
||||||
|
FiltrageDateVM = filtrageDateVM;
|
||||||
|
InitializeComponent();
|
||||||
|
BindingContext = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Methods
|
||||||
|
|
||||||
|
#endregion
|
||||||
}
|
}
|
@ -1,9 +1,27 @@
|
|||||||
|
using LivreLand.ViewModel;
|
||||||
|
|
||||||
namespace LivreLand.View;
|
namespace LivreLand.View;
|
||||||
|
|
||||||
public partial class FiltrageNoteView : ContentPage
|
public partial class FiltrageNoteView : ContentPage
|
||||||
{
|
{
|
||||||
public FiltrageNoteView()
|
#region Properties
|
||||||
{
|
|
||||||
InitializeComponent();
|
public FiltrageNoteVM FiltrageNoteVM { get; set; }
|
||||||
}
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Constructor
|
||||||
|
|
||||||
|
public FiltrageNoteView(FiltrageNoteVM filtrageNoteVM)
|
||||||
|
{
|
||||||
|
FiltrageNoteVM = filtrageNoteVM;
|
||||||
|
InitializeComponent();
|
||||||
|
BindingContext = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Methods
|
||||||
|
|
||||||
|
#endregion
|
||||||
}
|
}
|
@ -1,18 +1,30 @@
|
|||||||
using CommunityToolkit.Maui.Views;
|
using LivreLand.ViewModel;
|
||||||
using LivreLand.View.ContentViews;
|
using System.Windows.Input;
|
||||||
|
|
||||||
namespace LivreLand.View;
|
namespace LivreLand.View;
|
||||||
|
|
||||||
public partial class HeaderHome : ContentView
|
public partial class HeaderHome : ContentView
|
||||||
{
|
{
|
||||||
public HeaderHome()
|
|
||||||
{
|
|
||||||
InitializeComponent();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnPlusClicked(object sender, EventArgs e)
|
#region Properties
|
||||||
|
|
||||||
|
public NavigatorVM Navigator { get; private set; }
|
||||||
|
|
||||||
|
public static readonly BindableProperty ButtonTappedCommandProperty = BindableProperty.Create(nameof(ButtonTappedCommand), typeof(ICommand), typeof(HeaderPage));
|
||||||
|
public ICommand ButtonTappedCommand
|
||||||
{
|
{
|
||||||
var plusPopup = new PopupHomePlusButtonView();
|
get { return (ICommand)GetValue(ButtonTappedCommandProperty); }
|
||||||
App.Current.MainPage.ShowPopup(plusPopup);
|
set { SetValue(ButtonTappedCommandProperty, value); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Constructor
|
||||||
|
|
||||||
|
public HeaderHome()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
}
|
}
|
@ -0,0 +1,69 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
|
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||||
|
xmlns:toolkit="http://schemas.microsoft.com/dotnet/2022/maui/toolkit"
|
||||||
|
xmlns:cv="clr-namespace:Camera.MAUI;assembly=Camera.MAUI"
|
||||||
|
x:Class="LivreLand.View.ScanView"
|
||||||
|
Title="ScanView">
|
||||||
|
|
||||||
|
<Grid>
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="*"/>
|
||||||
|
<RowDefinition Height="auto"/>
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
|
<Grid Grid.Row="0">
|
||||||
|
<cv:CameraView x:Name="cameraView"
|
||||||
|
BarCodeDetectionEnabled="True"
|
||||||
|
Camera="{Binding ScanVM.Camera}"
|
||||||
|
Cameras="{Binding ScanVM.Cameras}"
|
||||||
|
NumCamerasDetected="{Binding ScanVM.CamerasCount}"
|
||||||
|
BarCodeResults="{Binding ScanVM.BarCodeResult}"
|
||||||
|
WidthRequest="300"
|
||||||
|
HeightRequest="200">
|
||||||
|
<cv:CameraView.Behaviors>
|
||||||
|
<toolkit:EventToCommandBehavior EventName="BarcodeDetected"
|
||||||
|
Command="{Binding ScanVM.BarcodeDetectCommand}"/>
|
||||||
|
<toolkit:EventToCommandBehavior EventName="CamerasLoaded"
|
||||||
|
Command="{Binding ScanVM.CamerasLoadCommand}"/>
|
||||||
|
</cv:CameraView.Behaviors>
|
||||||
|
</cv:CameraView>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
<Grid Margin="2"
|
||||||
|
Grid.Row="1">
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="auto"/>
|
||||||
|
<ColumnDefinition Width="*"/>
|
||||||
|
<ColumnDefinition Width="auto"/>
|
||||||
|
<ColumnDefinition Width="*"/>
|
||||||
|
<ColumnDefinition Width="auto"/>
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
|
||||||
|
<Grid Grid.Column="0">
|
||||||
|
<Label Text="Annuler"
|
||||||
|
TextColor="{StaticResource Blue100Accent}"/>
|
||||||
|
<Grid.GestureRecognizers>
|
||||||
|
<TapGestureRecognizer Command="{Binding ScanVM.Navigator.PopupBackButtonNavigationCommand}"/>
|
||||||
|
</Grid.GestureRecognizers>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
|
||||||
|
<Grid IsVisible="{Binding ScanVM.AddIsVisible}"
|
||||||
|
Grid.Column="2">
|
||||||
|
<Label Text="Ajouter le livre !"
|
||||||
|
TextColor="{StaticResource Blue100Accent}"/>
|
||||||
|
<Grid.GestureRecognizers>
|
||||||
|
<TapGestureRecognizer Command="{Binding ScanVM.AddBookISBNDetectedCommand}"
|
||||||
|
CommandParameter="{Binding ScanVM.BarcodeText}"/>
|
||||||
|
</Grid.GestureRecognizers>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
<Label Text="{Binding ScanVM.BarcodeText}"
|
||||||
|
TextColor="{StaticResource Blue100Accent}"
|
||||||
|
Grid.Column="4"/>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
</ContentPage>
|
@ -0,0 +1,24 @@
|
|||||||
|
using LivreLand.ViewModel;
|
||||||
|
|
||||||
|
namespace LivreLand.View;
|
||||||
|
|
||||||
|
public partial class ScanView : ContentPage
|
||||||
|
{
|
||||||
|
#region Properties
|
||||||
|
|
||||||
|
public ScanVM ScanVM { get; set; }
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Constructor
|
||||||
|
|
||||||
|
public ScanView(ScanVM scanVM)
|
||||||
|
{
|
||||||
|
ScanVM = scanVM;
|
||||||
|
InitializeComponent();
|
||||||
|
ScanVM.CameraView = cameraView; //ToRemove
|
||||||
|
BindingContext = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
@ -1,30 +1,28 @@
|
|||||||
using LivreLand.Model;
|
using LivreLand.Model;
|
||||||
|
using LivreLand.ViewModel;
|
||||||
|
|
||||||
namespace LivreLand.View;
|
namespace LivreLand.View;
|
||||||
|
|
||||||
public partial class StatutLectureView : ContentPage
|
public partial class StatutLectureView : ContentPage
|
||||||
{
|
{
|
||||||
public List<BookModel> NonLuBooks { get; set; } = new List<BookModel>()
|
#region Properties
|
||||||
{
|
|
||||||
new BookModel("La horde du contrevent","Alain Damasio","Non lu", 0),
|
public StatutLectureVM StatutLectureVM { get; set; }
|
||||||
};
|
|
||||||
|
#endregion
|
||||||
public List<BookModel> TermineBooks { get; set; } = new List<BookModel>()
|
|
||||||
{
|
#region Constructor
|
||||||
new BookModel("La zone du dehors","Alain Damasio","Terminé", 0),
|
|
||||||
new BookModel("L'équateur d'Einstein","Cixin Liu","Terminé", 0),
|
public StatutLectureView(StatutLectureVM statutLectureVM)
|
||||||
new BookModel("La forêt sombre","Cixin Liu","Terminé", 0),
|
|
||||||
new BookModel("Le problème à trois corps","Cixin Liu","Terminé", 0)
|
|
||||||
};
|
|
||||||
|
|
||||||
public StatutLectureView()
|
|
||||||
{
|
{
|
||||||
BindingContext = this;
|
StatutLectureVM = statutLectureVM;
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
|
BindingContext = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnSelectionChanged(object sender, SelectionChangedEventArgs e)
|
#endregion
|
||||||
{
|
|
||||||
App.Current.MainPage.Navigation.PushAsync(new DetailsLivreView());
|
#region Methods
|
||||||
}
|
|
||||||
|
#endregion
|
||||||
}
|
}
|
@ -1,30 +1,30 @@
|
|||||||
using LivreLand.Model;
|
using LivreLand.Model;
|
||||||
|
using LivreLand.ViewModel;
|
||||||
|
using ViewModels;
|
||||||
|
|
||||||
namespace LivreLand.View;
|
namespace LivreLand.View;
|
||||||
|
|
||||||
public partial class TousView : ContentPage
|
public partial class TousView : ContentPage
|
||||||
{
|
{
|
||||||
public List<BookModel> DamasioBooks { get; set; } = new List<BookModel>()
|
|
||||||
{
|
#region Properties
|
||||||
new BookModel("La horde du contrevent","Alain Damasio","Non lu", 0),
|
|
||||||
new BookModel("La zone du dehors","Alain Damasio","Terminé", 0),
|
public TousVM TousVM { get; set; }
|
||||||
};
|
|
||||||
|
#endregion
|
||||||
public List<BookModel> LiuBooks { get; set; } = new List<BookModel>()
|
|
||||||
{
|
#region Constructor
|
||||||
new BookModel("L'équateur d'Einstein","Cixin Liu","Terminé", 0),
|
|
||||||
new BookModel("La forêt sombre","Cixin Liu","Terminé", 0),
|
public TousView(TousVM tousVM)
|
||||||
new BookModel("Le problème à trois corps","Cixin Liu","Terminé", 0)
|
|
||||||
};
|
|
||||||
|
|
||||||
public TousView()
|
|
||||||
{
|
{
|
||||||
BindingContext = this;
|
TousVM = tousVM;
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
}
|
BindingContext = this;
|
||||||
|
}
|
||||||
|
|
||||||
void OnSelectionChanged(object sender, SelectionChangedEventArgs e)
|
#endregion
|
||||||
{
|
|
||||||
App.Current.MainPage.Navigation.PushAsync(new DetailsLivreView());
|
#region Methods
|
||||||
}
|
|
||||||
|
#endregion
|
||||||
}
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net7.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
</Project>
|
@ -0,0 +1,9 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net7.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
</Project>
|
@ -0,0 +1,426 @@
|
|||||||
|
# **LIVRE LAND**
|
||||||
|
|
||||||
|
## Bonjour et bienvenue sur le dépôt du projet LIVRE LAND ! 👋
|
||||||
|
|
||||||
|
*******
|
||||||
|
|
||||||
|
### Sommaire
|
||||||
|
1. [Accessibilité](#acces)
|
||||||
|
2. [Progression](#progression)
|
||||||
|
3. [Présentation du projet](#presentation)
|
||||||
|
4. [Architecture](#architecture)
|
||||||
|
5. [Contenu](#contenu)
|
||||||
|
6. [Auteurs](#auteurs)
|
||||||
|
|
||||||
|
*******
|
||||||
|
|
||||||
|
<div id='acces'/>
|
||||||
|
|
||||||
|
Pour accéder au code de l'application, vous pouvez cloner la branche `master` du dépôt Code#0 et ouvrir celle-ci dans `Microsoft Visual Studio` par exemple.
|
||||||
|
|
||||||
|
Disponible sur :
|
||||||
|
![](https://img.shields.io/badge/Android-3DDC84?style=for-the-badge&logo=android&logoColor=white)
|
||||||
|
![](https://img.shields.io/badge/iOS-000000?style=for-the-badge&logo=ios&logoColor=white)
|
||||||
|
|
||||||
|
> **Warning**: L'application est fonctionnelle sous Windows et Android mais n'a pas été testée sous IOS.
|
||||||
|
|
||||||
|
- Dans la branche **Master**, vous retrouverez l'intégralité de l'application avec les fonctionnalités du `TP2` ainsi que le scan de code-barres.
|
||||||
|
|
||||||
|
- Dans la branche **TP3**, vous retrouverez l'implémentation du `MVVM Community Toolkit` dans notre application.
|
||||||
|
|
||||||
|
*******
|
||||||
|
|
||||||
|
<div id='progression'/>
|
||||||
|
|
||||||
|
## 🚧 __EN PROGRESSION__
|
||||||
|
|
||||||
|
### Étape 1 : Développement des vues en XAML
|
||||||
|
- Intégralité des pages proposées sur la page d'accueil développées
|
||||||
|
- Mode clair & Mode sombre disponibles (pas très esthétique)
|
||||||
|
- Utilisable en mode portrait ou mode paysage
|
||||||
|
- Exploitation des Styles et des Content View réutilisables
|
||||||
|
- Mise à disposition de quelques données dans un Stub pour la présentation des vues
|
||||||
|
- View Model non utilisés et fonctionnalités pas toutes mises en place (seulement les vues)
|
||||||
|
- Navigation généralement utilisable mais pas parfaitement codée
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Étape 2 : Personnal MVVM Toolkit
|
||||||
|
|
||||||
|
La création de ce `Toolkit Personnel` a pour but de faciliter le développement de l'application en fournissant un ensemble de fonctionnalités et de composants réutilisables. De plus, à l'aide d'une classe comme `RelayCommand`, notre objectif est de ne pas inclure dans nos ViewModels une dépendance avec les Commands de .NET MAUI.
|
||||||
|
|
||||||
|
Nous pouvons représenter la structure de notre toolkit avec le diagramme suivant :
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
classDiagram
|
||||||
|
direction LR
|
||||||
|
class INotifyPropertyChanged {
|
||||||
|
<<interface>>
|
||||||
|
}
|
||||||
|
|
||||||
|
class ObservableObject{
|
||||||
|
+PropertyChanged: event PropertyChangedEventHandler?;
|
||||||
|
#OnPropertyChanged (string PropertyName = null) : void
|
||||||
|
#SetProperty<T> (T member, T value, Action<T> action, string propertyName = null) : void
|
||||||
|
#SetProperty<T> (ref T member, T value, string propertyName = null) : void
|
||||||
|
}
|
||||||
|
|
||||||
|
class BaseViewModel{
|
||||||
|
+Model: TModel;
|
||||||
|
-model: TModel;
|
||||||
|
+BaseViewModel(TModel model)
|
||||||
|
+BaseViewModel() : this(default)
|
||||||
|
}
|
||||||
|
|
||||||
|
class ICommand{
|
||||||
|
<<interface>>
|
||||||
|
}
|
||||||
|
|
||||||
|
class RelayCommand{
|
||||||
|
+CanExecuteChanged: event EventHandler?;
|
||||||
|
+CanExecute (object? parameter) : bool
|
||||||
|
+Execute (object? parameter) : void
|
||||||
|
+RefreshCommand() : void
|
||||||
|
}
|
||||||
|
|
||||||
|
ObservableObject ..|> INotifyPropertyChanged
|
||||||
|
BaseViewModel --|> ObservableObject
|
||||||
|
RelayCommand ..|> ICommand
|
||||||
|
```
|
||||||
|
|
||||||
|
Cette structure est une version remplaçant pour le moment le `Community Toolkit` mis en place par Microsoft qui permet aussi de supprimer beaucoup de code inutile en remplaçant celui-ci par des annotations et des classes partielles.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Étape 3 : MVVM
|
||||||
|
|
||||||
|
Nous utilisons au sein de notre projet le **patron d'architecture MVVM** avec les ViewModels Wrapping et Applicatives.
|
||||||
|
|
||||||
|
Nous retrouvons donc les 3 grandes parties du patron :
|
||||||
|
|
||||||
|
- **Model** :
|
||||||
|
Le `Model` représente la `logique métier`. Il est écrit en `C#` et est adpaté pour diifférentes applications.
|
||||||
|
|
||||||
|
- **View** :
|
||||||
|
Les `Vues` sont écrites en `XAML` et représentent l'interface utilisateur avec les vues de l'application. Le `Data Binding` est utilisé entre les propriétés du XAML et celles des ViewModels. Enfin, des évènements sont déclenchés à partir de certains composants des vues.
|
||||||
|
|
||||||
|
- **ViewModel** :
|
||||||
|
Les `ViewModels` sont écrits en `C#` et sont divisables en deux grandes catégories :
|
||||||
|
* Les **Wrapping ViewModel** encapsulent les données du modèle et exposent des propriétés et des commandes nécessaires à la vue pour interagir avec le modèle.
|
||||||
|
* Les **Applicative ViewModel** peuvent inclure une logique métier spécifique et des propriétés calculées, elles peuvent également exposer des commandes pour effectuer des actions spécifiques liées à la vue.
|
||||||
|
|
||||||
|
Le schéma suivant montre bien les relations entre les grandes parties du `patron MVVM` :
|
||||||
|
|
||||||
|
![Schema_MVVM](documentation/schema_mvvm.png)
|
||||||
|
|
||||||
|
Le **diagramme de classes** pouvant être extrèmement grand à cause des multiples classes au sein de notre projet, j'ai décidé de représenter une partie de celui-ci qui pourrait se répéter pour toutes les autres parties. L'objectif principal étant de comprendre comment fonctionne le **modèle MVVM** et comment les classes intéragissent entre elles, j'ai choisi de faire mon exemple avec la partie des livres qui est la plus générale du sujet.
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
classDiagram
|
||||||
|
class Book {
|
||||||
|
Id: string
|
||||||
|
Title: string
|
||||||
|
Publishers: List<string>
|
||||||
|
PublishDate: DateTime
|
||||||
|
ISBN13: string
|
||||||
|
Series: List<string>
|
||||||
|
NbPages: int
|
||||||
|
Format: string
|
||||||
|
Language: Languages
|
||||||
|
Contributors: List<Contributor>
|
||||||
|
ImageSmall: string
|
||||||
|
ImageMedium: string
|
||||||
|
ImageLarge: string
|
||||||
|
Works: List<Work>
|
||||||
|
Authors: List<Author>
|
||||||
|
Status: Status
|
||||||
|
UserTags: List<string>
|
||||||
|
UserRating: float?
|
||||||
|
UserNote: string
|
||||||
|
Equals(other: Book): bool
|
||||||
|
GetHashCode(): int
|
||||||
|
}
|
||||||
|
|
||||||
|
class DetailsLivreView {
|
||||||
|
DetailsLivreVM: DetailsLivreVM
|
||||||
|
}
|
||||||
|
|
||||||
|
class DetailsLivreVM {
|
||||||
|
isPickerVisible: bool
|
||||||
|
addFavorisButtonText: string
|
||||||
|
Manager: ManagerVM
|
||||||
|
Navigator: NavigatorVM
|
||||||
|
Book: BookVM
|
||||||
|
IsPickerVisible: bool
|
||||||
|
AddFavorisButtonText: string
|
||||||
|
BackButtonCommand: ICommand
|
||||||
|
ShowPickerCommand: ICommand
|
||||||
|
AddRemoveBookToFavoritesCommand: ICommand
|
||||||
|
AddBookToReadListCommand: ICommand
|
||||||
|
LoanBookCommand: ICommand
|
||||||
|
RemoveBookCommand: ICommand
|
||||||
|
OpenInfoCommand: ICommand
|
||||||
|
BackButton()
|
||||||
|
ShowPicker()
|
||||||
|
AddRemoveBookToFavorites(bookVM: BookVM)
|
||||||
|
AddBookToReadList(bookVM: BookVM)
|
||||||
|
LoanBook(bookVM: BookVM)
|
||||||
|
RemoveBook(bookVM: BookVM)
|
||||||
|
OpenInfo()
|
||||||
|
}
|
||||||
|
|
||||||
|
class BookVM {
|
||||||
|
Id: string
|
||||||
|
ISBN13: string
|
||||||
|
Title: string
|
||||||
|
Publishers: List<string>
|
||||||
|
PublishDate: DateTime
|
||||||
|
Works: List<WorkVM>
|
||||||
|
WorkDescription: string
|
||||||
|
Authors: List<AuthorVM>
|
||||||
|
Author: string
|
||||||
|
Status: Status
|
||||||
|
NbPages: int
|
||||||
|
Language: Languages
|
||||||
|
ImageSmall: string
|
||||||
|
UserRating: float?
|
||||||
|
}
|
||||||
|
|
||||||
|
DetailsLivreView --> DetailsLivreVM
|
||||||
|
DetailsLivreVM --> BookVM
|
||||||
|
DetailsLivreVM --> ManagerVM
|
||||||
|
DetailsLivreVM --> NavigatorVM
|
||||||
|
BookVM --> Book
|
||||||
|
BookVM --> WorkVM
|
||||||
|
BookVM --> AuthorVM
|
||||||
|
```
|
||||||
|
|
||||||
|
*******
|
||||||
|
|
||||||
|
<div id='presentation'/>
|
||||||
|
|
||||||
|
## **Présentation**
|
||||||
|
|
||||||
|
LivreLand : votre bibliothèque connectée !
|
||||||
|
Retrouver tous vos livres préférés en un clic.
|
||||||
|
|
||||||
|
*******
|
||||||
|
|
||||||
|
<div id='contenu'/>
|
||||||
|
|
||||||
|
## Fonctionnalités
|
||||||
|
|
||||||
|
**TP2 - Base** :
|
||||||
|
- [x] Page d'accueil
|
||||||
|
- [x] Affichage des livres de l'utilisateur : afficher tous les livres de l'utilisateur dans la vue BooksPage et permettre la sélection d'un livre et la navigation vers la page BookPage
|
||||||
|
* seule la note n'est pas encore affichée sous la forme d'étoiles (commencée dans `star-notation-22-10`)
|
||||||
|
- [x] Filtrage par auteur et par date de publication : afficher dans la vue de filtrage (FilterPage)
|
||||||
|
|
||||||
|
**TP2 - Ajouts** :
|
||||||
|
- [x] Changer le statut de lecture d'un livre
|
||||||
|
- [x] Ajouter un livre aux favoris
|
||||||
|
- [x] Filtrer les livres par Auteur, Date de publication, Note
|
||||||
|
* le filtrage fonctionne, au deuxième clique sur une date par exemple une fois une première date visitée, je remarque des soucis avec de temps à autre une exception
|
||||||
|
- [x] Ajouter un livre à sa collection en saisissant l'ISBN
|
||||||
|
- [x] Supprimer un livre
|
||||||
|
- [x] Prêter un livre (et ajouter un contact si besoin)
|
||||||
|
* la page avec les contacts n'est pas esthétiquement très réussie
|
||||||
|
- [x] Consulter la liste des livres prêtés
|
||||||
|
* j'ai fait le choix de n'afficher que les livres _actuellement_ prêtés ou empruntés
|
||||||
|
|
||||||
|
_Erreurs rencontrées_ :
|
||||||
|
* L'ajout en favoris fonctionne, cependant il m'ait arrivé lorque je choisissais à partir de la page BooksPage d'ajouter un livre qui ne se trouve pas sur la première page, que celui-ci supprime souvent tous les livres déjà en favoris.
|
||||||
|
* J'ai également eu à certains moments des problèmes avec l'accession à la page de détails et une double page qui s'ouvrait; dans ce cas je relance généralement l'application.
|
||||||
|
|
||||||
|
**TP3** :
|
||||||
|
- [X] Modifier l'intégralité du code pour que l'application utilise désormais le MVVM Community Toolkit à la place du toolkit personnel
|
||||||
|
* lecture de la documentation et implémentation dans la branche `TP3` (à affiner pour respecter parfaitement le Toolkit)
|
||||||
|
|
||||||
|
**TP 4** :
|
||||||
|
Ajouter les vues et les VM nécessaires pour permettre :
|
||||||
|
- [x] Le scan de code-barres afin d'ajouter de nouveaux livres
|
||||||
|
* le scan de code-barres fonctionne mais le livre n'est pas encore directement ajouté dans la liste (affichage de l'isbn dans en bas de page & du bouton d'ajout du livre)
|
||||||
|
- [X] La recherche en ligne (via le web service)
|
||||||
|
* il est possible d'accéder à la page d'un livre en ligne en cliquant dans la partie "Infos en ligne" de la page Détails
|
||||||
|
|
||||||
|
*******
|
||||||
|
|
||||||
|
<div id='architecture'/>
|
||||||
|
|
||||||
|
## Architectures du modèle et des services fournises
|
||||||
|
|
||||||
|
Dans cette partie, vous retrouverez dans un premier temps deux diagrammes mis à disposition dans le sujet représentant d'abord le `Modèle` puis les `Services et Interfaces` :
|
||||||
|
|
||||||
|
### Modèle
|
||||||
|
```mermaid
|
||||||
|
classDiagram
|
||||||
|
direction LR
|
||||||
|
class Book {
|
||||||
|
+Id : string
|
||||||
|
+Title : string
|
||||||
|
+Publishers : List~string~
|
||||||
|
+PublishDate : DateTime
|
||||||
|
+ISBN13 : string
|
||||||
|
+Series : List~string~
|
||||||
|
+NbPages : int
|
||||||
|
+Format : string
|
||||||
|
+ImageSmall : string
|
||||||
|
+ImageMedium : string
|
||||||
|
+ImageLarge : string
|
||||||
|
}
|
||||||
|
|
||||||
|
class Languages {
|
||||||
|
<<enum>>
|
||||||
|
Unknown,
|
||||||
|
French,
|
||||||
|
}
|
||||||
|
|
||||||
|
class Work {
|
||||||
|
+Id : string
|
||||||
|
+Description : string
|
||||||
|
+Title : string
|
||||||
|
+Subjects : List~string~
|
||||||
|
}
|
||||||
|
|
||||||
|
class Contributor {
|
||||||
|
+Name : string
|
||||||
|
+Role : string
|
||||||
|
}
|
||||||
|
|
||||||
|
class Author {
|
||||||
|
+Id : string
|
||||||
|
+Name : string
|
||||||
|
+ImageSmall : string
|
||||||
|
+ImageMedium : string
|
||||||
|
+ImageLarge : string
|
||||||
|
+Bio : string
|
||||||
|
+AlternateNames : List~string~
|
||||||
|
+BirthDate : DateTime?
|
||||||
|
+DeathDate : DateTime?
|
||||||
|
}
|
||||||
|
|
||||||
|
class Link {
|
||||||
|
+Title : string
|
||||||
|
+Url : string
|
||||||
|
}
|
||||||
|
|
||||||
|
class Ratings {
|
||||||
|
+Average : float
|
||||||
|
+Count : int
|
||||||
|
}
|
||||||
|
|
||||||
|
Book --> "1" Languages : Language
|
||||||
|
Book --> "*" Contributor : Contributors
|
||||||
|
Author --> "*" Link : Links
|
||||||
|
Work --> "*" Author : Authors
|
||||||
|
Work --> "1" Ratings : Ratings
|
||||||
|
Book --> "*" Author : Authors
|
||||||
|
Book --> "*" Work : Works
|
||||||
|
|
||||||
|
class Status {
|
||||||
|
<<enum>>
|
||||||
|
Unknown,
|
||||||
|
Finished,
|
||||||
|
Reading,
|
||||||
|
NotRead,
|
||||||
|
ToBeRead
|
||||||
|
}
|
||||||
|
|
||||||
|
class Contact{
|
||||||
|
+string Id;
|
||||||
|
+string FirstName;
|
||||||
|
+string LastName;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Services et Interfaces
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
classDiagram
|
||||||
|
direction LR
|
||||||
|
Book --> "1" Languages : Language
|
||||||
|
Book --> "*" Contributor : Contributors
|
||||||
|
Author --> "*" Link : Links
|
||||||
|
Work --> "1" Ratings : Ratings
|
||||||
|
Work --> "*" Author : Authors
|
||||||
|
Book --> "*" Work : Works
|
||||||
|
Book --> "*" Author : Authors
|
||||||
|
|
||||||
|
class IUserLibraryManager {
|
||||||
|
<<interface>>
|
||||||
|
+AddBook(Book book) : Task<Book>
|
||||||
|
+AddBook(string id) : Task<Book>
|
||||||
|
+AddBookByIsbn(string isbn) : Task<Book>
|
||||||
|
+RemoveBook(Book book) : Task<bool>
|
||||||
|
+RemoveBook(string id) : Task<bool>
|
||||||
|
+RemoveBook(string id) : Task<bool>
|
||||||
|
+AddToFavorites(Book book) : Task<bool>
|
||||||
|
+AddToFavorites(string bookId) : Task<bool>
|
||||||
|
+RemoveFromFavorites(Book book) : Task<bool>
|
||||||
|
+RemoveFromFavorites(string bookId) : Task<bool>
|
||||||
|
+UpdateBook(Book updatedBook) : Task<Book>
|
||||||
|
+AddContact(Contact contact) : Task<Contact>
|
||||||
|
+RemoveContact(Contact contact) : Task<bool>
|
||||||
|
+LendBook(Book book, Contact contact, DateTime? loanDate) : Task<bool>
|
||||||
|
+GetBackBook(Book book, DateTime? returnedDate) : Task<bool>
|
||||||
|
+BorrowBook(Book book, Contact owner, DateTime? borrowedDate) : Task<bool>
|
||||||
|
+GiveBackBook(Book book, DateTime? returnedDate) : Task<bool>
|
||||||
|
|
||||||
|
+GetCurrentLoans(int index, int count)
|
||||||
|
+GetPastLoans(int index, int count)
|
||||||
|
+GetCurrentBorrowings(int index, int count)
|
||||||
|
+GetPastBorrowings(int index, int count)
|
||||||
|
+GetContacts(int index, int count)
|
||||||
|
}
|
||||||
|
|
||||||
|
class ILibraryManager {
|
||||||
|
<<interface>>
|
||||||
|
+GetBookById(string id)
|
||||||
|
+GetBookByIsbn(string isbn)
|
||||||
|
+GetBooksByTitle(string title, int index, int count, string sort)
|
||||||
|
+GetBooksByAuthorId(string authorId, int index, int count, string sort)
|
||||||
|
+GetBooksByAuthor(string author, int index, int count, string sort)
|
||||||
|
+GetAuthorById(string id)
|
||||||
|
+GetAuthorsByName(string substring, int index, int count, string sort)
|
||||||
|
}
|
||||||
|
|
||||||
|
class Status {
|
||||||
|
<<enum>>
|
||||||
|
}
|
||||||
|
|
||||||
|
IUserLibraryManager ..|> ILibraryManager
|
||||||
|
IUserLibraryManager ..> Status
|
||||||
|
IUserLibraryManager ..> Contact
|
||||||
|
IUserLibraryManager ..> Book
|
||||||
|
ILibraryManager ..> Book
|
||||||
|
ILibraryManager ..> Author
|
||||||
|
```
|
||||||
|
|
||||||
|
*******
|
||||||
|
|
||||||
|
## Ressources
|
||||||
|
|
||||||
|
- Temps
|
||||||
|
- 4 Septembre au 22 Octobre 2023
|
||||||
|
- Matériel
|
||||||
|
- Ordinateurs portables sous Windows
|
||||||
|
- Émulateur sous Visual Studio 2022
|
||||||
|
- Téléphone portable
|
||||||
|
- Langages utilisés
|
||||||
|
- ![](https://img.shields.io/badge/.NETMAUI-5C2D91?style=for-the-badge&logo=.net&logoColor=white)
|
||||||
|
- ![](https://img.shields.io/badge/C%23-239120?style=for-the-badge&logo=c-sharp&logoColor=white)
|
||||||
|
- ![](https://img.shields.io/static/v1?style=for-the-badge&message=XAML&color=0C54C2&logo=XAML&logoColor=FFFFFF&label=)
|
||||||
|
- Personnes
|
||||||
|
- 1 étudiant en BUT Informatique
|
||||||
|
|
||||||
|
|
||||||
|
*******
|
||||||
|
|
||||||
|
<div id='auteurs'/>
|
||||||
|
|
||||||
|
## Auteur
|
||||||
|
|
||||||
|
Étudiant 3ème Annnée - BUT Informatique - IUT Clermont Auvergne - 2023-2024
|
||||||
|
`BRODA Lou`
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue