Compare commits

...

35 Commits

Author SHA1 Message Date
Louis DUFOUR 60fd3df3c4 Fix(master): README et léger fix
continuous-integration/drone/push Build is passing Details
2 years ago
Louis DUFOUR 1a90cf04af Fix(master): README et fix
continuous-integration/drone/push Build is passing Details
2 years ago
Louis DUFOUR 7153a3b557 Update(master): README
continuous-integration/drone/push Build is passing Details
2 years ago
Louis DUFOUR ff7178d266 Mise à jour de 'README.md'
continuous-integration/drone/push Build is passing Details
2 years ago
Louis DUFOUR 378abecbb1 Merge pull request 'Back-End' (#5) from Back-End into master
continuous-integration/drone/push Build is passing Details
2 years ago
Louis DUFOUR 94d10fb231 Add(Back-End): Filtrage up pour les auteurs
continuous-integration/drone/push Build is passing Details
2 years ago
Louis DUFOUR e76d6724de Add(Back-End): SearchBar
continuous-integration/drone/push Build is failing Details
2 years ago
Louis DUFOUR 2469160920 Add(Back-End): Suppresion d'un livre ok
continuous-integration/drone/push Build is failing Details
2 years ago
Louis DUFOUR d058835cd6 Update(Back-End): Passage du nom de la page
continuous-integration/drone/push Build is failing Details
2 years ago
Louis DUFOUR 82d7f54182 Update(Back-End): Converter Autors
continuous-integration/drone/push Build is failing Details
2 years ago
Louis DUFOUR c2d12ad647 Update(Back-End): Vu Switch button
continuous-integration/drone/push Build is failing Details
2 years ago
Louis DUFOUR deeaf1a596 Update(Back-End): Page detail fonctionne
continuous-integration/drone/push Build is failing Details
2 years ago
lodufour1 c597213c1c Update(Back-End): Suite
continuous-integration/drone/push Build is failing Details
2 years ago
lodufour1 2886bb8f2c Add(Back-End): mise en place de vm intermediaire
continuous-integration/drone/push Build is failing Details
2 years ago
Louis DUFOUR 9fc0d3a3e5 Update(Back-End): ReadMe
continuous-integration/drone/push Build is failing Details
2 years ago
Louis DUFOUR df28390026 Fix(Back-End): Oublier quelquechose
continuous-integration/drone/push Build is failing Details
2 years ago
Louis DUFOUR b6a6be1cd9 Update(Back-End): Navigation
continuous-integration/drone/push Build is failing Details
2 years ago
Louis DUFOUR e17371c514 Fix(Back-End): Navigation Menu Up
continuous-integration/drone/push Build is failing Details
2 years ago
lodufour1 58d1e5130a Update(Back-End): pas de manager mais encore pas stable sans
continuous-integration/drone/push Build is failing Details
2 years ago
lodufour1 5f17b504a7 Update(Back-End): Séparation des VMWrapper
continuous-integration/drone/push Build is failing Details
2 years ago
lodufour1 368ccab2cd Fix(Back-End): le manager marche
continuous-integration/drone/push Build is failing Details
2 years ago
lodufour1 998c29b0b3 Add (Back-End): on rajoute des vm de filtre et recherche
continuous-integration/drone/push Build is failing Details
2 years ago
Louis DUFOUR 9d7311917c Add (Back-End): Effect CollectionSelect
continuous-integration/drone/push Build is failing Details
2 years ago
Louis DUFOUR 080b2702f8 Add (Back-End): Navigation terminer
continuous-integration/drone/push Build is failing Details
2 years ago
Louis DUFOUR d87d16c481 Update (Back-end): Navigation établie, mais bancale
continuous-integration/drone/push Build is failing Details
2 years ago
Louis DUFOUR 25445b6f1b Update (Back-end): Ajout de VM
continuous-integration/drone/push Build is failing Details
2 years ago
Louis DUFOUR d4e4958c1b Update(Back-End): CSharpier par la
continuous-integration/drone/push Build is failing Details
2 years ago
lodufour1 f07ea2f058 Add (Back-End): Prototype archi
continuous-integration/drone/push Build is failing Details
2 years ago
Louis DUFOUR 1606a3a133 Update (Back-End): Mise à jour
continuous-integration/drone/push Build is failing Details
2 years ago
lodufour1 bf92f31134 Update (Back-End): début patron mvvm
continuous-integration/drone/push Build is failing Details
2 years ago
lodufour1 5d068b590e Add (Back-End): ajout du model et stub
continuous-integration/drone/push Build is failing Details
2 years ago
lodufour1 3ccbaff725 Refacto (master): change src en Sources
continuous-integration/drone/push Build is passing Details
2 years ago
lodufour1 d287fe4bbb Add(master): doc archi
continuous-integration/drone/push Build is passing Details
2 years ago
Louis DUFOUR 8567f7a722 Update (master): Fix selection pas beau
continuous-integration/drone/push Build is passing Details
2 years ago
Louis DUFOUR e564afd07b Merge pull request 'Front-End' (#2) from Front-End into master
continuous-integration/drone/push Build is passing Details
2 years ago

@ -15,13 +15,13 @@ steps:
commands:
- dotnet tool install -g CSharpier # Installez CSharpier si necessaire
- export PATH="$PATH:/root/.dotnet/tools" # Ajoutez le chemin des outils .NET Core au PATH
- cd src/
- cd Sources/
- dotnet-csharpier --check . # Verifie le formatage
- name: build
image: hub.codefirst.iut.uca.fr/marc.chevaldonne/codefirst-dotnet7-maui:latest
commandes:
- cd src/
- cd Sources/
- dotnet restore BookApp.sln
- dotnet build BookApp.sln -c Release --no-restore /p:AndroidSdkDirectory=$ANDROID_SDK_ROOT -property:Aapt2ToolPath=$ANDROID_SDK_ROOT/build-tools/33.0.0
- dotnet publish BookApp/BookApp.csproj -c Release --no-restore -o $CI_PROJECT_DIR/build/release -f:net7.0-android /p:AndroidSdkDirectory=/usr/lib/android-sdk
@ -29,7 +29,7 @@ steps:
- name: test
image: hub.codefirst.iut.uca.fr/marc.chevaldonne/codefirst-dotnet7-maui:latest
commands:
- cd src/
- cd Sources/
- dotnet restore BookApp.sln
- dotnet test BookApp.sln --no-restore /p:AndroidSdkDirectory=$ANDROID_SDK_ROOT -property:Aapt2ToolPath=$ANDROID_SDK_ROOT/build-tools/33.0.0
depends_on: [build]
@ -44,7 +44,7 @@ steps:
project_key: BookApp
coverage_exclusions: "Tests/**"
commands:
- cd src/
- cd Sources/
- dotnet restore BookApp.sln
- dotnet sonarscanner begin /k:$${project_key} /d:sonar.host.url=$${sonar_host} /d:sonar.coverageReportPaths="coveragereport/SonarQube.xml" /d:sonar.coverage.exclusions=$${coverage_exclusions} /d:sonar.login=$${sonar_token}
- dotnet build BookApp.sln -c Release --no-restore /p:AndroidSdkDirectory=$ANDROID_SDK_ROOT -property:Aapt2ToolPath=$ANDROID_SDK_ROOT/build-tools/33.0.0

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

@ -0,0 +1,40 @@
<mxfile host="app.diagrams.net" modified="2023-09-20T12:17:57.703Z" agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/115.0" etag="sVb7Rw98gNrLW8AO19HB" version="21.7.5" type="device">
<diagram name="Page-1" id="e78aO4FO6e_sPu6jAY4w">
<mxGraphModel dx="2261" dy="726" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
<root>
<mxCell id="0" />
<mxCell id="1" parent="0" />
<mxCell id="XgXC638uMGpcY1R6JfbD-9" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="XgXC638uMGpcY1R6JfbD-1" target="XgXC638uMGpcY1R6JfbD-3">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="XgXC638uMGpcY1R6JfbD-1" value="MAUI" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="220" y="370" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="XgXC638uMGpcY1R6JfbD-2" value="&lt;div align=&quot;left&quot;&gt;Contient:&lt;br&gt;- Pages/Vues&lt;/div&gt;&lt;div align=&quot;left&quot;&gt;- VM applicative&lt;br&gt;&lt;/div&gt;" style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=top;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
<mxGeometry x="220" y="440" width="250" height="100" as="geometry" />
</mxCell>
<mxCell id="XgXC638uMGpcY1R6JfbD-3" value="Model" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="-110" y="370" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="XgXC638uMGpcY1R6JfbD-12" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="XgXC638uMGpcY1R6JfbD-4" target="XgXC638uMGpcY1R6JfbD-3">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="XgXC638uMGpcY1R6JfbD-4" value="Stub" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="-110" y="160" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="XgXC638uMGpcY1R6JfbD-5" value="WebService" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="70" y="220" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="XgXC638uMGpcY1R6JfbD-11" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="XgXC638uMGpcY1R6JfbD-6" target="XgXC638uMGpcY1R6JfbD-3">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="XgXC638uMGpcY1R6JfbD-6" value="VMWrapper" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="-290" y="370" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="XgXC638uMGpcY1R6JfbD-7" value="&lt;div align=&quot;left&quot;&gt;Contient:&lt;br&gt;- Interface (pour récup les data)&lt;br&gt;&lt;/div&gt;" style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=top;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
<mxGeometry x="-120" y="440" width="250" height="100" as="geometry" />
</mxCell>
</root>
</mxGraphModel>
</diagram>
</mxfile>

@ -874,7 +874,7 @@ WARN_LOGFILE =
# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING
# Note: If this tag is empty the current directory is searched.
INPUT = ../../src
INPUT = ../../Sources
# This tag can be used to specify the character encoding of the source files
# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses

@ -1,29 +1,195 @@
# PocketBook
# PocketBook - Louis DUFOUR
# TP1 : Pages & Views
_à terminer pour le 17 septembre 2023 - 23h59_
## Informations projet
Application développer sous android API 28 pour ma part.
L'objectif est de reproduire les pages et les vues d'une application _PocketBook_ de recherche et de stockage de livres pour iPhone et Android en MAUI.
Une reproduction la plus _parfaite_ possible est souhaitée (avec la _TabBar_, le bouton _Modifier_, etc.).
Je vous conseille de faire (par ordre de priorité) :
- la page d'accueil de la bibliothèque ("Mes livres" avec les menus),
- la page affichant les livres,
- la page affichant les détails d'un livre,
- la page permettant de lister les auteurs et de filtrer les livres par auteur
- le menu contextuel permettant d'ajouter un nouveau livre
- une page permettant de prêter ou d'emprunter à livre à quelqu'un
- la page permettant de lister les années de publication et de filtrer les livres
- la page permettant de trier les livres par note.
## Critères d'évaluation
- L'app doit marcher sur iOS et Android
- Création des pages
- Utilisation de _Views_ (layout, affichage, buttons...)
- Création de _Views_ personnalisées
- Création et utilisation de Styles et ressources
- Création et utilisation des _Themes_ (light & dark)
- (si besoin) utilisation du MAUI Community Toolkit
### Documentation
Un schéma d'architecture est encore en cour de construction.
![Image clique droit](/Documentation/AnalyseSonar.PNG)
*Je n'ai pas pu, vous trouvez dans la liste d'ajouts des permissions voici un screenshot qui résume la qualité de mon code*
### Cas d'erreur connus
- Getsion du tabs qui s'adapte
#### Vu principale
- Button + *(TODO)*
- Button modifier *(TODO)*
#### Vu Tous
- Image par défaut *(TODO prévoire une image pardéfaut)*
- Button Tri *(TODO)*
- Button + *(TODO)*
#### Vu Detail
- Button:
- Déplacer Livre *(TODO)*
- Ajouter à la liste à lire plustard *(TODO)*
- Changer le status *(Marche sur le detail, mais se met pas à jour dans la groupCollection)*
- préter le livre *(TODO)*
#### Vu Emprunt/Emprunteur
- logic du switch button *(Début mis en place, mais pas compléter)*
- Button tri *(TODO)*
- Button + *(TODO)*
#### Vu Filtre
- Peut être mieux optimiser je pense
*ps: je sais pas pk sur mon tel lorsque l'appli est déployer la page ne veut même plus s'afficher. Par contre, lorsque je connecte mon téléphone avec un capable et je l'application via l'IDE cela marche parfaitement bien*
#### Vu Favoris
- pas faite si le passage du detail m'avais pas tant bloquer
### L'accès au code noté
- Projet ToolKitt
- Projet VMWrapper
- Projet BookApp Dossier ViewModel, UseCase, Composants, Pages
## 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 & 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
- [Doc officielle MAUI](https://learn.microsoft.com/en-us/dotnet/maui/)
@ -71,6 +237,11 @@ Lorsqu'on clique sur un le filtre "Date de publication" de la page "Mes Livres",
Un clic sur une de ces années permet d'aller sur la même page que celle qui affiche la liste des livres, mais seuls les livres publiée cette année apparaitront.
### Emprunts / Prêts
Lorsqu'on clique sur le menu "En prêt" sur la page d'accueil, on peut voir la liste de nos emprunts et de nos prêts répartis par contacts. Par exemple :
<img src="screens/emprunts.png" width="300"/>
Le switch permet de voir les livres qu'on a prêtés regroupés par contacts, ou les livres qu'on a empruntés regroupés par prêteurs.
### Le fameux bouton "+"
Un clic sur le bouton "+" fait apparaître un sous-menu permettant d'ajouter un livre à la bibliothèque :
- en scannant un code-barres (cf. plus bas)
@ -85,11 +256,3 @@ La page Scan pourra être réalisée plus tard.
<img src="screens/Scan.jpeg" width="300"/>
# Troubleshootings
#### J'ai bien renommé mes images, mais le Mac continue à me dire que non...
C'est peut-être dû au fait que certains fichiers cachés n'ont pas été correctement exclus (notamment les ```.DS_Store```).
Essayez d'appeler cette commande depuis un Terminal (sous Visual ou depuis... un Terminal) :
```
find . -name ".DS_Store" -delete
```

@ -0,0 +1,87 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.7.34024.191
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BookApp", "BookApp\BookApp.csproj", "{DBD6BB08-83E2-42EA-A28C-32DB6959E4B5}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DtoAbstractLayer", "DtoAbstractLayer\DtoAbstractLayer.csproj", "{C45DF3F7-AFCA-4252-89CC-1A6E5CA9EF33}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JsonReader", "JsonReader\JsonReader.csproj", "{F2A0B67A-2BA9-4447-9BFD-708D430EBCFA}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LibraryDTO", "LibraryDTO\LibraryDTO.csproj", "{94F9B003-9A66-424E-9758-77D140F041BA}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Model", "Model\Model.csproj", "{70ECEB25-24E4-47AA-BA64-0F0C8C4F090F}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "StubbedDTO", "StubbedDTO\StubbedDTO.csproj", "{B84474A1-D290-473B-AFF3-FA4ECB509024}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Utils", "Utils\Utils.csproj", "{03A3193F-92CC-4360-8061-E5207CC7FD2F}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stub", "Stub\Stub.csproj", "{14ED7ADF-7B83-432E-A87B-40C153041067}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tests", "Tests\Tests.csproj", "{945A6DB3-CB0A-4FB8-8117-64F0CB0D838A}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "VMWrapper", "VMWrapper\VMWrapper.csproj", "{377DC5AB-5D7C-4A29-ACED-C08B581A8E58}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ToolKit", "ToolKit\ToolKit.csproj", "{778541B9-BECF-49DC-8860-B8F134A6F4E2}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{DBD6BB08-83E2-42EA-A28C-32DB6959E4B5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DBD6BB08-83E2-42EA-A28C-32DB6959E4B5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DBD6BB08-83E2-42EA-A28C-32DB6959E4B5}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
{DBD6BB08-83E2-42EA-A28C-32DB6959E4B5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DBD6BB08-83E2-42EA-A28C-32DB6959E4B5}.Release|Any CPU.Build.0 = Release|Any CPU
{DBD6BB08-83E2-42EA-A28C-32DB6959E4B5}.Release|Any CPU.Deploy.0 = Release|Any CPU
{C45DF3F7-AFCA-4252-89CC-1A6E5CA9EF33}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C45DF3F7-AFCA-4252-89CC-1A6E5CA9EF33}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C45DF3F7-AFCA-4252-89CC-1A6E5CA9EF33}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C45DF3F7-AFCA-4252-89CC-1A6E5CA9EF33}.Release|Any CPU.Build.0 = Release|Any CPU
{F2A0B67A-2BA9-4447-9BFD-708D430EBCFA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F2A0B67A-2BA9-4447-9BFD-708D430EBCFA}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F2A0B67A-2BA9-4447-9BFD-708D430EBCFA}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F2A0B67A-2BA9-4447-9BFD-708D430EBCFA}.Release|Any CPU.Build.0 = Release|Any CPU
{94F9B003-9A66-424E-9758-77D140F041BA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{94F9B003-9A66-424E-9758-77D140F041BA}.Debug|Any CPU.Build.0 = Debug|Any CPU
{94F9B003-9A66-424E-9758-77D140F041BA}.Release|Any CPU.ActiveCfg = Release|Any CPU
{94F9B003-9A66-424E-9758-77D140F041BA}.Release|Any CPU.Build.0 = Release|Any CPU
{70ECEB25-24E4-47AA-BA64-0F0C8C4F090F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{70ECEB25-24E4-47AA-BA64-0F0C8C4F090F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{70ECEB25-24E4-47AA-BA64-0F0C8C4F090F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{70ECEB25-24E4-47AA-BA64-0F0C8C4F090F}.Release|Any CPU.Build.0 = Release|Any CPU
{B84474A1-D290-473B-AFF3-FA4ECB509024}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B84474A1-D290-473B-AFF3-FA4ECB509024}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B84474A1-D290-473B-AFF3-FA4ECB509024}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B84474A1-D290-473B-AFF3-FA4ECB509024}.Release|Any CPU.Build.0 = Release|Any CPU
{03A3193F-92CC-4360-8061-E5207CC7FD2F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{03A3193F-92CC-4360-8061-E5207CC7FD2F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{03A3193F-92CC-4360-8061-E5207CC7FD2F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{03A3193F-92CC-4360-8061-E5207CC7FD2F}.Release|Any CPU.Build.0 = Release|Any CPU
{14ED7ADF-7B83-432E-A87B-40C153041067}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{14ED7ADF-7B83-432E-A87B-40C153041067}.Debug|Any CPU.Build.0 = Debug|Any CPU
{14ED7ADF-7B83-432E-A87B-40C153041067}.Release|Any CPU.ActiveCfg = Release|Any CPU
{14ED7ADF-7B83-432E-A87B-40C153041067}.Release|Any CPU.Build.0 = Release|Any CPU
{945A6DB3-CB0A-4FB8-8117-64F0CB0D838A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{945A6DB3-CB0A-4FB8-8117-64F0CB0D838A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{945A6DB3-CB0A-4FB8-8117-64F0CB0D838A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{945A6DB3-CB0A-4FB8-8117-64F0CB0D838A}.Release|Any CPU.Build.0 = Release|Any CPU
{377DC5AB-5D7C-4A29-ACED-C08B581A8E58}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{377DC5AB-5D7C-4A29-ACED-C08B581A8E58}.Debug|Any CPU.Build.0 = Debug|Any CPU
{377DC5AB-5D7C-4A29-ACED-C08B581A8E58}.Release|Any CPU.ActiveCfg = Release|Any CPU
{377DC5AB-5D7C-4A29-ACED-C08B581A8E58}.Release|Any CPU.Build.0 = Release|Any CPU
{778541B9-BECF-49DC-8860-B8F134A6F4E2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{778541B9-BECF-49DC-8860-B8F134A6F4E2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{778541B9-BECF-49DC-8860-B8F134A6F4E2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{778541B9-BECF-49DC-8860-B8F134A6F4E2}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {27FCF0C7-3613-4FC6-9E95-2EEFB171F0F4}
EndGlobalSection
EndGlobal

@ -10,24 +10,21 @@
<TabBar >
<Tab Title="My Library"
Icon="books_vertical_fill.svg">
Icon="books_vertical_fill.svg">
<ShellContent ContentTemplate="{DataTemplate local:MainPage}" Route="Mainpage"/>
</Tab>
<Tab Title="My lists"
Icon="list_bullet.svg">
<ShellContent ContentTemplate="{DataTemplate pages:EmpruntsPrets}"/>
Icon="list_bullet.svg">
<ShellContent ContentTemplate="{DataTemplate pages:Tous}" Route="TousPage"/>
</Tab>
<Tab Title="My Readings"
Icon="bookmark_fill.svg">
<ShellContent ContentTemplate="{DataTemplate local:MainPage}" />
Icon="bookmark_fill.svg">
<ShellContent ContentTemplate="{DataTemplate pages:EmpruntsPrets}" Route="EmpruntsPretsPage"/>
</Tab>
<Tab Title="Search"
Icon="magnifyingglass.svg">
<ShellContent ContentTemplate="{DataTemplate local:MainPage}" />
Icon="magnifyingglass.svg">
<ShellContent ContentTemplate="{DataTemplate pages:Filtrage}" Route="FiltragePage"/>
</Tab>
</TabBar>
<ShellContent Route="FiltragePage" ContentTemplate="{DataTemplate pages:Filtrage}" />
<ShellContent Route="TousPage" ContentTemplate="{DataTemplate pages:Tous}" />
</Shell>

@ -10,7 +10,8 @@ namespace BookApp
Routing.RegisterRoute("FiltragePage", typeof(Filtrage));
Routing.RegisterRoute("TousPage", typeof(Tous));
Routing.RegisterRoute("Mainpage", typeof(MainPage));
Routing.RegisterRoute("EmpruntsPrets", typeof(EmpruntsPrets));
Routing.RegisterRoute("EmpruntsPretsPage", typeof(EmpruntsPrets));
Routing.RegisterRoute("DetailBookPage", typeof(DetailBook));
}
}
}

@ -67,9 +67,17 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="CommunityToolkit.Maui" Version="5.3.0" />
<PackageReference Include="CommunityToolkit.Maui" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="7.0.0" />
<PackageReference Include="SimpleRatingControl.MAUI" Version="0.1.0" />
<PackageReference Include="System.Linq" Version="4.3.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Model\Model.csproj" />
<ProjectReference Include="..\Stub\Stub.csproj" />
<ProjectReference Include="..\ToolKit\ToolKit.csproj" />
<ProjectReference Include="..\VMWrapper\VMWrapper.csproj" />
</ItemGroup>
<ItemGroup>
@ -79,6 +87,9 @@
<MauiXaml Update="Composants\GroupCollection.xaml">
<Generator>MSBuild:Compile</Generator>
</MauiXaml>
<MauiXaml Update="Composants\ToggleSwitchView.xaml">
<Generator>MSBuild:Compile</Generator>
</MauiXaml>
<MauiXaml Update="Pages\DetailBook.xaml">
<Generator>MSBuild:Compile</Generator>
</MauiXaml>

@ -2,10 +2,12 @@
<ContentView 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:vm="clr-namespace:BookApp.ViewModel"
xmlns:model="clr-namespace:Model;assembly=Model"
x:Class="BookApp.Composants.CollectionFiltrage">
<CollectionView ItemsSource="{Binding MyCollections1}">
<CollectionView ItemsSource="{Binding AuthorList}" x:Name="collectionView">
<CollectionView.ItemTemplate>
<DataTemplate>
<DataTemplate x:DataType="model:Author">
<StackLayout Padding="5">
<Grid RowDefinitions="auto" Margin="5,0,0,0">
<Grid.ColumnDefinitions>
@ -19,8 +21,8 @@
<toolkit:IconTintColorBehavior TintColor="Red" />
</Image.Behaviors>
</Image>
<Label Grid.Column="1" Margin="10,0,0,0" VerticalTextAlignment="Center" Text="{Binding AuteurName}"/>
<Label Grid.Column="2" VerticalTextAlignment="Center" Margin="0,0,40,0" HorizontalTextAlignment="End" Text="{Binding NbLivre}"/>
<Label Grid.Column="1" Margin="10,0,0,0" VerticalTextAlignment="Center" Text="{Binding Name}"/>
<Label Grid.Column="2" VerticalTextAlignment="Center" Margin="0,0,40,0" HorizontalTextAlignment="End" Text="{Binding Source={x:Reference collectionView}, Path=BindingContext.TotalBooks}"/>
<Button Grid.Column="2"
ImageSource="chevron_right.svg"
HeightRequest="35"

@ -0,0 +1,19 @@
using BookApp.ViewModel;
using VMWrapper;
namespace BookApp.Composants
{
public partial class CollectionFiltrage : ContentView
{
public CollectionFiltrage()
{
InitializeComponent();
}
public CollectionFiltrage(FilterViewModel data)
: this()
{
BindingContext = data;
}
}
}

@ -0,0 +1,84 @@
<?xml version="1.0" encoding="utf-8" ?>
<ContentView xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:composants="clr-namespace:BookApp.Composants"
xmlns:model="clr-namespace:Model;assembly=Model"
xmlns:usecase="clr-namespace:BookApp.UseCase"
x:Name="ThisPage"
x:Class="BookApp.Composants.GroupCollection">
<ContentView.Resources>
<ResourceDictionary>
<usecase:AuthorsListToStringConverter x:Key="authorsConverter"/>
</ResourceDictionary>
</ContentView.Resources>
<CollectionView ItemsSource="{Binding AuteurGroups}" IsGrouped="True" SelectionMode="Single" x:Name="groupCollectionView">
<CollectionView.GroupHeaderTemplate>
<DataTemplate x:DataType="model:Author">
<Label Text="{Binding Name}"
FontFamily="SF-Compact-Display-Semibold"
BackgroundColor="LightGrey"
TextColor="Gray"
Padding="5"/>
</DataTemplate>
</CollectionView.GroupHeaderTemplate>
<CollectionView.ItemTemplate>
<DataTemplate x:DataType="model:Book">
<SwipeView Style="{StaticResource StyleCollectionStack}">
<SwipeView.LeftItems>
<SwipeItems>
<SwipeItem Text="Favorite"
IconImageSource="favorite.png"
BackgroundColor="LightGreen"/>
<SwipeItem Text="Delete"
IconImageSource="delete.png"
BackgroundColor="LightPink"
Command="{Binding Source={x:Reference groupCollectionView}, Path=BindingContext.RemoveBookCommand}"
CommandParameter="{Binding Id}"/>
</SwipeItems>
</SwipeView.LeftItems>
<StackLayout>
<Grid>
<Grid.GestureRecognizers>
<TapGestureRecognizer Command="{Binding Source={x:Reference ThisPage}, Path=Nav.BookDetailCommand}"
CommandParameter="{Binding Id}"/>
</Grid.GestureRecognizers>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Image Grid.Column="0"
Source="{Binding ImageLarge}"
HeightRequest="125"
WidthRequest="125"
Margin="0,10,0,10"/>
<StackLayout Grid.Column="1">
<Label Text="{Binding Title}"
FontFamily="SF-Compact-Display-Bold"
FontSize="18"
TextColor="Black"/>
<Label Text="{Binding Authors, Converter={StaticResource authorsConverter}}" FontFamily="SF-Compact-Display-Semibold" TextColor="Black"/>
<Label
TextColor="SlateGray"
Text="{Binding Status}"/>
<StackLayout Margin="0,10" Orientation="Horizontal" VerticalOptions="EndAndExpand">
<Image Source="empty_star.svg" WidthRequest="25" HeightRequest="25"/>
<Image Source="empty_star.svg" WidthRequest="25" HeightRequest="25"/>
<Image Source="empty_star.svg" WidthRequest="25" HeightRequest="25"/>
<Image Source="empty_star.svg" WidthRequest="25" HeightRequest="25"/>
<Image Source="empty_star.svg" WidthRequest="25" HeightRequest="25"/>
</StackLayout>
</StackLayout>
</Grid>
<Rectangle Margin="25,0,0,10" HeightRequest="1" BackgroundColor="LightGray" VerticalOptions="End" />
</StackLayout>
</SwipeView>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</ContentView>

@ -0,0 +1,21 @@
using BookApp.ViewModel;
using VMWrapper;
namespace BookApp.Composants
{
public partial class GroupCollection : ContentView
{
public ViewModelNavigation Nav { get; } = new ViewModelNavigation();
public GroupCollection()
{
InitializeComponent();
}
public GroupCollection(BooksViewModel data)
: this()
{
BindingContext = data;
}
}
}

@ -0,0 +1,48 @@
<?xml version="1.0" encoding="utf-8" ?>
<ContentView xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="BookApp.Composants.ToggleSwitchView">
<Grid
VerticalOptions="FillAndExpand"
HorizontalOptions="FillAndExpand"
Padding="10">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<StackLayout
Orientation="Horizontal"
HorizontalOptions="Center"
VerticalOptions="Center"
Grid.Row="0"
Spacing="30">
<Label
x:Name="OffLabel"
Text="Prêts"
Opacity="0.25"
VerticalTextAlignment="Center"/>
<Grid
VerticalOptions="Center"
HorizontalOptions="Center"
Scale="1.5">
<Switch
x:Name="ToggleSwitch"
Toggled="OnToggled" />
</Grid>
<Label
x:Name="OnLabel"
Text="Emprunts"
Opacity="0.25"
VerticalTextAlignment="Center"/>
</StackLayout>
<!-- Autres éléments de l'interface utilisateur si nécessaire -->
</Grid>
</ContentView>

@ -0,0 +1,24 @@
namespace BookApp.Composants;
public partial class ToggleSwitchView : ContentView
{
public ToggleSwitchView()
{
InitializeComponent();
}
// Gestionnaire d'<27>v<EFBFBD>nements pour le changement d'<27>tat du switch
private void OnToggled(object sender, ToggledEventArgs e)
{
if (e.Value) // Si c'est ON
{
OnLabel.Opacity = 1;
OffLabel.Opacity = 0.25;
}
else // Si c'est OFF
{
OnLabel.Opacity = 0.25;
OffLabel.Opacity = 1;
}
}
}

@ -2,7 +2,9 @@
<ContentPage
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:vm="clr-namespace:BookApp.ViewModel"
xmlns:toolkit="http://schemas.microsoft.com/dotnet/2022/maui/toolkit"
x:Name="ThisPage"
x:Class="BookApp.MainPage">
<Shell.TitleView>
<Grid RowDefinitions="Auto">
@ -40,106 +42,112 @@
<StackLayout>
<Label FontSize="35" FontFamily="SF-Pro-Display-Bold" Padding="10">Mes livres</Label>
<Rectangle HeightRequest="1" BackgroundColor="black" VerticalOptions="End" />
<CollectionView ItemsSource="{Binding MyCollections1}" Margin="25,0,0,0" BackgroundColor="#F9F9F9">
<CollectionView.ItemTemplate>
<DataTemplate>
<Grid RowDefinitions="Auto" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="25"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Image Grid.Column="0"
Source="{Binding Icone}"
HeightRequest="25"
WidthRequest="25"/>
<Label FontFamily="SF-Compact-Display-Semibold" Grid.Column="1"
Text="{Binding Name}"
FontAttributes="Bold"
Padding="5"
VerticalOptions="Center"/>
<Grid Grid.Column="2">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Label Grid.Column="2"
Text="{Binding Number}"
FontAttributes="Bold"
VerticalOptions="Center"
Margin="0,0,40,0"
HorizontalOptions="End"/>
<Button Grid.Column="2"
ImageSource="chevron_right.svg"
HeightRequest="35"
WidthRequest="35"
BackgroundColor="#F9F9F9"
Clicked="ButtonTous"
HorizontalOptions="End"/>
</Grid>
<Rectangle Grid.ColumnSpan="4" HeightRequest="1" BackgroundColor="LightGray" VerticalOptions="End">
<Rectangle.Triggers>
<DataTrigger TargetType="Rectangle" Binding="{Binding IsLastItem}" Value="true">
<Setter Property="IsVisible" Value="False"/>
</DataTrigger>
</Rectangle.Triggers>
</Rectangle>
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
<CollectionView ItemsSource="{Binding MenuItemsLivre}" Margin="25,0,0,0" BackgroundColor="#F9F9F9">
<CollectionView.ItemTemplate>
<DataTemplate x:DataType="vm:ViewModelMenuItem">
<Grid RowDefinitions="Auto" Style="{StaticResource StyleCollectionGrid}" Padding="2">
<Grid.GestureRecognizers>
<TapGestureRecognizer Command="{Binding Source={x:Reference ThisPage}, Path=Nav.MenuItemsCommand}"
CommandParameter="{Binding .}" NumberOfTapsRequired="1"/>
</Grid.GestureRecognizers>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="25"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Image Grid.Column="0"
Source="{Binding Icone}"
HeightRequest="25"
WidthRequest="25"/>
<Label FontFamily="SF-Compact-Display-Semibold" Grid.Column="1"
Text="{Binding Name}"
FontAttributes="Bold"
Padding="5"
VerticalOptions="Center"/>
<Grid Grid.Column="2">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Label Grid.Column="2"
Text="{Binding Number}"
FontAttributes="Bold"
VerticalOptions="Center"
Margin="0,0,40,0"
HorizontalOptions="End"/>
<Image Grid.Column="2"
Source="chevron_right.svg"
HeightRequest="25"
WidthRequest="25"
HorizontalOptions="End"/>
</Grid>
<Rectangle Grid.ColumnSpan="4" HeightRequest="1" BackgroundColor="LightGray" VerticalOptions="End">
<Rectangle.Triggers>
<DataTrigger TargetType="Rectangle" Binding="{Binding IsLastItem}" Value="true">
<Setter Property="IsVisible" Value="False"/>
</DataTrigger>
</Rectangle.Triggers>
</Rectangle>
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
<Rectangle HeightRequest="1" BackgroundColor="black" VerticalOptions="End"/>
<Label FontFamily="SF-Pro-Display-Heavy" FontSize="20" Padding="10">Filtres</Label>
<Rectangle HeightRequest="1" BackgroundColor="black" VerticalOptions="End"/>
<CollectionView ItemsSource="{Binding MyCollections2}" Margin="25,0,0,0" BackgroundColor="#F9F9F9">
<CollectionView.ItemTemplate>
<DataTemplate>
<Grid RowDefinitions="Auto" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="25" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Image Grid.Column="0"
Source="{Binding Icone}"
HeightRequest="25"
WidthRequest="25"/>
<Label FontFamily="SF-Compact-Display-Semibold" Grid.Column="1"
Text="{Binding Name}"
FontAttributes="Bold"
Padding="5"
VerticalOptions="Center"/>
<Grid Grid.Column="2" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Label FontFamily="SF-Compact-Display-Semibold" Grid.Column="2"
Text="{Binding Number}"
FontAttributes="Bold"
VerticalOptions="Center"
Margin="0,0,40,0"
HorizontalOptions="End"/>
<Button Grid.Column="2"
ImageSource="chevron_right.svg"
HeightRequest="35"
WidthRequest="35"
BackgroundColor="#F9F9F9"
Clicked="ButtonAuteur"
HorizontalOptions="End"/>
</Grid>
<Rectangle Grid.ColumnSpan="4" HeightRequest="1" BackgroundColor="LightGray" VerticalOptions="End">
<Rectangle.Triggers>
<DataTrigger TargetType="Rectangle" Binding="{Binding IsLastItem}" Value="true">
<Setter Property="IsVisible" Value="False"/>
</DataTrigger>
</Rectangle.Triggers>
</Rectangle>
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
<CollectionView ItemsSource="{Binding MenuItemsFiltre}" Margin="25,0,0,0" BackgroundColor="#F9F9F9">
<CollectionView.ItemTemplate>
<DataTemplate x:DataType="vm:ViewModelMenuItem">
<Grid RowDefinitions="Auto" Style="{StaticResource StyleCollectionGrid}" Padding="2">
<Grid.GestureRecognizers>
<TapGestureRecognizer Command="{Binding Source={x:Reference ThisPage}, Path=Nav.MenuItemsFiltreCommand}"
CommandParameter="{Binding .}" NumberOfTapsRequired="1"/>
</Grid.GestureRecognizers>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="25" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Image Grid.Column="0"
Source="{Binding Icone}"
HeightRequest="25"
WidthRequest="25"/>
<Label FontFamily="SF-Compact-Display-Semibold" Grid.Column="1"
Text="{Binding Name}"
FontAttributes="Bold"
Padding="5"
VerticalOptions="Center"/>
<Grid Grid.Column="2" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Label FontFamily="SF-Compact-Display-Semibold" Grid.Column="2"
Text="{Binding Number}"
FontAttributes="Bold"
VerticalOptions="Center"
Margin="0,0,40,0"
HorizontalOptions="End"/>
<Image Grid.Column="2"
Source="chevron_right.svg"
HeightRequest="25"
WidthRequest="25"
HorizontalOptions="End"/>
</Grid>
<Rectangle Grid.ColumnSpan="4" HeightRequest="1" BackgroundColor="LightGray" VerticalOptions="End">
<Rectangle.Triggers>
<DataTrigger TargetType="Rectangle" Binding="{Binding IsLastItem}" Value="true">
<Setter Property="IsVisible" Value="False"/>
</DataTrigger>
</Rectangle.Triggers>
</Rectangle>
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</StackLayout>
</ContentPage>

@ -0,0 +1,18 @@
using BookApp.Pages;
using System.Collections.ObjectModel;
using BookApp.ViewModel;
using System.Diagnostics;
namespace BookApp
{
public partial class MainPage : ContentPage
{
public ViewModelNavigation Nav { get; } = new ViewModelNavigation();
public MainPage(ViewModelMenu data)
{
InitializeComponent();
BindingContext = data;
}
}
}

@ -0,0 +1,52 @@
using BookApp.Composants;
using BookApp.Pages;
using BookApp.ViewModel;
using CommunityToolkit.Maui;
using Microsoft.Extensions.Logging;
using Model;
using SimpleRatingControlMaui;
using StubLib;
using VMWrapper;
namespace BookApp
{
public static class MauiProgram
{
public static MauiApp CreateMauiApp()
{
var builder = MauiApp.CreateBuilder();
builder
.UseMauiApp<App>()
.UseMauiCommunityToolkit()
.UseSimpleRatingControl()
.ConfigureFonts(fonts =>
{
fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
});
#if DEBUG
builder.Logging.AddDebug();
#endif
builder.Services.AddSingleton<ILibraryManager, LibraryStub>();
builder.Services.AddSingleton<IUserLibraryManager, UserLibraryStub>();
builder.Services.AddSingleton<BooksViewModel>();
builder.Services.AddSingleton<FilterViewModel>();
builder.Services.AddSingleton<DetailBookViewModel>();
builder.Services.AddSingleton<ViewModelDetailProvider>();
builder.Services.AddSingleton<ViewModelNavigation>();
builder.Services.AddSingleton<ViewModelMenu>();
builder.Services.AddSingleton<DetailBook>();
builder.Services.AddSingleton<GroupCollection>();
builder.Services.AddSingleton<CollectionFiltrage>();
builder.Services.AddSingleton<Filtrage>();
builder.Services.AddSingleton<Tous>();
builder.Services.AddSingleton<MainPage>();
builder.Services.AddSingleton<EmpruntsPrets>();
return builder.Build();
}
}
}

@ -3,7 +3,11 @@
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:vm="clr-namespace:BookApp.ViewModel"
xmlns:usecase="clr-namespace:BookApp.UseCase"
x:Name="ThisPage"
x:Class="BookApp.Pages.DetailBook">
<Shell.BackButtonBehavior>
<BackButtonBehavior IsVisible="False" IsEnabled="False"/>
</Shell.BackButtonBehavior>
@ -18,7 +22,8 @@
Source="Chevron_left.svg"
HorizontalOptions="Start">
<Image.GestureRecognizers>
<TapGestureRecognizer Tapped="BackButton" NumberOfTapsRequired="1"/>
<TapGestureRecognizer
Command="{Binding Source={x:Reference ThisPage}, Path=Nav.BackButtonCommand}" NumberOfTapsRequired="1"/>
</Image.GestureRecognizers>
<Image.Behaviors>
<toolkit:IconTintColorBehavior TintColor="Red" />
@ -45,6 +50,13 @@
Grid.Column="1" />
</Grid>
</Shell.TitleView>
<ContentPage.Resources>
<ResourceDictionary>
<usecase:AuthorsListToStringConverter x:Key="authorsConverter"/>
</ResourceDictionary>
</ContentPage.Resources>
<ContentPage.Content>
<ScrollView>
<StackLayout>
@ -54,9 +66,9 @@
<ColumnDefinition Width="125"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Image Margin="10,10,10,0" Grid.Column="0" Source="{Binding BookDetail.ImageBook}"/>
<Image Margin="10,10,10,0" Grid.Column="0" Source="{Binding BookDetail.ImageLarge}"/>
<StackLayout Grid.Column="1">
<Label FontAttributes="Bold" FontSize="20" Text="{Binding BookDetail.Name}"/>
<Label FontAttributes="Bold" FontSize="20" Text="{Binding BookDetail.Title }"/>
<Grid RowDefinitions="auto" VerticalOptions="EndAndExpand">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
@ -81,13 +93,13 @@
</Grid>
<Rectangle Margin="25,0,0,10" HeightRequest="1" BackgroundColor="LightGray" VerticalOptions="End"/>
<Label FontAttributes="Bold" Margin="25,0,0,0" VerticalTextAlignment="Center" Text="Auteur"/>
<Label Margin="25,0,0,0" VerticalTextAlignment="Center" Text="{Binding BookDetail.Auteur.Name}"/>
<Label Margin="25,0,0,0" VerticalTextAlignment="Center" Text="{Binding BookDetail.Authors, Converter={StaticResource authorsConverter}}"/>
<Rectangle Margin="25,10,0,10" HeightRequest="1" BackgroundColor="LightGray" VerticalOptions="End"/>
<Label FontAttributes="Bold" Margin="25,0,0,0" VerticalTextAlignment="Center" Text="Maison d'édition"/>
<Label Margin="25,0,0,0" VerticalTextAlignment="Center" Text="{Binding BookDetail.MaisonEdit}"/>
<Label Margin="25,0,0,0" VerticalTextAlignment="Center" Text="{Binding BookDetail.Authors}"/>
<Rectangle Margin="25,10,0,10" HeightRequest="1" BackgroundColor="LightGray" VerticalOptions="End"/>
<Label FontAttributes="Bold" Margin="25,0,0,0" VerticalTextAlignment="Center" Text="Résumer"/>
<Label Margin="25,0,0,0" VerticalTextAlignment="Center" Text="Le Lorem Ipsum est simplement du faux texte employé dans la composition et la mise en page avant impression. Le Lorem Ipsum est le faux texte standard de l'imprimerie depuis les années 1500, quand un imprimeur anonyme assembla ensemble des morceaux de texte pour réaliser un livre spécimen de polices de texte. Il n'a pas fait que survivre cinq siècles, mais s'est aussi adapté à la bureautique informatique, sans que son contenu n'en soit modifié. Il a été popularisé dans les années 1960 grâce à la vente de feuilles Letraset contenant des passages du Lorem Ipsum, et, plus récemment, par son inclusion dans des applications de mise en page de texte, comme Aldus PageMaker."/>
<Label Margin="25,0,0,0" VerticalTextAlignment="Center" Text="{Binding BookDetail.Format}"/>
<Rectangle Margin="25,10,0,10" HeightRequest="1" BackgroundColor="LightGray" VerticalOptions="End" />
<Label FontAttributes="Bold" Margin="25,0,0,0" VerticalTextAlignment="Center" Text="Details"/>
<Grid Margin="25,0,20,0">
@ -101,11 +113,11 @@
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Label Grid.Row="0" Grid.Column="0" Text="Nombre de pages"/>
<Label Grid.Row="0" Grid.Column="1" HorizontalTextAlignment="End" Text="{Binding BookDetail.NbPage}"/>
<Label Grid.Row="0" Grid.Column="1" HorizontalTextAlignment="End" Text="{Binding BookDetail.NbPages}"/>
<Label Grid.Row="1" Grid.Column="0" Text="Langue"/>
<Label Grid.Row="1" Grid.Column="1" HorizontalTextAlignment="End" Text="{Binding BookDetail.Langue}"/>
<Label Grid.Row="1" Grid.Column="1" HorizontalTextAlignment="End" Text="{Binding BookDetail.Language}"/>
<Label Grid.Row="2" Grid.Column="0" Text="ISBN"/>
<Label Grid.Row="2" Grid.Column="1" HorizontalTextAlignment="End" Text="{Binding BookDetail.ISBN}"/>
<Label Grid.Row="2" Grid.Column="1" HorizontalTextAlignment="End" Text="{Binding BookDetail.Status}"/>
</Grid>
<Rectangle Margin="25,10,0,10" HeightRequest="1" BackgroundColor="LightGray" VerticalOptions="End" />
<Label FontAttributes="Bold" Margin="25,0,0,0" VerticalTextAlignment="Center" Text="Status de lecture"/>
@ -115,7 +127,7 @@
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Label Grid.Column="0" Text="Status"/>
<Label Grid.Column="1" HorizontalTextAlignment="End" Text="{Binding BookDetail.Statut}"/>
<Label Grid.Column="1" HorizontalTextAlignment="End" Text="{Binding BookDetail.Status}"/>
</Grid>
<Rectangle Margin="25,10,0,10" HeightRequest="1" BackgroundColor="LightGray" VerticalOptions="End" />
<Label FontAttributes="Bold" Margin="25,0,0,0" VerticalTextAlignment="Center" Text="biliothèque"/>
@ -125,7 +137,7 @@
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Label Grid.Column="0" Text="Ajouter le"/>
<Label Grid.Column="1" HorizontalTextAlignment="End" Text="{Binding BookDetail.dateAjout}"/>
<Label Grid.Column="1" HorizontalTextAlignment="End" Text="{Binding BookDetail.PublishDate}"/>
</Grid>
<Rectangle Margin="25,10,0,10" HeightRequest="1" BackgroundColor="LightGray" VerticalOptions="End" />
<Rectangle HeightRequest="100" Fill="Transparent"/>
@ -163,6 +175,9 @@
<ColumnDefinition Width="25"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.GestureRecognizers>
<TapGestureRecognizer Command="{Binding PopUpCommand}" NumberOfTapsRequired="1"/>
</Grid.GestureRecognizers>
<Image Grid.Column="0" HeightRequest="25"
WidthRequest="25" Source="eyeglasses.svg">
<Image.Behaviors>

@ -0,0 +1,16 @@
using BookApp.ViewModel;
using System.Diagnostics;
namespace BookApp.Pages
{
public partial class DetailBook : ContentPage
{
public ViewModelNavigation Nav { get; } = new ViewModelNavigation();
public DetailBook(ViewModelDetailProvider VMProvider)
{
InitializeComponent();
BindingContext = VMProvider;
}
}
}

@ -1,9 +1,10 @@
<?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"
x:Class="BookApp.Pages.EmpruntsPrets"
xmlns:toolkit="http://schemas.microsoft.com/dotnet/2022/maui/toolkit"
Title="EmpruntsPrets">
xmlns:composants="clr-namespace:BookApp.Composants"
x:Name="ThisPage"
x:Class="BookApp.Pages.EmpruntsPrets">
<Shell.BackButtonBehavior>
<BackButtonBehavior IsVisible="False" IsEnabled="False"/>
</Shell.BackButtonBehavior>
@ -19,7 +20,8 @@
Source="Chevron_left.svg"
HorizontalOptions="Start">
<Image.GestureRecognizers>
<TapGestureRecognizer Tapped="BackButton" NumberOfTapsRequired="1"/>
<TapGestureRecognizer
Command="{Binding Source={x:Reference ThisPage}, Path=Nav.BackButtonCommand}" NumberOfTapsRequired="1"/>
</Image.GestureRecognizers>
<Image.Behaviors>
<toolkit:IconTintColorBehavior TintColor="Red" />
@ -68,33 +70,17 @@
</HorizontalStackLayout>
</Grid>
</Shell.TitleView>
<StackLayout>
<ContentView>
<ContentView.GestureRecognizers>
<TapGestureRecognizer Command="{Binding TapCommand}" NumberOfTapsRequired="1" />
</ContentView.GestureRecognizers>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Rectangle HeightRequest="1" BackgroundColor="LightGray" VerticalOptions="Start" />
<composants:ToggleSwitchView Grid.Row="0" VerticalOptions="Center" HorizontalOptions="Center"/>
<Rectangle HeightRequest="1" BackgroundColor="LightGray" VerticalOptions="End" />
<Grid WidthRequest="150" HeightRequest="50"
BackgroundColor="LightGray"
VerticalOptions="Center"
HorizontalOptions="Center">
<!-- Le Switch -->
<Switch x:Name="MySwitch" IsToggled="{Binding IsToggled}"
HorizontalOptions="Start"
VerticalOptions="Center"/>
<!-- Le Texte -->
<Label Text="Mon Switch"
VerticalOptions="Center"
HorizontalOptions="Center"
FontSize="16"
TextColor="Black" />
</Grid>
</ContentView>
<!-- TODO with collection group on personn -->
</StackLayout>
<ScrollView Grid.Row="1">
<composants:GroupCollection/>
</ScrollView>
</Grid>
</ContentPage>

@ -0,0 +1,17 @@
using BookApp.ViewModel;
using System.Windows.Input;
using VMWrapper;
namespace BookApp.Pages
{
public partial class EmpruntsPrets : ContentPage
{
public ViewModelNavigation Nav { get; } = new ViewModelNavigation();
public EmpruntsPrets(BooksViewModel data)
{
InitializeComponent();
BindingContext = data;
}
}
}

@ -4,6 +4,7 @@
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:toolkit="http://schemas.microsoft.com/dotnet/2022/maui/toolkit"
xmlns:composants="clr-namespace:BookApp.Composants"
x:Name="ThisPage"
x:Class="BookApp.Pages.Filtrage">
<Shell.BackButtonBehavior>
<BackButtonBehavior IsVisible="False" IsEnabled="False"/>
@ -20,25 +21,17 @@
Source="Chevron_left.svg"
HorizontalOptions="Start">
<Image.GestureRecognizers>
<TapGestureRecognizer Tapped="BackButton" NumberOfTapsRequired="1"/>
<TapGestureRecognizer
Command="{Binding Source={x:Reference ThisPage}, Path=Nav.BackButtonCommand}" NumberOfTapsRequired="1"/>
</Image.GestureRecognizers>
<Image.Behaviors>
<toolkit:IconTintColorBehavior TintColor="Red" />
</Image.Behaviors>
</Image>
<Label
Text="Auteur"
FontFamily="Strande2"
TextColor="Red"
FontSize="Medium"
VerticalTextAlignment="Center"
HorizontalOptions="Start"
Grid.Column="0" />
</HorizontalStackLayout>
<Label
Text="Tous"
Text="{Binding Source={x:Reference ThisPage}, Path=Title}"
FontFamily="Strande2"
TextColor="Black"
FontSize="Medium"
@ -52,6 +45,12 @@
HorizontalOptions="End"
Margin="0,0,10,0"
Grid.Column="2">
<Image.GestureRecognizers>
<TapGestureRecognizer
Command="{Binding SortCommand }"
CommandParameter="name"
NumberOfTapsRequired="1"/>
</Image.GestureRecognizers>
<Image.Behaviors>
<toolkit:IconTintColorBehavior TintColor="Red" />
</Image.Behaviors>
@ -62,9 +61,11 @@
<ContentPage.Content>
<StackLayout>
<Rectangle HeightRequest="1" BackgroundColor="LightGray"/>
<SearchBar Placeholder="Search items..."/>
<Rectangle HeightRequest="1" BackgroundColor="LightGray"/>
<composants:CollectionFiltrage VerticalOptions="FillAndExpand"/>
<SearchBar Placeholder="Rechercher des auteurs..."
Text="{Binding SearchQuery, Mode=TwoWay}"
SearchCommand="{Binding SearchCommand}"
SearchCommandParameter="{Binding Text, Source={x:Reference Name=SearchBar}}"/>
<composants:CollectionFiltrage/>
</StackLayout>
</ContentPage.Content>
</ContentPage>

@ -0,0 +1,20 @@
using BookApp.ViewModel;
using System.Diagnostics;
using VMWrapper;
namespace BookApp.Pages
{
[QueryProperty(nameof(Title), "Title")]
public partial class Filtrage : ContentPage
{
private readonly string Title;
public ViewModelNavigation Nav { get; } = new ViewModelNavigation();
public Filtrage(FilterViewModel data)
{
InitializeComponent();
BindingContext = data;
}
}
}

@ -2,8 +2,9 @@
<ContentPage
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:composants="clr-namespace:BookApp.Composants"
xmlns:toolkit="http://schemas.microsoft.com/dotnet/2022/maui/toolkit"
xmlns:composants="clr-namespace:BookApp.Composants"
x:Name="ThisPage"
x:Class="BookApp.Pages.Tous">
<Shell.BackButtonBehavior>
<BackButtonBehavior IsVisible="False" IsEnabled="False"/>
@ -20,7 +21,8 @@
Source="Chevron_left.svg"
HorizontalOptions="Start">
<Image.GestureRecognizers>
<TapGestureRecognizer Tapped="BackButton" NumberOfTapsRequired="1"/>
<TapGestureRecognizer
Command="{Binding Source={x:Reference ThisPage}, Path=Nav.BackButtonCommand}" NumberOfTapsRequired="1"/>
</Image.GestureRecognizers>
<Image.Behaviors>
<toolkit:IconTintColorBehavior TintColor="Red" />

@ -0,0 +1,18 @@
using BookApp.ViewModel;
using System.Collections.ObjectModel;
using System.Diagnostics;
using VMWrapper;
namespace BookApp.Pages
{
public partial class Tous : ContentPage
{
public ViewModelNavigation Nav { get; } = new ViewModelNavigation();
public Tous(BooksViewModel data)
{
InitializeComponent();
BindingContext = data;
}
}
}

Before

Width:  |  Height:  |  Size: 228 B

After

Width:  |  Height:  |  Size: 228 B

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

Before

Width:  |  Height:  |  Size: 785 B

After

Width:  |  Height:  |  Size: 785 B

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Before

Width:  |  Height:  |  Size: 703 B

After

Width:  |  Height:  |  Size: 703 B

Before

Width:  |  Height:  |  Size: 3.8 KiB

After

Width:  |  Height:  |  Size: 3.8 KiB

Before

Width:  |  Height:  |  Size: 465 B

After

Width:  |  Height:  |  Size: 465 B

Before

Width:  |  Height:  |  Size: 560 B

After

Width:  |  Height:  |  Size: 560 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Before

Width:  |  Height:  |  Size: 343 B

After

Width:  |  Height:  |  Size: 343 B

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Before

Width:  |  Height:  |  Size: 179 B

After

Width:  |  Height:  |  Size: 179 B

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

Before

Width:  |  Height:  |  Size: 714 B

After

Width:  |  Height:  |  Size: 714 B

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Before

Width:  |  Height:  |  Size: 761 B

After

Width:  |  Height:  |  Size: 761 B

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

Before

Width:  |  Height:  |  Size: 564 B

After

Width:  |  Height:  |  Size: 564 B

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

Before

Width:  |  Height:  |  Size: 921 B

After

Width:  |  Height:  |  Size: 921 B

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

@ -4,11 +4,9 @@
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml">
<Color x:Key="BackGroundApp">#F9F9F9</Color>
<Color x:Key="Primary">red</Color>
<Color x:Key="Primary">#FB0A10</Color>
<Color x:Key="Secondary">#DFD8F7</Color>
<Color x:Key="Tertiary">#2B0B98</Color>
<Color x:Key="White">White</Color>
@ -18,6 +16,7 @@
<Color x:Key="Gray300">#ACACAC</Color>
<Color x:Key="Gray400">#919191</Color>
<Color x:Key="Gray500">#6E6E6E</Color>
<Color x:Key="Gray550">#595959</Color>
<Color x:Key="Gray600">#404040</Color>
<Color x:Key="Gray900">#212121</Color>
<Color x:Key="Gray950">#141414</Color>
@ -45,4 +44,43 @@
<Color x:Key="Blue200Accent">#72ACF1</Color>
<Color x:Key="Blue300Accent">#A7CBF6</Color>
</ResourceDictionary>
<Color x:Key="DividerLight">#E1E1E1</Color>
<Color x:Key="DividerDark">#3D3C41</Color>
<Color x:Key="StarOnLight">Orange</Color>
<Color x:Key="StarOnDark">Orange</Color>
<Color x:Key="StarOffLight">#E1E1E1</Color>
<Color x:Key="StarOffDark">#717171</Color>
<Color x:Key="ChevronLight">#C5C5C7</Color>
<Color x:Key="ChevronDark">#59585D</Color>
<Color x:Key="BookDataLight">#6E6E6E</Color>
<Color x:Key="BookDataDark">#AAAAAA</Color>
<Color x:Key="groupHeaderLabelLight">#807F84</Color>
<Color x:Key="groupHeaderLabelDark">#9998A0</Color>
<Color x:Key="groupHeaderBackgroundLight">#F1F1F6</Color>
<Color x:Key="groupHeaderBackgroundDark">#1C1C1E</Color>
<Color x:Key="bookItemStatusLight">#6E6E6E</Color>
<Color x:Key="bookItemStatusDark">#87878C</Color>
<Color x:Key="indexScrollLight">#3378F7</Color>
<Color x:Key="indexScrollDark">#3686F8</Color>
<Color x:Key="scanMenuBackgroundLight">#F4F4F4</Color>
<Color x:Key="scanMenuBackgroundDark">#262626</Color>
<Color x:Key="scanMenuTitleLight">#C8C8C8</Color>
<Color x:Key="scanMenuTitleDark">#9E9F13</Color>
<Color x:Key="scanMenuDividerLight">#C8C8C8</Color>
<Color x:Key="scanMenuDividerDark">#726D6A</Color>
<Color x:Key="scanMenuStrongDividerLight">#C8C8C8</Color>
<Color x:Key="scanMenuStrongDividerDark">#242424</Color>
<Color x:Key="filterCountColorLight">#919191</Color>
<Color x:Key="filterCountColorDark">#99989E</Color>
<Color x:Key="filterDividerLight">#E1E1E1</Color>
<Color x:Key="filterDividerDark">#3C3B41</Color>
<Color x:Key="selectorBackgroundLight">#E1E1E1</Color>
<Color x:Key="selectorBackgroundDark">#323137</Color>
<Color x:Key="selectorSelectedLight">White</Color>
<Color x:Key="selectorSelectedDark">#6A696F</Color>
<Color x:Key="selectorLabelLight">Black</Color>
<Color x:Key="selectorLabelDark">#FDFDFD</Color>
<Color x:Key="filterMenuLight">#F8F8F8</Color>
<Color x:Key="filterMenuDark">#1C1C1E</Color>
</ResourceDictionary>

@ -2,9 +2,75 @@
<?xaml-comp compile="true" ?>
<ResourceDictionary
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml">
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:toolkit="http://schemas.microsoft.com/dotnet/2022/maui/toolkit">
<Style TargetType="ActivityIndicator">
<Style TargetType="Border" x:Key="selectorItemSelectedStyle">
<Setter Property="Stroke" Value="Transparent"/>
<Setter Property="HorizontalOptions" Value="Center"/>
<Setter Property="VerticalOptions" Value="CenterAndExpand"/>
<Setter Property="BackgroundColor" Value="{AppThemeBinding Light={StaticResource selectorSelectedLight}, Dark={StaticResource selectorSelectedDark}}"/>
<Setter Property="HeightRequest" Value="29"/>
<Setter Property="WidthRequest" Value="108"/>
<Setter Property="StrokeShape">
<RoundRectangle CornerRadius="6"/>
</Setter>
</Style>
<Style TargetType="Label" x:Key="selectorLabelStyle">
<Setter Property="BackgroundColor" Value="Transparent"/>
<Setter Property="VerticalOptions" Value="Center"/>
<Setter Property="HorizontalOptions" Value="Center"/>
<Setter Property="FontFamily" Value="SF Pro Display Regular"/>
<Setter Property="TextColor" Value="{AppThemeBinding Light={StaticResource selectorLabelLight}, Dark={StaticResource selectorLabelDark}}"/>
</Style>
<Style TargetType="Border" x:Key="selector2Style">
<Setter Property="Stroke" Value="Transparent"/>
<Setter Property="HorizontalOptions" Value="Center"/>
<Setter Property="VerticalOptions" Value="Center"/>
<Setter Property="Margin" Value="0, 15"/>
<Setter Property="HeightRequest" Value="33"/>
<Setter Property="WidthRequest" Value="222"/>
<Setter Property="BackgroundColor" Value="{AppThemeBinding Light={StaticResource selectorBackgroundLight}, Dark={StaticResource selectorBackgroundDark}}"/>
<Setter Property="StrokeShape">
<RoundRectangle CornerRadius="8"/>
</Setter>
</Style>
<Style x:Key="StyleCollectionStack" TargetType="SwipeView">
<Setter Property="VisualStateManager.VisualStateGroups">
<VisualStateGroupList>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="Selected">
<VisualState.Setters>
<Setter Property="BackgroundColor"
Value="Transparent" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateGroupList>
</Setter>
</Style>
<Style x:Key="StyleCollectionGrid" TargetType="Grid">
<Setter Property="VisualStateManager.VisualStateGroups">
<VisualStateGroupList>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="Selected">
<VisualState.Setters>
<Setter Property="BackgroundColor"
Value="Transparent" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateGroupList>
</Setter>
</Style>
<Style TargetType="ActivityIndicator">
<Setter Property="Color" Value="{AppThemeBinding Light={StaticResource Primary}, Dark={StaticResource White}}" />
</Style>

@ -0,0 +1,33 @@
using Model;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BookApp.UseCase
{
public class AuthorsListToStringConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is List<Author> authorsList && authorsList.Any())
{
return string.Join(", ", authorsList.Select(a => a.Name));
}
return string.Empty;
}
public object ConvertBack(
object value,
Type targetType,
object parameter,
CultureInfo culture
)
{
throw new NotImplementedException();
}
}
}

@ -0,0 +1,125 @@
using Model;
using System.Diagnostics;
using System.Threading.Tasks;
using System.Windows.Input;
using ToolKit;
using VMWrapper;
namespace BookApp.ViewModel
{
[QueryProperty(nameof(BookId), "BookId")]
public class ViewModelDetailProvider : BaseViewModel
{
private readonly DetailBookViewModel _detailBookViewModel;
private string _id;
public string BookId
{
get => _id;
set
{
if (_id != value)
{
_id = value;
OnPropertyChanged();
LoadBookDetailAsync(_id);
}
}
}
private Book _bookDetail;
public Book BookDetail
{
get => _bookDetail;
set
{
_bookDetail = value;
OnPropertyChanged();
}
}
// Command Pop-up
public ICommand _popUpCommand;
public ICommand PopUpCommand => _popUpCommand ??= new CommandPersonnal(ShowPopUP);
public ViewModelDetailProvider(DetailBookViewModel detailBookViewModel)
{
_detailBookViewModel =
detailBookViewModel ?? throw new ArgumentNullException(nameof(detailBookViewModel));
}
private async void ShowPopUP()
{
string action = await DisplayActionSheet(
"Quel est le statut du livre ?",
"Cancel",
null,
"Finished",
"Reading",
"NotRead",
"ToBeRead"
);
switch (action)
{
case "Finished":
BookDetail.Status = Status.Finished;
OnPropertyChanged(nameof(BookDetail));
_detailBookViewModel.UpdateColleciton();
break;
case "Reading":
BookDetail.Status = Status.Reading;
OnPropertyChanged(nameof(BookDetail));
_detailBookViewModel.UpdateColleciton();
break;
case "NotRead":
BookDetail.Status = Status.NotRead;
OnPropertyChanged(nameof(BookDetail));
_detailBookViewModel.UpdateColleciton();
break;
case "ToBeRead":
BookDetail.Status = Status.ToBeRead;
OnPropertyChanged(nameof(BookDetail));
_detailBookViewModel.UpdateColleciton();
break;
default:
BookDetail.Status = Status.Unknown;
OnPropertyChanged(nameof(BookDetail));
break;
}
}
public async Task<string> DisplayActionSheet(
string title,
string cancel,
string destruction,
params string[] buttons
)
{
return await Application.Current.MainPage.DisplayActionSheet(
title,
cancel,
destruction,
buttons
);
}
private async Task LoadBookDetailAsync(string bookId)
{
if (string.IsNullOrWhiteSpace(_id))
return;
try
{
await _detailBookViewModel.LoadBookDetail(bookId);
BookDetail = _detailBookViewModel.BookDetail;
}
catch (Exception ex)
{
Debug.WriteLine($"An error occurred: {ex.Message}");
}
}
}
}

@ -0,0 +1,67 @@
using System.Collections.ObjectModel;
using VMWrapper;
namespace BookApp.ViewModel
{
public class ViewModelMenu
{
public ObservableCollection<ViewModelMenuItem> MenuItemsLivre { get; set; }
public ObservableCollection<ViewModelMenuItem> MenuItemsFiltre { get; set; }
public ViewModelMenu(BooksViewModel booksViewModel)
{
MenuItemsLivre = new ObservableCollection<ViewModelMenuItem>()
{
new ViewModelMenuItem(
"Tous",
"../Resources/Images/tray_2_fill.svg",
booksViewModel.TotalBooks,
"TousPage"
),
new ViewModelMenuItem(
"En prêt",
"../Resources/Images/person_badge_clock_fill.svg",
null,
"EmpruntsPretsPage"
),
new ViewModelMenuItem(
"À lire plus tard",
"../Resources/Images/arrow_forward.svg",
null,
""
),
new ViewModelMenuItem(
"Statut de lecture",
"../Resources/Images/eyeglasses.svg",
null,
""
),
new ViewModelMenuItem("Favoris", "../Resources/Images/heart_fill.svg", null, ""),
new ViewModelMenuItem(
"Étiquettes",
"../Resources/Images/tag_fill.svg",
null,
"",
true
),
};
MenuItemsFiltre = new ObservableCollection<ViewModelMenuItem>()
{
new ViewModelMenuItem(
"Auteur",
"../Resources/Images/person_fill.svg",
booksViewModel.TotalAuthors,
"FiltragePage"
),
new ViewModelMenuItem(
"Date de publication",
"../Resources/Images/calendar.svg",
null,
"FiltragePage"
),
new ViewModelMenuItem("Note", "../Resources/Images/sparkles.svg", null, "", true),
};
}
}
}

@ -0,0 +1,32 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BookApp.ViewModel
{
public class ViewModelMenuItem
{
public string Name { get; set; }
public string Icone { get; set; }
public long? Number { get; set; }
public string Route { get; set; }
public bool IsLastItem { get; set; }
public ViewModelMenuItem(
string name,
string icone,
long? number,
string route,
bool isLastItem = false
)
{
Name = name;
Icone = icone;
Number = number;
Route = route;
IsLastItem = isLastItem;
}
}
}

@ -0,0 +1,115 @@
using ToolKit;
using System.Windows.Input;
using System.Diagnostics;
using Model;
using System.Net;
namespace BookApp.ViewModel
{
public class ViewModelNavigation : BaseViewModel
{
public INavigation Navigation { get; set; }
private string _title;
public string Title
{
get => _title;
set
{
_title = value;
OnPropertyChanged();
}
}
// Command Pop
public ICommand _backButtonCommand;
public ICommand BackButtonCommand =>
_backButtonCommand ??= new CommandPersonnal(
async () => await BackButton(this, EventArgs.Empty)
);
// Command Collection livre
public ICommand _bookDetailCommand;
public ICommand BookDetailCommand =>
_bookDetailCommand ??= new CommandPersonnal<string>(
async (book) => await OnToItemDetail(book)
);
// Command Collection menu
private ICommand _menuItemsCommand;
public ICommand MenuItemsCommand =>
_menuItemsCommand ??= new CommandPersonnal<ViewModelMenuItem>(
async (item) => await OnItemSelected(item)
);
public ICommand _menuItemsFiltreCommand;
public ICommand MenuItemsFiltreCommand =>
_menuItemsFiltreCommand ??= new CommandPersonnal<ViewModelMenuItem>(
async (item) => await OnItemSelected(item)
);
public ViewModelNavigation() { }
private async Task OnItemSelected(ViewModelMenuItem selectedItem)
{
if (string.IsNullOrEmpty(selectedItem?.Route))
{
Debug.WriteLine("Route is null, cannot navigate.");
return;
}
try
{
Title = selectedItem.Name;
SelectTab(selectedItem.Route);
var navigationParameter = new Dictionary<string, object> { { "Title", Title } };
await Shell.Current.GoToAsync(selectedItem.Route, navigationParameter);
Shell.Current.ForceLayout();
}
catch (Exception ex)
{
Debug.WriteLine($"Navigation failed: {ex.Message}");
}
}
private async Task OnToItemDetail(string bookId)
{
if (bookId == null)
{
Debug.WriteLine("Book is null, cannot navigate to details page.");
return;
}
try
{
var navigationParameter = new Dictionary<string, object> { { "BookId", bookId } };
await Shell.Current.GoToAsync($"DetailBookPage", navigationParameter);
}
catch (Exception ex)
{
Debug.WriteLine($"Navigation failed: {ex.Message}");
}
}
async Task BackButton(object sender, EventArgs args)
{
if (Shell.Current.Navigation.NavigationStack.Count > 1)
{
await Shell.Current.Navigation.PopAsync();
}
}
private void SelectTab(string route)
{
var shellItem = Shell.Current.Items.FirstOrDefault(
item => item.Items.Any(section => section.Route.Contains(route))
);
if (shellItem != null)
{
Shell.Current.CurrentItem = shellItem;
}
}
}
}

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save