Compare commits

...

214 Commits

Author SHA1 Message Date
tomivt 27016668bd Code Smells from Pages/Edit
continuous-integration/drone/push Build is passing Details
2 months ago
tomivt ccf7e35f39 Code Smells from Pages/DeleteUser
continuous-integration/drone/push Build is passing Details
2 months ago
tomivt cc616955bc Code Smells from Pages/AddQuiz
continuous-integration/drone/push Build is passing Details
2 months ago
tomivt 04110bc503 Code Smells from Pages/Acceuil
continuous-integration/drone/push Build is passing Details
2 months ago
tomivt 0bead3de61 Code Smells from Service
continuous-integration/drone/push Build is passing Details
2 months ago
tomivt 2018e18e10 Code Smells from Program.cs
continuous-integration/drone/push Build is passing Details
2 months ago
tomivt 15392ab08a Code Smells from wwwroot/css
continuous-integration/drone/push Build is passing Details
2 months ago
Kentin BRONGNIART 7885b8c724 Random daily quote
continuous-integration/drone/push Build is passing Details
2 months ago
Kentin BRONGNIART dc8d2510af Random daily quote
2 months ago
Maxime ROCHER c9a9e592d4 Mise à jour de 'README.md'
continuous-integration/drone/push Build is passing Details
2 months ago
Maxime ROCHER cdf1c5777c ajout petits icons stylax
continuous-integration/drone/push Build is passing Details
2 months ago
Maxime ROCHER 79f819295d Merge branch 'master' of https://codefirst.iut.uca.fr/git/WhatTheFantasy/WF-WebAdmin
continuous-integration/drone/push Build is passing Details
2 months ago
Maxime ROCHER 3070676b20 Enfin le graphique
2 months ago
tomivt 4be846cd05 Code Smells from Converter
continuous-integration/drone/push Build is passing Details
2 months ago
tomivt 6aff34e983 Code Smells from Model
continuous-integration/drone/push Build is passing Details
2 months ago
Maxime ROCHER 6b3a7283b5 retablissement CI
continuous-integration/drone/push Build is passing Details
2 months ago
Maxime ROCHER a16dca6156 retablissement CI
2 months ago
Maxime ROCHER 34abbf746b rien
continuous-integration/drone/push Build is failing Details
2 months ago
Maxime ROCHER afc393907a Merge branch 'master' of https://codefirst.iut.uca.fr/git/WhatTheFantasy/WF-WebAdmin
continuous-integration/drone/push Build is failing Details
2 months ago
Maxime ROCHER eab4b4fa05 rien
2 months ago
Kentin BRONGNIART b1edb3fec5 Mise à jour de 'WF-WebAdmin/WF-WebAdmin/Pages/Error.cshtml.cs'
continuous-integration/drone/push Build is failing Details
2 months ago
Maxime ROCHER 6fa4511781 Merge branch 'master' of https://codefirst.iut.uca.fr/git/WhatTheFantasy/WF-WebAdmin
2 months ago
Kentin BRONGNIART 73595560e5 correction erreur a la con
continuous-integration/drone/push Build is failing Details
2 months ago
Maxime ROCHER 0e564f580b Merge branch 'master' of https://codefirst.iut.uca.fr/git/WhatTheFantasy/WF-WebAdmin
2 months ago
Maxime ROCHER db4edcb1d1 rien
2 months ago
Kentin BRONGNIART 4f730ec5f8 Merge branch 'master' of https://codefirst.iut.uca.fr/git/WhatTheFantasy/WF-WebAdmin
continuous-integration/drone/push Build is failing Details
2 months ago
Kentin BRONGNIART 9dcb541816 debut graph
2 months ago
Louis GUICHARD-MONTGUERS d735893b9d Mise à jour de 'WF-WebAdmin/WF-WebAdmin/Pages/Accueil.razor.cs'
continuous-integration/drone/push Build is failing Details
2 months ago
Louis GUICHARD-MONTGUERS 7fe7395d9e Mise à jour de 'WF-WebAdmin/WF-WebAdmin/Model/UserLogin.cs'
continuous-integration/drone/push Build is failing Details
2 months ago
Louis GUICHARD-MONTGUERS 52b377fef8 Mise à jour de 'WF-WebAdmin/WF-WebAdmin/Model/User.cs'
continuous-integration/drone/push Build is failing Details
2 months ago
Louis GUICHARD-MONTGUERS 8e700eeca2 Mise à jour de 'WF-WebAdmin/WF-WebAdmin/Model/Source.cs'
continuous-integration/drone/push Build is failing Details
2 months ago
Louis GUICHARD-MONTGUERS 1c7397fe87 Mise à jour de 'WF-WebAdmin/WF-WebAdmin/Model/QuoteModel.cs'
continuous-integration/drone/push Build is failing Details
2 months ago
Louis GUICHARD-MONTGUERS 6e4f1d8398 Mise à jour de 'WF-WebAdmin/WF-WebAdmin/Model/Quote.cs'
continuous-integration/drone/push Build is failing Details
2 months ago
Louis GUICHARD-MONTGUERS 925528a922 Mise à jour de 'WF-WebAdmin/WF-WebAdmin/Model/QuizModel.cs'
continuous-integration/drone/push Build is failing Details
2 months ago
Louis GUICHARD-MONTGUERS d45847c03a Mise à jour de 'WF-WebAdmin/WF-WebAdmin/Model/QuizModel.cs'
continuous-integration/drone/push Build is failing Details
2 months ago
Louis GUICHARD-MONTGUERS 866156ca35 Mise à jour de 'WF-WebAdmin/WF-WebAdmin/Model/Quiz.cs'
continuous-integration/drone/push Build is failing Details
2 months ago
Louis GUICHARD-MONTGUERS 9a71fea118 Mise à jour de 'WF-WebAdmin/WF-WebAdmin/Model/LoggerSaveStub.cs'
continuous-integration/drone/push Build is failing Details
2 months ago
Louis GUICHARD-MONTGUERS 5a5d83fa02 Mise à jour de 'WF-WebAdmin/WF-WebAdmin/Model/Character.cs'
continuous-integration/drone/push Build is failing Details
2 months ago
Louis GUICHARD-MONTGUERS a06a14ffcc Mise à jour de 'WF-WebAdmin/WF-WebAdmin/Converter/UserDto.cs'
continuous-integration/drone/push Build is failing Details
2 months ago
Louis GUICHARD-MONTGUERS 45d8ba09ca Mise à jour de 'WF-WebAdmin/WF-WebAdmin/Converter/UserDto.cs'
continuous-integration/drone/push Build is failing Details
2 months ago
Louis GUICHARD-MONTGUERS bfe46f272c Mise à jour de 'WF-WebAdmin/WF-WebAdmin/Converter/DailyQuoteDto.cs'
continuous-integration/drone/push Build is failing Details
2 months ago
Louis GUICHARD-MONTGUERS 0408cc51fe Mise à jour de 'WF-WebAdmin/WF-WebAdmin/Converter/CommentaryDto.cs'
continuous-integration/drone/push Build is failing Details
2 months ago
Louis GUICHARD-MONTGUERS adc57b1ba9 Mise à jour de 'WF-WebAdmin/WF-WebAdmin/Converter/QuoteDto.cs'
continuous-integration/drone/push Build is failing Details
2 months ago
Louis GUICHARD-MONTGUERS 02aa7a1b15 Mise à jour de 'WF-WebAdmin/WF-WebAdmin/wwwroot/css/site.css'
continuous-integration/drone/push Build is failing Details
2 months ago
Louis GUICHARD-MONTGUERS 95db35940c Mise à jour de 'WF-WebAdmin/WF-WebAdmin/Pages/Error.cshtml.cs'
continuous-integration/drone/push Build is failing Details
2 months ago
Louis GUICHARD-MONTGUERS 6b6a859982 Mise à jour de 'WF-WebAdmin/WF-WebAdmin/Pages/DeleteUser.razor.cs'
continuous-integration/drone/push Build is failing Details
2 months ago
Louis GUICHARD-MONTGUERS f6936c7caa Mise à jour de 'WF-WebAdmin/WF-WebAdmin/Service/QuoteServiceLocal.cs'
continuous-integration/drone/push Build is passing Details
2 months ago
Louis GUICHARD-MONTGUERS 72e29790a3 Mise à jour de 'WF-WebAdmin/WF-WebAdmin/Pages/Error.cshtml'
continuous-integration/drone/push Build is passing Details
2 months ago
Louis GUICHARD-MONTGUERS 72ff55a889 Mise à jour de 'WF-WebAdmin/WF-WebAdmin/Pages/_Layout.cshtml'
continuous-integration/drone/push Build is passing Details
2 months ago
Louis GUICHARD-MONTGUERS 05b13c040a Mise à jour de 'WF-WebAdmin/WF-WebAdmin/Pages/Error.cshtml'
continuous-integration/drone/push Build is passing Details
2 months ago
Louis GUICHARD-MONTGUERS de00eac783 Mise à jour de 'WF-WebAdmin/WF-WebAdmin/Pages/_Layout.cshtml'
continuous-integration/drone/push Build is passing Details
2 months ago
Louis GUICHARD-MONTGUERS 319ae73422 Mise à jour de 'WF-WebAdmin/WF-WebAdmin/Pages/_Layout.cshtml'
continuous-integration/drone/push Build is passing Details
2 months ago
Louis GUICHARD-MONTGUERS d2188b3de8 Mise à jour de 'WF-WebAdmin/WF-WebAdmin/Pages/ModifQuote.razor.cs'
continuous-integration/drone/push Build is passing Details
2 months ago
Louis GUICHARD-MONTGUERS 611de18362 Mise à jour de 'WF-WebAdmin/WF-WebAdmin/Pages/Edit.razor.cs'
continuous-integration/drone/push Build is passing Details
2 months ago
Louis GUICHARD-MONTGUERS 5ad531d6bb Mise à jour de 'WF-WebAdmin/WF-WebAdmin/Pages/AddQuiz.razor.cs'
continuous-integration/drone/push Build is passing Details
2 months ago
Louis GUICHARD-MONTGUERS c358e55aa2 Mise à jour de 'WF-WebAdmin/WF-WebAdmin/Pages/ModifQuiz.razor.cs'
continuous-integration/drone/push Build is passing Details
2 months ago
Maxime ROCHER f6bd5d2fc1 ça ne marche pas mais je n'y arrive pas tant pis au moins la page est propre
continuous-integration/drone/push Build is passing Details
3 months ago
Leni BEAULATON 67b4094d81 Merge pull request 'trad Logs' (#32) from TradLog into master
continuous-integration/drone/push Build is passing Details
3 months ago
lebeaulato 5597617c48 trad Logs
continuous-integration/drone/push Build is passing Details
3 months ago
Kentin BRONGNIART ea6f8e9837 Mise à jour de 'README.md'
continuous-integration/drone/push Build is passing Details
3 months ago
Kentin BRONGNIART 226af6cb8f Merge pull request 'Logs' (#31) from Logs into master
continuous-integration/drone/push Build is passing Details
3 months ago
kentin.brongniart 35badacd55 Merge de master sur login pour le merge
continuous-integration/drone/push Build is passing Details
3 months ago
kentin.brongniart 2d314b5a87 Logs complet
continuous-integration/drone/push Build is passing Details
3 months ago
Leni BEAULATON 6ea3c6e7f9 Mise à jour de 'README.md'
continuous-integration/drone/push Build is passing Details
3 months ago
Leni BEAULATON 3cfc5fad2e Mise à jour de 'README.md'
continuous-integration/drone/push Build is passing Details
3 months ago
Leni BEAULATON 69a7d64a9f Merge pull request 'Docummentation' (#30) from Docummentation into master
continuous-integration/drone/push Build is passing Details
3 months ago
lebeaulato 1e89ed53c1 Merge branch 'Docummentation' of https://codefirst.iut.uca.fr/git/WhatTheFantasy/WF-WebAdmin into Docummentation
continuous-integration/drone/push Build is passing Details
3 months ago
lebeaulato 1707cfe514 Doc classe
3 months ago
kentin.brongniart b8af563ce9 merge de logs et de master
3 months ago
lebeaulato 7b71f7ea86 doc fait sur le code behind des pages
3 months ago
lebeaulato 6697bfc395 Correction drone
continuous-integration/drone/push Build is passing Details
3 months ago
lebeaulato e90dfa53f9 URL
continuous-integration/drone/push Build is failing Details
3 months ago
lebeaulato af56418753 Test URL
continuous-integration/drone/push Build is failing Details
3 months ago
Leni BEAULATON 2aa33effc9 Merge pull request 'SuppLogin' (#29) from SuppLogin into master
continuous-integration/drone/push Build is failing Details
3 months ago
lebeaulato f1ec7af13c Login retiré
continuous-integration/drone/push Build is passing Details
3 months ago
lebeaulato 8739576cec pb de URL corrigé
continuous-integration/drone/push Build is failing Details
3 months ago
lebeaulato f3b95d273d doc fait sur le code behind des pages
continuous-integration/drone/push Build is passing Details
3 months ago
Leni BEAULATON c0596f6810 Mise à jour de 'README.md'
continuous-integration/drone/push Build is passing Details
3 months ago
lebeaulato 582bb13bcf problème de pare feu mais j'ai normalement retiré le login
continuous-integration/drone/push Build is passing Details
3 months ago
Kentin BRONGNIART 25963b2c38 Finition des logs (fonction créé a rajouter sur tous les bouton pour la création des logs / logs enregister et afficher dans la page logs)
3 months ago
Tommy NGUYEN 7ad7135804 Documentation réalisée
continuous-integration/drone/push Build is passing Details
3 months ago
Maxime ROCHER 757643c47b roll back
continuous-integration/drone/push Build is passing Details
3 months ago
Maxime ROCHER 6eef595777 roll back
continuous-integration/drone/push Build is failing Details
3 months ago
Maxime ROCHER 21acb505ef roll back
continuous-integration/drone/push Build encountered an error Details
3 months ago
Maxime ROCHER 0af5d95878 deploiement 7
continuous-integration/drone/push Build was killed Details
3 months ago
Maxime ROCHER 37a0b06885 deploiement 7
continuous-integration/drone/push Build is failing Details
3 months ago
Maxime ROCHER 5fbd65e3ba deploiement 6
continuous-integration/drone/push Build is failing Details
3 months ago
Maxime ROCHER 0ba0670270 deploiement 5
continuous-integration/drone/push Build is failing Details
3 months ago
Maxime ROCHER d11ce9cbc9 deploiement 4
continuous-integration/drone/push Build is failing Details
3 months ago
Maxime ROCHER 0875452004 deploiement 3
continuous-integration/drone/push Build is failing Details
3 months ago
Maxime ROCHER 3b96126e7d deploiement 2
continuous-integration/drone/push Build is passing Details
3 months ago
Maxime ROCHER 050d401443 deploiement
continuous-integration/drone/push Build is failing Details
3 months ago
Maxime ROCHER d83a99fec1 m
continuous-integration/drone/push Build is passing Details
3 months ago
Maxime ROCHER 5a93a72b76 test deploy
continuous-integration/drone/push Build is passing Details
3 months ago
Maxime ROCHER 0c6dd6026c test deploy
continuous-integration/drone/push Build is passing Details
3 months ago
Maxime ROCHER e77505db6d test deploy
continuous-integration/drone/push Build is failing Details
3 months ago
Maxime ROCHER fab75f2fe8 test deploy
continuous-integration/drone/push Build encountered an error Details
3 months ago
Maxime ROCHER 67252ff84f test deploy
continuous-integration/drone/push Build encountered an error Details
3 months ago
Maxime ROCHER 99db1ed7a2 Test CI 19
continuous-integration/drone/push Build is passing Details
3 months ago
Maxime ROCHER d3fe3e7323 Test CI 18
continuous-integration/drone/push Build is failing Details
3 months ago
Maxime ROCHER 5a63b9916e Test CI 17
continuous-integration/drone/push Build is failing Details
3 months ago
Maxime ROCHER e052f95ad9 Test CI 16
continuous-integration/drone/push Build is failing Details
3 months ago
Maxime ROCHER fe0cef5afd Merge branch 'master' of https://codefirst.iut.uca.fr/git/WhatTheFantasy/WF-WebAdmin
continuous-integration/drone/push Build encountered an error Details
3 months ago
Maxime ROCHER 82a534d9c7 Test CI 15
3 months ago
Kevin MONDEJAR 356bff2072 Mise à jour de 'README.md'
continuous-integration/drone/push Build is failing Details
3 months ago
Maxime ROCHER 10970ffd9a Test CI 14
continuous-integration/drone/push Build is failing Details
3 months ago
Maxime ROCHER 6e40ec6ca9 Test CI 13
continuous-integration/drone/push Build is failing Details
3 months ago
Maxime ROCHER 68483c3178 Test CI 12
continuous-integration/drone/push Build is failing Details
3 months ago
Maxime ROCHER 9b1c324dfd Test CI 11
continuous-integration/drone/push Build is failing Details
3 months ago
Kentin BRONGNIART 6a9afeb6f4 Début Logs
3 months ago
Maxime ROCHER b9cb6fe4b3 Test CI 10
continuous-integration/drone/push Build is failing Details
3 months ago
Maxime ROCHER 2b3e93121e Test CI 9
continuous-integration/drone/push Build is failing Details
3 months ago
Maxime ROCHER 188c759f07 Test CI 8
continuous-integration/drone/push Build is failing Details
3 months ago
Maxime ROCHER 7cf5395f14 Test CI 7
continuous-integration/drone/push Build is failing Details
3 months ago
Maxime ROCHER c4a7ae258a Test CI 6
continuous-integration/drone/push Build is failing Details
3 months ago
Maxime ROCHER 4be7866a60 Test CI 5
continuous-integration/drone/push Build is failing Details
3 months ago
Maxime ROCHER d4dc0ce2e6 Test CI 4
continuous-integration/drone/push Build is failing Details
3 months ago
Maxime ROCHER 24daff406c Test CI 3
continuous-integration/drone/push Build is failing Details
3 months ago
Maxime ROCHER daa004e9b2 Test CI 2
continuous-integration/drone/push Build encountered an error Details
3 months ago
Maxime ROCHER 18a4bfd070 Test CI
continuous-integration/drone/push Build encountered an error Details
3 months ago
Maxime ROCHER c31576b3cc retour a une version valable
continuous-integration/drone/push Build is passing Details
3 months ago
Maxime ROCHER 21a6ba1179 retour a une version valable
continuous-integration/drone/push Build is passing Details
3 months ago
Maxime ROCHER 321dc6feb5 test CI 13
continuous-integration/drone/push Build encountered an error Details
3 months ago
Maxime ROCHER f0dce9458d test CI 12
continuous-integration/drone/push Build is failing Details
3 months ago
Maxime ROCHER bd925d8464 test CI 10
continuous-integration/drone/push Build is passing Details
3 months ago
Maxime ROCHER f71147c972 test CI 10
continuous-integration/drone/push Build is failing Details
3 months ago
Maxime ROCHER 56d6cac2e2 test CI 9
continuous-integration/drone/push Build is failing Details
3 months ago
Maxime ROCHER 9d64672696 test CI 8
continuous-integration/drone/push Build is failing Details
3 months ago
Maxime ROCHER 193556acdb test CI 7
continuous-integration/drone/push Build is failing Details
3 months ago
Maxime ROCHER 09552612b6 test CI 6
continuous-integration/drone/push Build is failing Details
3 months ago
Maxime ROCHER 050fdcff63 test CI 5
continuous-integration/drone/push Build is failing Details
3 months ago
Maxime ROCHER cf739c6b2e test CI 4
continuous-integration/drone/push Build is failing Details
3 months ago
Maxime ROCHER 9603dbbb53 test CI 3
continuous-integration/drone/push Build is failing Details
3 months ago
Maxime ROCHER f75579fe99 test CI 2
3 months ago
Maxime ROCHER 9210407757 test CI
3 months ago
Leni BEAULATON c11f071714 Mise à jour de 'README.md'
3 months ago
Leni BEAULATON bb660e1ff8 Mise à jour de 'README.md'
3 months ago
Leni BEAULATON 9caa42b511 Merge pull request 'Traduction' (#28) from Traduction into master
3 months ago
lebeaulato 13f435d606 fin trad
3 months ago
lebeaulato 3a896aa3ce Trad AddQuiz et ValidQuote
3 months ago
Kevin MONDEJAR b58a71448d resolve build problem
3 months ago
Kevin MONDEJAR 37edad86db Merge pull request 'Service' (#26) from Service into master
3 months ago
Kevin MONDEJAR f4b6c6bfe1 merge conflict resolution
3 months ago
Kevin MONDEJAR c1f629502d Merge branch 'master' into Service
3 months ago
Kevin MONDEJAR 9d8eb2e5d5 fin service
3 months ago
Kevin MONDEJAR f17fa7e31e Mise à jour de 'README.md'
3 months ago
Kevin MONDEJAR 4ee638eae7 Mise à jour de 'README.md'
3 months ago
Leni BEAULATON 36551e32bd Merge pull request 'Langage2' (#25) from Langage2 into master
3 months ago
lebeaulato 2f381cb77f trad Accueil
3 months ago
lebeaulato 675388ed42 trad Login / deleteUser
3 months ago
lebeaulato 0b836046d6 les langues marchent
3 months ago
Kentin BRONGNIART a15a229374 Mise à jour de 'README.md'
3 months ago
Kevin MONDEJAR 2f32bb42ee Page gestion quiz + ajout quiz admin (ne pas aller sur les page elle font planter le site pour l'instant)
3 months ago
lebeaulato b68613d4da marche pas encore
3 months ago
lebeaulato e0f3f01d8d test encore de cette langue qui marche pas
3 months ago
Kevin MONDEJAR bfc54acd19 modification QuizServiceStub/DeleteUser/ModifQuote
3 months ago
tomivt f79e01ea05 Start editQuote method
3 months ago
tomivt 85aeeb061c Complete setAdmin method
3 months ago
tomivt 944c620e80 Add QuizService
3 months ago
Kevin MONDEJAR 35e33f14fc comencement datagrid user
3 months ago
Leni BEAULATON 3a2e66c4d3 Mise à jour de 'README.md'
3 months ago
Leni BEAULATON 02d8f0056f Mise à jour de 'README.md'
3 months ago
Leni BEAULATON 6d32625317 Mise à jour de 'README.md'
3 months ago
Leni BEAULATON b8365ee2b0 Mise à jour de 'README.md'
3 months ago
Kevin MONDEJAR 7be821200b j en ai marre y a rien qui marche comme je veux
3 months ago
Kevin MONDEJAR f1d4537b72 enlever les accent
3 months ago
Kevin MONDEJAR d84d419ee4 J ai ratraper les connerie de tommy pour pas changer
3 months ago
lebeaulato 1f5d60db65 Mise en place d'un bouton pour se déconnecter (ne marche pas encore)
3 months ago
Leni BEAULATON ae05689214 Merge pull request 'modif accueil et essai de mettre l'icon de Wf dans le header' (#24) from Modif into master
3 months ago
lebeaulato 616ecc8220 modif accueil et essai de mettre l'icon de Wf dans le header
3 months ago
tomivt b3f3133e1a Add modify/update on click button
3 months ago
Louis GUICHARD-MONTGUERS 750785032b Quote stub json
3 months ago
tomivt dc90d68d79 Apply methods on click
3 months ago
tomivt 8352e4fe28 Add UserServiceJson
3 months ago
lebeaulato 63ef5a9cd3 fautes d'aurtaugrafe
3 months ago
lebeaulato 60eeea3920 Login fonctionne
3 months ago
Leni BEAULATON 00bc784f05 Merge pull request 'Login' (#22) from Login into master
3 months ago
lebeaulato 5bc530fe3b fusion Login
3 months ago
lebeaulato c7ba93c33b Login avec connexion (fake)
3 months ago
lebeaulato 6c95137bf8 Login en cours
3 months ago
tomivt e22c0973fe Merge ValidQuiz into master
3 months ago
tomivt 9567032ef1 Remove @ + Add OnButtonClicked methods
3 months ago
tomivt e54f60b8c8 Add table + buttons
3 months ago
tomivt 033894993a Add datagrid + fake data
3 months ago
kentin.brongniart c5c2e597ae Debut correction bug
3 months ago
Maxime ROCHER 54ab34216a Merge branch 'Converter'
3 months ago
Maxime ROCHER 5ad2ff07dc Merge branch 'master' of https://codefirst.iut.uca.fr/git/WikiFantasy/WF-WebAdmin
3 months ago
Maxime ROCHER 37aaf55c4a jsp
3 months ago
lebeaulato d1c7001bf7 changement de nom
4 months ago
lebeaulato b4c50be578 correcton bug
4 months ago
Leni BEAULATON cf755c7cb4 Merge pull request 'Login' (#18) from Login into master
4 months ago
lebeaulato 6a3f265328 Fusion
4 months ago
lebeaulato 9c76e5204e encore pour la fusion
4 months ago
lebeaulato 2d83bd8014 pour la fusion
4 months ago
lebeaulato ce916e4422 renommage
4 months ago
Leni BEAULATON afa6845535 Mise à jour de 'WF-WebAdmin/WF-WebAdmin/wwwroot/fake-dataUsers.json'
4 months ago
lebeaulato 5ed7fa68d8 css login
4 months ago
Louis GUICHARD-MONTGUERS 77d8653ffd ajout
4 months ago
lebeaulato b416e774af Ajout de la page login + affichage des commentaires par utilisateur
4 months ago
kentin.brongniart 292e724a25 création fausse basse de donné
4 months ago
kentin.brongniart 226e2531b0 création fausse basse de donné
4 months ago
kentin.brongniart a52e071113 création fausse basse de donné
4 months ago
Maxime ROCHER 4fdfc87290 DTO user et Quote terminé avec extensions
4 months ago
Louis GUICHARD-MONTGUERS ee0a976ee2 Merge remote-tracking branch 'origin/Service' into Converter
4 months ago
Kevin MONDEJAR e176e97bb2 passage a Task interface
4 months ago
Louis GUICHARD-MONTGUERS c5eefafa96 Merge remote-tracking branch 'origin/Service' into Converter
4 months ago
Leni BEAULATON 6451b22dc3 Merge pull request 'Admin' (#10) from Admin into master
4 months ago
lebeaulato 59a06339be fusion de fonction pour la modif du rôle
4 months ago
Maxime ROCHER cd9edeb2fa DTO
4 months ago
lebeaulato 143a8c2f8a Ajout de la fonctionnalité, add Admin et delete admin
4 months ago
Kevin MONDEJAR 5853ad7004 Interface service Quote/User + Debut Stub Service Quote
4 months ago
Maxime ROCHER 1e2a18613e Début du DTO et des extensions
4 months ago
kentin.brongniart 2cecc2b68d recuperation push
4 months ago
kentin.brongniart 415257342c recuperation push
4 months ago

@ -0,0 +1,71 @@
kind: pipeline
name: CI
type: docker
trigger:
event:
- push
steps:
- name: build
image: mcr.microsoft.com/dotnet/sdk:6.0
commands:
- cd WF-WebAdmin/WF-WebAdmin
- dotnet restore WF-WebAdmin.csproj
- dotnet build WF-WebAdmin.csproj -c Release --no-restore
- dotnet publish WF-WebAdmin.csproj -c Release --no-restore -o $CI_PROJECT_DIR/build/publish
- name: tests
image: mcr.microsoft.com/dotnet/sdk:6.0
commands:
- cd WF-WebAdmin/WF-WebAdmin
- dotnet restore WF-WebAdmin.csproj
- dotnet test WF-WebAdmin.csproj --no-restore
depends_on: [ build ]
- name: code-analysis
image: hub.codefirst.iut.uca.fr/marc.chevaldonne/codefirst-dronesonarplugin-dotnet8
commands:
- cd WF-WebAdmin/
- dotnet restore WF-WebAdmin.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 WF-WebAdmin.sln -c Release --no-restore
- dotnet test WF-WebAdmin.sln --logger trx --no-restore /p:CollectCoverage=true /p:CoverletOutputFormat=cobertura --collect "XPlat Code Coverage"
- reportgenerator -reports:"**/coverage.cobertura.xml" -reporttypes:SonarQube -targetdir:"coveragereport"
- dotnet publish WF-WebAdmin.sln -c Release --no-restore -o $CI_PROJECT_DIR/build/release
- dotnet sonarscanner end /d:sonar.login=$${sonar_token}
secrets: [ SECRET_SONAR_LOGIN ]
environment:
sonar_host: https://codefirst.iut.uca.fr/sonar/
sonar_token:
from_secret: sonar_token
project_key: web_admin
coverage_exclusions: "Tests/**"
depends_on: [ tests ]
- name: generate-and-deploy-docs
image: hub.codefirst.iut.uca.fr/thomas.bellembois/codefirst-docdeployer
failure: ignore
volumes:
- name: docs
path: /docs
commands:
- /entrypoint.sh
when:
branch:
- master
depends_on: [ build ]
- name: docker_build
image: plugins/docker
settings:
repo: hub.codefirst.iut.uca.fr/whatthefantasy/wf-webadmin
registry: hub.codefirst.iut.uca.fr
dockerfile: Docker/Dockerfile
tags:
- latest
username:
from_secret: docker_username
password:
from_secret: docker_password
depends_on: [ build, tests, code-analysis ]

@ -0,0 +1,27 @@
# 1. Étape de build (SDK .NET 6)
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /src
# Copier le csproj et restaurer les dépendances
COPY WF-WebAdmin/WF-WebAdmin/WF-WebAdmin.csproj ./
RUN dotnet restore WF-WebAdmin.csproj
# Copier le reste du code et compiler
COPY WF-WebAdmin/WF-WebAdmin/ ./
RUN dotnet publish WF-WebAdmin.csproj -c Release -o /app/publish
# 2. Étape finale (runtime .NET 6)
FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS final
WORKDIR /app
# Désactiver le rechargement de config pour éviter les erreurs inotify
ENV ASPNETCORE_HOSTBUILDER__RELOADCONFIGONCHANGE=false
# Copier les binaires publiés
COPY --from=build /app/publish ./
# Exposer le port HTTP (80) ; adapte si besoin
EXPOSE 80
# Lancement
ENTRYPOINT ["dotnet", "WF-WebAdmin.dll"]

@ -1,2 +1,81 @@
# WF-WebAdmin # Projet Blazor What the Fantasy
## Description
Ce projet est une application web construite avec **Blazor**, permettant aux administrateurs de gérer plusieurs aspects du site, notamment :
- Administration des comptes utilisateurs : possibilité de **modifier** ou **supprimer** des comptes utilisateurs.
- Gestion des citations : les administrateurs peuvent **modifier**, **valider** ou **supprimer** des citations présentes sur le site.
- Création et génération de **quiz** : l'application permet de **créer** et **générer** des quiz interactifs.
L'application fournit une interface utilisateur claire et intuitive pour les administrateurs, offrant une expérience de gestion efficace et dynamique en utilisant **C#** au lieu de JavaScript, tout en tirant parti des technologies Blazor et .NET.
### Fonctionnalités principales
- **Gestion des utilisateurs** : Visualiser la liste des utilisateurs, modifier leurs informations, ou supprimer leur compte.
- **Gestion des citations** : Ajouter, valider, éditer ou supprimer des citations.
- **Gestion des quiz** : Créer de nouveaux quiz, ajouter des questions et gérer les résultats.
- **Tableau de bord administrateur** : Interface pour naviguer entre les différentes sections de gestion avec des statistiques en temps réel.
## Prérequis
Avant de pouvoir exécuter ce projet, assurez-vous d'avoir installé les éléments suivants sur votre machine :
- [.NET 6 SDK](https://dotnet.microsoft.com/download)
- Un navigateur compatible avec WebAssembly (par exemple, Chrome, Firefox, Edge, Safari)
- Visual Studio ou Visual Studio Code (optionnel, mais recommandé pour le développement)
## Installation
### 1. Cloner le repository
Clonez le dépôt Git sur votre machine locale avec la commande suivante :
```bash
git clone https://codefirst.iut.uca.fr/git/WhatTheFantasy/WF-WebAdmin.git
```
### 2. Ouvrir le projet dans votre IDE
Une fois le dépôt cloné, ouvrez le dossier du projet dans votre IDE préféré (par exemple, Visual Studio ou Visual Studio Code).
### 3. Restaurer les dépendances (si besoin)
Avant de pouvoir exécuter l'application, vous devez restaurer les dépendances NuGet. Dans le terminal, naviguez dans le répertoire du projet cloné (si ce n'est pas déjà fait) et exécutez la commande suivante :
```bash
cd blazor-admin-app
dotnet restore
```
### 4. Lancer l'application
Une fois les dépendances installées, vous pouvez démarrer l'application en mode développement avec la commande suivante :
```bash
dotnet run
```
L'application sera maintenant accessible dans votre navigateur à l'adresse suivante : http://localhost:5000.
### 5. Ouvrir l'application dans le navigateur
L'application devrait se lancer automatiquement dans votre navigateur par défaut. Si ce n'est pas le cas, ouvrez manuellement un navigateur et accédez à l'adresse **http://localhost:5000** pour voir l'application en action.
# Blazor Apps (30 points)
🟨 En cours / ✅ Fait / ❌ Pas fait<br/><br/>
✅ Mise en place d'une page de visualisation des données avec pagination (2 points) <br/>
✅ Page d'ajout d'un élement avec validation (2 point)<br/>
✅ Page d'édition d'un élement avec validation (2 point)<br/>
✅ Supression d'un élement avec une confirmation (2 point)<br/>
✅ Composant complexe (5 point)<br/>
🟨 Use API (Get / Insert / Update / Delete) (3 point)<br/>
✅ Utilisation IOC & DI (4 point)<br/>
✅ Localisation & Globalisation (au moins deux langues) (1 point) <br/>
❓ Utilisation de la configuration (1 point)<br/>
✅ Logs (2 point)<br/>
🟨 Propreté du code (Vous pouvez vous servir de sonarqube) (2 point)<br/>
✅ IHM (Design global, placement des boutons, ...) (2 point)<br/>
✅ Emplacement du code (Pas de code dans les vues) (2 point)<br/>
# Documentation (10 points)
✅ Le Readme (2 points)<br/>
✅ Description du fonctionnement de la solution client (illustrutration au niveau du code) (6 points)<br/>
✅ Merge request (2 points)<br/>

@ -0,0 +1,11 @@
namespace UnitTestWF
{
public class UnitTest1
{
[Fact]
public void Test1()
{
}
}
}

@ -0,0 +1,29 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
<IsTestProject>true</IsTestProject>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="coverlet.collector" Version="6.0.4">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.12.0" />
<PackageReference Include="xunit" Version="2.9.3" />
<PackageReference Include="xunit.runner.visualstudio" Version="3.0.2">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>
<Using Include="Xunit" />
</ItemGroup>
</Project>

@ -5,6 +5,8 @@ VisualStudioVersion = 17.9.34723.18
MinimumVisualStudioVersion = 10.0.40219.1 MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WF-WebAdmin", "WF-WebAdmin\WF-WebAdmin.csproj", "{0E8D1007-ADDC-4103-847D-8EE48ACCDC62}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WF-WebAdmin", "WF-WebAdmin\WF-WebAdmin.csproj", "{0E8D1007-ADDC-4103-847D-8EE48ACCDC62}"
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UnitTestWF", "UnitTestWF\UnitTestWF.csproj", "{A4EC0EC4-7A46-4F8E-99C3-4FD32F173F2F}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU Debug|Any CPU = Debug|Any CPU
@ -15,6 +17,10 @@ Global
{0E8D1007-ADDC-4103-847D-8EE48ACCDC62}.Debug|Any CPU.Build.0 = Debug|Any CPU {0E8D1007-ADDC-4103-847D-8EE48ACCDC62}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0E8D1007-ADDC-4103-847D-8EE48ACCDC62}.Release|Any CPU.ActiveCfg = Release|Any CPU {0E8D1007-ADDC-4103-847D-8EE48ACCDC62}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0E8D1007-ADDC-4103-847D-8EE48ACCDC62}.Release|Any CPU.Build.0 = Release|Any CPU {0E8D1007-ADDC-4103-847D-8EE48ACCDC62}.Release|Any CPU.Build.0 = Release|Any CPU
{A4EC0EC4-7A46-4F8E-99C3-4FD32F173F2F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A4EC0EC4-7A46-4F8E-99C3-4FD32F173F2F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A4EC0EC4-7A46-4F8E-99C3-4FD32F173F2F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A4EC0EC4-7A46-4F8E-99C3-4FD32F173F2F}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE

@ -0,0 +1,34 @@
using Microsoft.AspNetCore.Localization;
using Microsoft.AspNetCore.Mvc;
namespace WF_WebAdmin.Controllers
{
/// <summary>
/// The culture controller.
/// </summary>
[Route("[controller]/[action]")]
public class CultureController : Controller
{
/// <summary>
/// Sets the culture.
/// </summary>
/// <param name="culture">The culture.</param>
/// <param name="redirectUri">The redirect URI.</param>
/// <returns>
/// The action result.
/// </returns>
public IActionResult SetCulture(string culture, string redirectUri)
{
if (culture != null)
{
// Define a cookie with the selected culture
this.HttpContext.Response.Cookies.Append(
CookieRequestCultureProvider.DefaultCookieName,
CookieRequestCultureProvider.MakeCookieValue(
new RequestCulture(culture)));
}
return this.LocalRedirect(redirectUri);
}
}
}

@ -0,0 +1,23 @@
using System;
using System.Text.Json.Serialization;
namespace WF_WebAdmin.Converter
{
public class CommentaryDto
{
[JsonPropertyName("id_comment")]
public int Id { get; set; }
[JsonPropertyName("quote")]
public int Quote { get; set; }
[JsonPropertyName("users")]
public int IdUser { get; set; }
[JsonPropertyName("dateC")]
public string DateCreationRaw { get; set; } = string.Empty;
[JsonPropertyName("comment")]
public string Text { get; set; } = string.Empty;
}
}

@ -0,0 +1,46 @@
using System;
using System.Globalization;
using WF_WebAdmin.Model;
namespace WF_WebAdmin.Converter
{
public static class CommentaryExtensions
{
public static Commentary ToModel(this CommentaryDto dto)
{
DateTime parsedDate = DateTime.MinValue;
if (!string.IsNullOrEmpty(dto.DateCreationRaw) &&
DateTime.TryParseExact(dto.DateCreationRaw, "yyyy-MM-dd",
CultureInfo.InvariantCulture,
DateTimeStyles.None,
out DateTime result))
{
parsedDate = result;
}
else
{
Console.Out.WriteLine($"Erreur de conversion de la date : {dto.DateCreationRaw}");
}
return new Commentary
{
Id = dto.Id,
IdUser = dto.IdUser,
DateCreation = parsedDate,
Text = dto.Text
};
}
public static CommentaryDto ToDTO(this Commentary model)
{
return new CommentaryDto
{
Id = model.Id,
IdUser = model.IdUser,
DateCreationRaw = model.DateCreation.ToString("yyyy-MM-dd"),
Text = model.Text
};
}
}
}

@ -0,0 +1,12 @@
namespace WF_WebAdmin.Converter
{
public class DailyQuoteDto
{
private int Id { get; set; }
public DailyQuoteDto(int id)
{
this.Id = id;
}
}
}

@ -0,0 +1,13 @@
using WF_WebAdmin.Model;
namespace WF_WebAdmin.Converter
{
public class DailyQuoteExtension
{
public DailyQuoteDto DailyQuoteToDto(DailyQuote dq)
{
DailyQuoteDto dailyQuote = new DailyQuoteDto(dq.Id);
return dailyQuote;
}
}
}

@ -0,0 +1,43 @@
using Microsoft.AspNetCore.DataProtection.KeyManagement;
using System;
namespace WF_WebAdmin.Converter
{
public class QuoteDto
{
public int Id { get; set; }
public string Content { get; set; }
public int Likes { get; set; }
public string Langue { get; set; }
public bool IsValide { get; set; }
public string? Reason { get; set; }
public int? IdCaracter { get; set; }
public string NameCharac { get; set; }
public int? IdSource { get; set; }
public string TitleSrc { get; set; }
public DateTime DateSrc { get; set; }
public int? IdUserVerif { get; set; }
public string NameUser { get; set; }
public int? IdImg { get; set; }
public string ImgPath { get; set; }
public QuoteDto(int id_quote,string content,int likes,string langue,bool isValide,string? reason,int? id_caracter,string name_charac,int? id_source,string title,DateTime date,int? id_user_verif,string name_user ,int? id_img,string img_path)
{
this.Id = id_quote;
this.Content = content;
this.Likes = likes;
this.Langue = langue;
this.IsValide = isValide;
this.Reason = reason;
this.IdCaracter = id_caracter;
this.NameCharac = name_charac;
this.IdSource = id_source;
this.TitleSrc = title;
this.DateSrc = date;
this.IdUserVerif = id_user_verif;
this.NameUser = name_user;
this.IdImg = id_img;
this.ImgPath =img_path;
}
}
}

@ -0,0 +1,19 @@
using WF_WebAdmin.Model;
namespace WF_WebAdmin.Converter
{
public class QuoteExtension
{
public QuoteDto QuoteToDTO(Quote? q)
{
QuoteDto quote = new QuoteDto(q.Id, q.Content, q.Like, q.Langue, q.IsValid,null, null,q.Charac,null,q.TitleSrc,q.DateSrc,null,q.UserProposition,null,q.ImgPath);
return quote;
}
public Quote DTOToQuote(QuoteDto q)
{
Quote quote = new Quote(q.Id, q.Content,q.NameCharac,q.ImgPath,q.TitleSrc,q.DateSrc,q.Likes,q.Langue,q.NameUser,q.IsValide);
return quote;
}
}
}

@ -0,0 +1,24 @@
using WF_WebAdmin.Model;
namespace WF_WebAdmin.Converter
{
public class UserDto
{
public string Image { get; set; }
public string Name { get; set; }
public string Email { get; set; }
public DateTime DateCreation { get; set; }
public Boolean IsAdmin { get; set; }
public List<Commentary>? Comments { get; set; }
public UserDto(string image, string name, string email, DateTime dateCreation)
{
this.Image = image;
this.Name = name;
this.Email = email;
this.DateCreation = dateCreation;
}
}
}

@ -0,0 +1,19 @@
using WF_WebAdmin.Model;
namespace WF_WebAdmin.Converter
{
public class UserExtension
{
public User UserToDto(UserDto u)
{
var user = new User(u.Image, u.Name, u.Email, u.DateCreation,u.IsAdmin);
return user;
}
public UserDto DtoToUser(User u)
{
var user = new UserDto(u.Image ?? "default.png", u.Name ?? "Bob", u.Email ?? "bob@mail.com", u.DateCreation);
return user;
}
}
}

@ -0,0 +1,8 @@
namespace WF_WebAdmin.Model
{
public class Character
{
public int id_caracter { get; set; }
public string? caracter { get; set; }
}
}

@ -0,0 +1,12 @@
using System;
namespace WF_WebAdmin.Model
{
public class Commentary
{
public int Id { get; set; }
public int IdUser { get; set; }
public DateTime DateCreation { get; set; }
public string Text { get; set; } = string.Empty;
}
}

@ -0,0 +1,12 @@
namespace WF_WebAdmin.Model
{
public class DailyQuote
{
public int Id { get; set; }
public DailyQuote(int Id)
{
this.Id = Id;
}
}
}

@ -0,0 +1,24 @@
using Microsoft.AspNetCore.Components;
using Microsoft.Extensions.Configuration.UserSecrets;
using Microsoft.Extensions.Logging;
using Microsoft.VisualBasic;
using System;
using System.Diagnostics;
using System.Security.Claims;
using WF_WebAdmin.Pages;
using WF_WebAdmin.Service;
namespace WF_WebAdmin.Model
{
public static partial class LoggerSaveStub
{
public static void Log(ILogger? logs, LogLevel logLevel, string message, params object[] args)
{
ILogsService logsService = new LogsServiceStub();
logsService.addLogs(new Logs(logLevel, string.Format(message, args)));
logs.Log(logLevel, message, args);
}
}
}

@ -0,0 +1,14 @@
namespace WF_WebAdmin.Model
{
public class Logs
{
public LogLevel LogLevel { get; set; }
public string Message { get; set; }
public Logs(LogLevel logLevel , string message) {
this.LogLevel=logLevel;
this.Message=message;
}
}
}

@ -3,12 +3,27 @@ namespace WF_WebAdmin.Model
public class Quiz public class Quiz
{ {
public int Id { get; set; } public int Id { get; set; }
public string Question { get; set; } public string? Question { get; set; }
public string AnswerA { get; set; } public string AnswerA { get; set; }
public string AnswerB { get; set; } public string AnswerB { get; set; }
public string AnswerC { get; set; } public string AnswerC { get; set; }
public string AnswerD { get; set; } public string AnswerD { get; set; }
public string CAnswer { get; set; } public string CAnswer { get; set; }
public bool IsValid { get; set; }
public string UserProposition { get; set; } public string UserProposition { get; set; }
public Quiz(int id, string question, string answerA, string answerB, string answerC, string answerD, string cAnswer)
{
Id = id;
Question = question;
AnswerA = answerA;
AnswerB = answerB;
AnswerC = answerC;
AnswerD = answerD;
CAnswer = cAnswer;
IsValid = true;
UserProposition = "Admin";
}
} }
} }

@ -0,0 +1,30 @@
using System.ComponentModel.DataAnnotations;
namespace WF_WebAdmin.Model
{
public class QuizModel
{
[Required]
[StringLength(200, ErrorMessage = "La question ne peut pas depasser les 200 caractère.")]
public string? Question { get; set; }
[Required]
[StringLength(50, ErrorMessage = "La réponse ne peut pas depasser les 50 caractère.")]
public string? AnswerA { get; set; }
[Required]
[StringLength(50, ErrorMessage = "La réponse ne peut pas depasser les 50 caractère.")]
public string? AnswerB { get; set; }
[Required]
[StringLength(50, ErrorMessage = "La réponse ne peut pas depasser les 50 caractère.")]
public string? AnswerC { get; set; }
[Required]
[StringLength(50, ErrorMessage = "La réponse ne peut pas depasser les 50 caractère.")]
public string? AnswerD { get; set; }
[Required]
public string? CAnswer { get; set; }
}
}

@ -1,15 +1,33 @@
namespace WF_WebAdmin.Model using Microsoft.AspNetCore.DataProtection.KeyManagement;
namespace WF_WebAdmin.Model
{ {
public class Quote public class Quote
{ {
public int Id { get; set; } public int Id { get; set; }
public string Content { get; set; } public string Content { get; set; }
public int Like { get; set; }
public string Langue { get; set; }
public string Charac { get; set; } public string Charac { get; set; }
public string ImgPath { get; set; } public string ImgPath { get; set; }
public string TitleSrc { get; set; } public string TitleSrc { get; set; }
public DateTime DateSrc { get; set; } public DateTime DateSrc { get; set; }
public int Like { get; set; }
public string Langue { get; set; }
public string UserProposition { get; set; } public string UserProposition { get; set; }
public bool IsValid { get; set; }
public Quote(int id, string content, string charac, string imgPath, string titleSrc, DateTime dateSrc, int like, string langue, string userProposition, bool isvalid)
{
Id = id;
Content = content;
Charac = charac;
ImgPath = imgPath;
TitleSrc = titleSrc;
DateSrc = dateSrc;
Like = like;
Langue = langue;
UserProposition = userProposition;
IsValid = isvalid;
}
} }
} }

@ -0,0 +1,27 @@
using System.ComponentModel.DataAnnotations;
namespace WF_WebAdmin.Model
{
public class QuoteModel
{
public int Id { get; set; }
[Required]
[StringLength(300, ErrorMessage = "La citation ne peut pas dépasser les 300 caractère.")]
public string? Content { get; set; }
public int Like { get; set; }
[Required]
[StringLength(2, ErrorMessage = "La langue ne peut pas dépasser 2 caractère.")]
public string? Langue { get; set; }
public string? Charac { get; set; }
public string? ImgPath { get; set; }
public string? TitleSrc { get; set; }
public DateTime DateSrc { get; set; }
public string? UserProposition { get; set; }
public bool IsValid { get; set; }
}
}

@ -0,0 +1,11 @@
namespace WF_WebAdmin.Model
{
public class Source
{
public int id_source { get; set; }
public string? title { get; set; }
public int date { get; set; }
}
}

@ -3,10 +3,24 @@
public class User public class User
{ {
public int Id { get; set; } public int Id { get; set; }
public string Image { get; set; } public string? Image { get; set; }
public string Name { get; set; } public string? Name { get; set; }
public string Email { get; set; } public string? Email { get; set; }
public DateTime DateCreation { get; set; } public DateTime DateCreation { get; set; }
public Boolean IsAdmin { get; set; }
public List<Commentary>? Comments { get; set; }
public User(string image, string name, string email, DateTime dateCreation, bool isAdmin)
{
this.Image = image;
this.Name = name;
this.Email = email;
this.DateCreation = dateCreation;
IsAdmin = isAdmin;
}
public User() { }
} }
} }

@ -0,0 +1,22 @@
using System;
namespace WF_WebAdmin.Model
{
public class UserLogin
{
public int Id { get; set; }
public string? Image { get; set; }
public string? Name { get; set;}
public Boolean IsAdmin { get; set; }
public string? Mdp { get; set; }
public UserLogin(int id,string image, string name, bool isAdmin, string mdp)
{
Id = id;
this.Image = image;
this.Name = name;
this.IsAdmin = isAdmin;
this.Mdp = mdp;
}
public UserLogin() { }
}
}

@ -1,39 +1,32 @@
@page "/" @page "/"
@using WF_WebAdmin.Model
<PageTitle>Accueil</PageTitle> <PageTitle>Accueil</PageTitle>
<h1>Accueil</h1> <h2><strong>@Localizer["AccueilWelcome"] ?? "Bienvenue"</strong></h2>
<button>Mettre une citation aléatoire</button> <h4>@Localizer["AccueilTitle"]</h4>
@if (quotes != null) @if (Dailyquote != null)
{ {
<table class="table"> @foreach(var quote in Dailyquote)
<thead>
<tr>
<th>Id</th>
<th>Content</th>
<th>Charactére</th>
<th>Title Source</th>
<th>Like</th>
<th>Langue</th>
<th>Date Source</th>
</tr>
</thead>
<tbody>
@foreach (var quote in quotes)
{ {
<tr> <div class="QuoteDiv">
<td>@quote.Id</td> <img class="imgProfil" src="@quote.ImgPath" />
<td>@quote.Content</td> <p class ="pseudo"> @quote.Content</p>
<td>@quote.Charac</td>
<td>@quote.TitleSrc</td> <p class="pseudo"><strong>@Localizer["AccueilCharacter"]</strong> @quote.Charac</p>
<td>@quote.Like</td> <p class="pseudo"><strong>@Localizer["AccueilSrc"]</strong> @quote.TitleSrc</p>
<td>@quote.Langue</td>
<td>@quote.DateSrc.ToShortDateString()</td> </div>
</tr>
} }
</tbody>
</table>
} }
else
{
<p>@Localizer["AccueilNoQuote"]</p>
}
<h4>@Localizer["AccueilManualChange"]</h4>
<button @onclick="() => RandomDailyquote()">@Localizer["AccueilAddRandomQuote"]</button>

@ -0,0 +1,86 @@
using Blazorise.DataGrid;
using Microsoft.AspNetCore.Components;
using Microsoft.Extensions.Localization;
using System;
using System.Security.Claims;
using System.Text.Json;
using WF_WebAdmin.Model;
namespace WF_WebAdmin.Pages
{
public partial class Accueil
{
private Quote[]? Dailyquote;
[Inject]
public ILogger<Accueil>? Logger { get; set; }
[Inject]
public HttpClient? Http { get; set; }
[Inject]
public NavigationManager? NavigationManager { get; set; }
[Inject]
public IStringLocalizer<Accueil>? Localizer { get; set; }
/// <summary>
/// This method is called during the initialization of the Blazor component.
/// It is asynchronous and is used to load data or perform actions before the component is rendered.
/// </summary>
protected override async Task OnInitializedAsync()
{
var url = $"{NavigationManager.BaseUri}fake-dataDailyQuote.json";
try
{
var response = await Http.GetFromJsonAsync<Quote[]>(url);
Dailyquote = response ?? Array.Empty<Quote>(); // Assurer qu'on ne stocke pas null
}
catch (Exception ex)
{
Console.WriteLine($"Erreur lors du chargement des citations : {ex.Message}");
Dailyquote = Array.Empty<Quote>(); // Éviter une exception en cas d'erreur réseau
}
}
private async Task RandomDailyquote()
{
try
{
string _jsonFilePath = Path.Combine(Environment.CurrentDirectory, "wwwroot", "fake-dataDailyQuote.json");
Random random = new Random();
var response = await Http.GetFromJsonAsync<Quote[]>($"{NavigationManager.BaseUri}fake-dataQuote.json");
Quote[] quotes = response ?? Array.Empty<Quote>(); // Empêche null
if (quotes.Length > 0)
{
Dailyquote = new Quote[] { quotes.OrderBy(x => random.Next()).First() };
}
else
{
Console.WriteLine("Aucune citation disponible dans le fichier JSON.");
return;
}
var json = JsonSerializer.Serialize(Dailyquote, new JsonSerializerOptions { WriteIndented = true });
await File.WriteAllTextAsync(_jsonFilePath, json);
if (Logger != null)
{
LoggerSaveStub.Log(Logger, LogLevel.Information, "Random change of quote of the day");
}
else
{
Console.WriteLine("Logger non initialisé.");
}
}
catch (Exception ex)
{
Console.WriteLine($"Erreur dans RandomDailyquote: {ex.Message}");
}
}
}
}

@ -0,0 +1,58 @@
@using WF_WebAdmin.Model;
@page "/add"
<h3>@Localizer["TitleAddQuiz"]</h3>
<EditForm Model="@_quizModel" OnValidSubmit="@HandleValidSubmit">
<DataAnnotationsValidator />
<ValidationSummary />
<p>
<label for="display-quest">
@Localizer["TitleQuestion"]
<InputText id="display-quest" @bind-Value="_quizModel.Question" />
</label>
</p>
<p>
<label for="display-a">
@Localizer["AnswerA"]
<InputText id="display-a" @bind-Value="_quizModel.AnswerA" />
</label>
</p>
<p>
<label for="display-b">
@Localizer["AnswerB"]
<InputText id="display-b" @bind-Value="_quizModel.AnswerB" />
</label>
</p>
<p>
<label for="display-c">
@Localizer["AnswerC"]
<InputText id="display-c" @bind-Value="_quizModel.AnswerC" />
</label>
</p>
<p>
<label for="display-d">
@Localizer["AnswerD"]
<InputText id="display-d" @bind-Value="_quizModel.AnswerD" />
</label>
</p>
<p>
<label for="cA">
@Localizer["GoodAnswer"]
<input name="cA" type="radio" @onchange="@(e => OnCAwnserChange("A"))" /> A
<input name="cA" type="radio" @onchange="@(e => OnCAwnserChange("B"))" /> B
<input name="cA" type="radio" @onchange="@(e => OnCAwnserChange("C"))" /> C
<input name="cA" type="radio" @onchange="@(e => OnCAwnserChange("D"))" /> D
</label>
</p>
<button type="submit">@Localizer["Submit"]</button>
</EditForm>

@ -0,0 +1,128 @@
using Microsoft.AspNetCore.Components;
using WF_WebAdmin.Service;
using WF_WebAdmin.Model;
using Microsoft.AspNetCore.Mvc;
using System.Text.RegularExpressions;
using Microsoft.Extensions.Localization;
using Microsoft.Extensions.Logging;
using System.Security.Claims;
namespace WF_WebAdmin.Pages
{
public partial class AddQuiz
{
[Inject]
public ILogger<AddQuiz>? Logger { get; set; }
[Inject]
public IStringLocalizer<AddQuiz>? Localizer { get; set; }
[Inject]
private IQuizService? QuizService { get; set; }
[Inject]
public NavigationManager? NavigationManager { get; set; }
private readonly QuizModel _quizModel = new();
/// <summary>
/// Handles the valid submission of a quiz form.
/// This method is triggered when the form is successfully validated and the user submits the quiz data.
/// It retrieves the current quiz count, increments it, and then adds a new quiz entry to the quiz service.
/// Finally, it navigates to the "modifquiz" page.
/// </summary>
private async Task HandleValidSubmit()
{
// Declare a variable to hold the ID of the new quiz.
int id;
// Get the current number of quizzes from the quiz service.
id = await QuizService.getNbQuiz();
// Increment the quiz ID for the new quiz.
id++;
// Create a new quiz and add it using the quiz service.
LoggerSaveStub.Log(Logger, LogLevel.Information, $"Creation of the {_quizModel.Question} question");
await QuizService.addQuiz(new Quiz(
id, // New quiz ID
ValidateInformation(_quizModel.Question), // Validated question
ValidateInformation(_quizModel.AnswerA), // Validated answer A
ValidateInformation(_quizModel.AnswerB), // Validated answer B
ValidateInformation(_quizModel.AnswerC), // Validated answer C
ValidateInformation(_quizModel.AnswerD), // Validated answer D
ValidateReponse(_quizModel.CAnswer) // Validated correct answer
));
// Navigate to the "modifquiz" page after adding the quiz.
NavigationManager.NavigateTo("modifquiz");
}
/// <summary>
/// Handles the change of the correct answer for the quiz.
/// This method is triggered when the user selects or changes the correct answer for the quiz question.
/// It updates the QuizModel's Correct Answer property with the selected answer.
/// </summary>
/// <param name="item">The selected answer that will be marked as the correct answer.</param>
/// <param name="checkedValue">The value of the selected option, typically used for validation or additional logic.</param>
private void OnCAwnserChange(string item)
{
// Update the correct answer in the QuizModel with the selected answer.
_quizModel.CAnswer = item;
}
/// <summary>
/// Validates the provided string item.
/// This method is used to validate input data, but the validation logic is not yet implemented.
/// </summary>
/// <param name="item">The string input to be validated.</param>
/// <returns>
/// Returns the input string as it is for now. The validation logic is yet to be implemented.
/// </returns>
private string ValidateInformation(string? item)
{
return string.IsNullOrWhiteSpace(item) ? "Valeur par défaut" : item;
}
/// <summary>
/// Validates the provided answer item (A, B, C, or D) for the quiz.
/// This method ensures that the input corresponds to one of the allowed values for the correct answer.
/// If the input is invalid or null, it throws an exception and returns a default value ("A") in case of error.
/// </summary>
/// <param name="item">The answer item (A, B, C, or D) to be validated.</param>
/// <returns>
/// Returns the input item if valid (A, B, C, or D). If the item is invalid or null, it returns a default value ("A").
/// </returns>
private static string ValidateReponse(string item)
{
// Check if the item is null or empty
if (string.IsNullOrEmpty(item))
{
// Throw exception if the item is null or empty
throw new ArgumentNullException(nameof(item), "The item cannot be null or empty.");
}
// Validate that the item is one of the allowed values: A, B, C, or D
switch (item)
{
case "A":
case "B":
case "C":
case "D":
// Valid values, no action needed
break;
default:
// Throw exception if the item is not one of the allowed answers
throw new InvalidDataException($"Invalid item '{item}' provided. Item must be one of: A, B, C, or D.");
}
// Return the validated item
return item;
}
}
}

@ -0,0 +1,37 @@
@page "/commentary-chart"
<h1>Nombre de commentaires par mois</h1>
<MudChart ChartType="ChartType.Bar" ChartSeries="@Series" @bind-SelectedIndex="Index" LegendPosition="Position.Bottom" XAxisLabels="@XAxisLabels" Width="100%" Height="350px"></MudChart>
@code {
private int Index = -1;
private List<ChartSeries> Series = new();
private string[] XAxisLabels = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
[Inject] private WF_WebAdmin.Service.ICommentaryService CommentaryService { get; set; } = default!;
protected override async Task OnInitializedAsync()
{
var comments = await CommentaryService.GetCommentsAsync();
var groupedData = comments.GroupBy(c => c.DateCreation.Month)
.OrderBy(g => g.Key)
.Select(g => new { Month = g.Key - 1, Value = g.Count() })
.ToList();
double[] data = new double[12];
foreach (var item in groupedData)
{
data[item.Month] = item.Value;
}
Series = new List<ChartSeries>
{
new ChartSeries
{
Name = "",
Data = data
}
};
}
}

@ -1,45 +1,118 @@
@page "/deleteuser" @page "/deleteuser"
@using WF_WebAdmin.Model
<PageTitle>Gestion utilisateur</PageTitle> <PageTitle>Gestion utilisateur</PageTitle>
<h3>Gestion des utilisateurs</h3> <h3>@Localizer["TitleUser"]</h3>
@if(_users == null)
{
<p><strong>@Localizer["UserNobody"]</strong></p>
}
@if (users != null) else
{ {
<p>Utilisateurs présents:</p> <DataGrid TItem="User"
@foreach (var user in users) Data="@_users"
PageSize="@MaxValue"
ReadData="@OnReadData"
TotalItems="@_totalItem"
ShowPager
Responsive>
<DataGridColumn TItem="User" Field="@nameof(User.Id)" Caption="Id" />
<DataGridColumn TItem="User" Field="@nameof(User.IsAdmin)" Caption="Admin" />
<DataGridColumn TItem="User" Field="@nameof(User.Name)" Caption="Nom" />
<DataGridColumn TItem="User" Field="@nameof(User.Email)" Caption="Email" />
<DataGridColumn TItem="User" Field="@nameof(User.DateCreation)" Caption="Date de création"/>
</DataGrid>
<p>@Localizer["UserHere"]</p>
@foreach (var user in _users)
{ {
<div class="userDiv"> <div class="userDiv" id="@user.Id">
<img class="imgProfil" src="@user.Image" /> <img class="imgProfil" src="@user.Image" />
<p class="idUser"><strong>Identifiant d'utilisateur :</strong> @user.Id</p> @if (user.IsAdmin)
<p class="pseudo"><strong>Nom d'utilisateur :</strong> @user.Name</p> {
<p class="mail"><strong>Email de l'utilisateur :</strong> @user.Email</p>
<p class="dateCrea"><strong>Date de création de l'utilisateur :</strong> @user.DateCreation.ToShortDateString()</p> <p class="pseudo"><strong>@Localizer["UserName"]</strong> @user.Name <strong>(@Localizer["UserAdmin"])</strong></p>
<button id="DeleteButton" @onclick="() => ShowConfirmation(user)">Supprimer l'utilisateur</button> }
else
{
<p class="pseudo"><strong>@Localizer["UserName"]</strong> @user.Name</p>
}
<p class="mail"><strong>@Localizer["UserEmail"]</strong> @user.Email</p>
<p class="dateCrea"><strong>@Localizer["UserDate"]</strong> @user.DateCreation.ToShortDateString()</p>
@if(user.Comments != null)
{
<p class="titleComments"><strong>▶ @Localizer["UserComment"] @user.Name : </strong></p>
@foreach (var comment in user.Comments)
{
<p class="comments">@comment.DateCreation.ToShortDateString() - @comment.Text</p>
}
}
else
{
<p><i>@Localizer["UserNoComment"]</i></p>
}
<button id="ModifyButton" @onclick="() => ShowModifyConfirmation(user)">Modifier l'utilisateur</button>
<button id="DeleteButton" @onclick="() => ShowConfirmation(user)">@Localizer["UserDelete"]</button>
@if (!user.IsAdmin)
{
<button id="AdminButton" @onclick="() => ShowConfirmationAdmin(user)">@Localizer["UserAddAdmin"]</button>
}
else
{
<button id="AdminButton" @onclick="() => ShowConfirmationAdmin(user)">@Localizer["UserDeleteAdmin"]</button>
}
</div>
<!-- Fenêtre de confirmation de suppression -->
@if (_showPopupDelete)
{
<div class="divPopup">
<div class="contentPopup">
<p>@Localizer["UserPopupTitle"]</p>
<button @onclick="() => RemoveUser()">@Localizer["UserConfirmButton"]</button>
<button @onclick="ClosePopup">@Localizer["UserDeleteButton"]</button>
</div>
</div> </div>
} }
<!-- Fenêtre de confirmation --> @if (_showModifyPopup)
@if (showPopup)
{ {
<div class="divPopup"> <div class="divPopup">
<div class="contentPopup"> <div class="contentPopup">
<p>Êtes-vous sûr de vouloir supprimer cet utilisateur ?</p> <p>Modifier les informations de l'utilisateur :</p>
<button @onclick="() => RemoveUser()">Confirmer</button> <label>Nom d'utilisateur:</label>
<input type="text" @bind="_selectedUser.Name"/>
<label>Email:</label>
<input type="email" @bind="_selectedUser.Email" />
<label>Image:</label>
<input type="text" @bind="_selectedUser.Image" />
<button @onclick="ModifyUser">Sauvegarder</button>
<button @onclick="ClosePopup">Annuler</button> <button @onclick="ClosePopup">Annuler</button>
</div> </div>
</div> </div>
} }
}
else
{
<p><strong>Aucun utilisateurs présents sur le site</strong></p>
} }
<!-- Fenêtre de confirmation d'ajout admin-->
@if (_showPopupAdmin)
{
<div class="divPopup">
<div class="contentPopup">
<p>@Localizer["UserPopupTitle2"]</p>
<button @onclick="() => setAdmin()">@Localizer["UserConfirmButton"]</button>
<button @onclick="ClosePopup">@Localizer["UserDeleteButton"]</button>
</div>
</div>
}
@code {
} }

@ -1,52 +1,216 @@
using Microsoft.AspNetCore.Components; using Blazorise.DataGrid;
using Microsoft.AspNetCore.Components;
using Microsoft.Extensions.Configuration.UserSecrets; using Microsoft.Extensions.Configuration.UserSecrets;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Localization;
using System.Collections.Generic;
using WF_WebAdmin.Model; using WF_WebAdmin.Model;
using WF_WebAdmin.Service;
namespace WF_WebAdmin.Pages namespace WF_WebAdmin.Pages
{ {
public partial class DeleteUser public partial class DeleteUser
{ {
private List<User> users; [Inject]
public ILogger<DeleteUser>? Logger { get; set; }
private List<User>? _users;
private bool _showModifyPopup = false;
private User? _userToDelete = null;
private User? _selectedUser;
private bool _showPopupDelete = false;
private bool _showPopupAdmin = false;
private User? _userToAdmin = null;
private const int MaxValue = 5;
private int _totalItem;
private int _page = 1;
private bool showPopup = false;
private User userToDelete = null;
[Inject] [Inject]
public HttpClient Http { get; set; } public HttpClient? Http { get; set; }
[Inject] [Inject]
public NavigationManager NavigationManager { get; set; } public NavigationManager? NavigationManager { get; set; }
[Inject]
private IUserService? UserService { get; set; }
[Inject]
public IStringLocalizer<DeleteUser>? Localizer { get; set; }
/// <summary>
/// This method is called when the component is initialized.
/// It is an asynchronous method that retrieves a list of users from the user service.
/// The method fetches a subset of users with a specified maximum value and page number (1 in this case).
/// </summary>
protected override async Task OnInitializedAsync() protected override async Task OnInitializedAsync()
{ {
users = await Http.GetFromJsonAsync<List<User>>($"{NavigationManager.BaseUri}fake-dataUser.json"); // Retrieve a list of users using the user service. The number of users and page number are specified.
// MaxValue determines how many users to retrieve, and '1' refers to the first page of results.
_users = await UserService.getSomeUser(MaxValue, 1);
}
/// <summary>
/// Handles the event when data is read in the data grid.
/// This method is triggered during pagination or when data is loaded into the grid.
/// It asynchronously fetches a page of users based on the requested page size and page number,
/// and updates the list of users and total item count if the operation is not cancelled.
/// </summary>
/// <param name="e">The event arguments containing pagination details (page size and page number) and a cancellation token.</param>
private async Task OnReadData(DataGridReadDataEventArgs<User> e)
{
// If the cancellation token is requested, exit the method without processing the request.
if (e.CancellationToken.IsCancellationRequested)
{
return;
} }
// Fetch a page of users from the user service using the page size and page number provided by the event arguments.
var response = await UserService.getSomeUser(e.PageSize, e.Page);
// If the operation is not cancelled, update the total number of users and the list of users.
if (!e.CancellationToken.IsCancellationRequested)
{
_totalItem = await UserService.getNbUser(); // Get the total number of users
_users = new List<User>(response.ToArray()); // Store the retrieved users in the users list
_page = e.Page; // Update the current page number
}
}
// ------- Popup remove user -------
private void ShowConfirmation(User user) /// <summary>
/// Displays a confirmation popup to confirm the deletion of a user.
/// This method is triggered when the user intends to delete a user,
/// and it sets the user to be deleted and shows the confirmation popup.
/// </summary>
/// <param name="user">The user to be deleted, which is passed to the method for confirmation.</param>
private void ShowConfirmation(User? user)
{ {
// Afficher la modale et mémoriser l'utilisateur à supprimer // Set the user to be deleted and show the confirmation popup.
userToDelete = user; _userToDelete = user; // Store the user to be deleted in a variable
showPopup = true; _showPopupDelete = true; // Display the confirmation popup
} }
/// <summary>
/// Displays a confirmation popup for modifying a user's information.
/// This method is triggered when the user intends to modify a specific user's data,
/// and it sets the selected user and shows the modification confirmation popup.
/// </summary>
/// <param name="user">The user whose information is to be modified, passed to the method for confirmation.</param>
private void ShowModifyConfirmation(User? user)
{
// Set the selected user and show the modification confirmation popup.
_selectedUser = user; // Store the user to be modified
_showModifyPopup = true; // Display the confirmation popup for modification
}
/// <summary>
/// Removes the specified user from the system.
/// This method is triggered when the user confirms the deletion of a user.
/// It calls the user service to remove the user, closes the confirmation popup,
/// and then refreshes the list of users by fetching the updated data.
/// </summary>
private async Task RemoveUser() private async Task RemoveUser()
{ {
if (userToDelete != null) // Check if there is a user to delete
if (_userToDelete != null)
{ {
users.RemoveAll(u => u.Id == userToDelete.Id); // Remove the selected user from the system using the user service
LoggerSaveStub.Log(Logger, LogLevel.Information, $"Delete user {_userToDelete.Name}");
await UserService.removeUser(_userToDelete);
// Close the confirmation popup after the deletion
ClosePopup(); ClosePopup();
// Refresh the list of users by fetching the updated data from the user service
var response = await UserService.getSomeUser(MaxValue, _page);
// Update the users list with the latest data
_users = new List<User>(response.ToArray());
} }
} }
/// <summary>
/// Modifies the selected user's information.
/// This method is triggered when the user confirms the modification of a user's details.
/// It calls the user service to update the user's information and then closes the modification popup.
/// </summary>
private async Task ModifyUser()
{
// Update the selected user's information using the user service
LoggerSaveStub.Log(Logger, LogLevel.Information, $"Modification of user {_selectedUser.Name}");
await UserService.updateUser(_selectedUser);
// Close the modification popup after the update is complete
ClosePopup();
}
/// <summary>
/// Closes all open popups in the UI by setting their visibility flags to false.
/// This method is typically called after an action (like deleting or modifying a user)
/// to hide any active popups and reset the UI state.
/// </summary>
private void ClosePopup() private void ClosePopup()
{ {
showPopup = false; // Set all popup visibility flags to false to hide the popups
_showModifyPopup = false; // Close the modify confirmation popup
_showPopupDelete = false; // Close any additional delete popups
_showPopupAdmin = false; // Close the admin-related popup (if any)
}
// ------- Popup admin -------
/// <summary>
/// Displays a confirmation popup to confirm the promotion of a user to admin status.
/// This method is triggered when the user intends to promote a specific user to admin.
/// It sets the selected user to be promoted and shows the confirmation popup for admin promotion.
/// </summary>
/// <param name="user">The user to be promoted to admin, passed to the method for confirmation.</param>
private void ShowConfirmationAdmin(User? user)
{
// Set the user to be promoted to admin and show the confirmation popup.
_userToAdmin = user; // Store the user to be promoted
_showPopupAdmin = true; // Display the confirmation popup for admin promotion
}
/// <summary>
/// Toggles the admin status of the selected user.
/// This method checks the current admin status of the user, and if the user is not an admin,
/// it promotes them to admin. If the user is already an admin, it demotes them.
/// After the change, the user's information is updated, and the confirmation popup is closed.
/// </summary>
private async Task setAdmin()
{
// Check if the user is not already an admin
if (!_userToAdmin.IsAdmin)
{
// Promote the user to admin
LoggerSaveStub.Log(Logger, LogLevel.Information, $"User {_userToAdmin.Name} is now administrator");
_userToAdmin.IsAdmin = true;
await UserService.updateUser(_userToAdmin); // Update the user status in the service
ClosePopup(); // Close the confirmation popup
}
else
{
// Demote the user from admin to normal user
LoggerSaveStub.Log(Logger, LogLevel.Information, $"User {_userToAdmin.Name} is no longer an administator");
_userToAdmin.IsAdmin = false;
await UserService.updateUser(_userToAdmin); // Update the user status in the service
ClosePopup(); // Close the confirmation popup
} }
} }
}
} }

@ -0,0 +1,48 @@
@using WF_WebAdmin.Model
@page "/edit/{Id:int}"
<h3>Editer</h3>
<EditForm Model="@_quoteModel" OnValidSubmit="@HandleValidSubmit">
<DataAnnotationsValidator />
<ValidationSummary />
<p>
<label for="display-cit">
Citation:
<InputText id="display-cit" @bind-Value="_quoteModel.Content" />
</label>
</p>
<p>
<label for="lang">
Langue:
<input name="lang" type="radio" @onchange="@(e => OnlangChange("fr"))" /> fr
<input name="lang" type="radio" @onchange="@(e => OnlangChange("en"))" /> en
</label>
</p>
<p>
<label for="charac">
<InputSelect id="charac" @bind-Value="_quoteModel.Charac">
@foreach (Character display in _charac)
{
<option value="@display.caracter">@display.caracter (ID: @display.id_caracter)</option>
}
</InputSelect>
</label>
</p>
<p>
<label for="src">
<InputSelect id="src" @bind-Value="_quoteModel.TitleSrc">
@foreach (Source display in _src)
{
<option value="@display.title">@display.title (ID: @display.id_source)</option>
}
</InputSelect>
</label>
</p>
<button type="submit">Submit</button>
</EditForm>

@ -0,0 +1,107 @@
using Microsoft.AspNetCore.Components;
using System.Security.Claims;
using WF_WebAdmin.Model;
using WF_WebAdmin.Service;
namespace WF_WebAdmin.Pages
{
public partial class Edit
{
[Parameter]
public int Id { get; set; }
[Inject]
public ILogger<Edit>? Logger { get; set; }
[Inject]
private IQuoteService? quoteService { get; set; }
[Inject]
public NavigationManager? NavigationManager { get; set; }
private Quote? Q { get; set; }
private QuoteModel _quoteModel = new();
private List<Character> _charac = new List<Character>();
private List<Source> _src = new List<Source>();
/// <summary>
/// Asynchronously initializes the component by loading data related to a quote.
/// This method fetches a specific quote based on the provided ID and populates the `quoteModel`
/// with the quote's content, language, character, source, and other associated data.
/// It also loads additional data such as character and source information for the quote.
/// </summary>
protected override async Task OnInitializedAsync()
{
// Fetch the quote data based on the provided ID.
Q = await quoteService.getOnequote(Id);
// Populate the quoteModel with the data from the retrieved quote.
_quoteModel.Content = Q.Content;
_quoteModel.Langue = Q.Langue;
_quoteModel.Charac = Q.Charac;
_quoteModel.TitleSrc = Q.TitleSrc;
_quoteModel.Id = Q.Id;
_quoteModel.Like = Q.Like;
_quoteModel.ImgPath = Q.ImgPath;
_quoteModel.DateSrc = Q.DateSrc;
_quoteModel.UserProposition = Q.UserProposition;
_quoteModel.IsValid = Q.IsValid;
// Fetch additional data related to the quote, such as character and source.
_charac = await quoteService.getChar();
_src = await quoteService.getSrc();
}
/// <summary>
/// Handles the submission of a valid form for updating a quote.
/// This method takes the data from `quoteModel`, updates the selected quote (`q`) with the new values,
/// and then calls the `quoteService.updateQuote` method to persist the changes.
/// After updating, it navigates to the "modifquote" page.
/// </summary>
protected async Task HandleValidSubmit()
{
if (Q == null)
{
LoggerSaveStub.Log(Logger, LogLevel.Error, "Quote is null.");
return;
}
// Update the properties of the selected quote (`q`) with the data from `quoteModel`.
LoggerSaveStub.Log(Logger, LogLevel.Information, $"Editing the quote {Q.Content}");
Q.Content = _quoteModel.Content ?? "Content";
Q.Langue = _quoteModel.Langue ?? "EN";
Q.TitleSrc = _quoteModel.TitleSrc ?? "Something";
Q.Charac = _quoteModel.Charac ?? "Someone";
// Call the quote service to update the quote in the data source.
await quoteService.updateQuote(Q);
// Navigate to the "modifquote" page after updating the quote.
NavigationManager.NavigateTo("modifquote");
}
/// <summary>
/// Handles the language change event for the quote.
/// This method updates the `Langue` property of the `quoteModel` based on the selected language (`item`).
/// It only accepts "fr" (French) or "en" (English) as valid language options.
/// </summary>
/// <param name="item">The selected language ("fr" or "en") passed to the method.</param>
/// <param name="checkedValue">The checked value (unused in this method but may be used for other purposes).</param>
private void OnlangChange(string item)
{
// Check if the selected language is either "fr" or "en"
if (item == "fr" || item == "en")
{
// Update the Langue property of the quoteModel with the selected language
_quoteModel.Langue = item;
}
}
}
}

@ -7,7 +7,7 @@
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" /> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<title>Error</title> <title>error</title>
<link href="~/css/bootstrap/bootstrap.min.css" rel="stylesheet" /> <link href="~/css/bootstrap/bootstrap.min.css" rel="stylesheet" />
<link href="~/css/site.css" rel="stylesheet" asp-append-version="true" /> <link href="~/css/site.css" rel="stylesheet" asp-append-version="true" />
</head> </head>
@ -27,12 +27,12 @@
<h3>Development Mode</h3> <h3>Development Mode</h3>
<p> <p>
Swapping to the <strong>Development</strong> environment displays detailed information about the error that occurred. Swapping to the <strong>development</strong> environment displays detailed information about the error that occurred.
</p> </p>
<p> <p>
<strong>The Development environment shouldn't be enabled for deployed applications.</strong> <strong>The Development environment shouldn't be enabled for deployed applications.</strong>
It can result in displaying sensitive information from exceptions to end users. It can result in displaying sensitive information from exceptions to end users.
For local debugging, enable the <strong>Development</strong> environment by setting the <strong>ASPNETCORE_ENVIRONMENT</strong> environment variable to <strong>Development</strong> For local debugging, enable the <strong>development</strong> environment by setting the <strong>ASPNETCORE_ENVIRONMENT</strong> environment variable to <strong>Development</strong>
and restarting the app. and restarting the app.
</p> </p>
</div> </div>

@ -6,6 +6,7 @@ namespace WF_WebAdmin.Pages
{ {
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)] [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
[IgnoreAntiforgeryToken] [IgnoreAntiforgeryToken]
public class ErrorModel : PageModel public class ErrorModel : PageModel
{ {
public string? RequestId { get; set; } public string? RequestId { get; set; }
@ -14,13 +15,26 @@ namespace WF_WebAdmin.Pages
private readonly ILogger<ErrorModel> _logger; private readonly ILogger<ErrorModel> _logger;
/// <summary>
/// Initializes a new instance of the <see cref="ErrorModel"/> class.
/// This constructor is used to inject the <see cref="ILogger{ErrorModel}"/> into the model for logging purposes.
/// </summary>
/// <param name="logger">An instance of the <see cref="ILogger{ErrorModel}"/> used for logging error-related information.</param>
public ErrorModel(ILogger<ErrorModel> logger) public ErrorModel(ILogger<ErrorModel> logger)
{ {
_logger = logger; _logger = logger;
} }
/// <summary>
/// Handles the GET request for the page or endpoint.
/// This method retrieves the request ID for tracing purposes, using the `Activity.Current?.Id`
/// if it's available, or the `HttpContext.TraceIdentifier` as a fallback if no current activity ID is present.
/// </summary>
public void OnGet() public void OnGet()
{ {
// Retrieve the current request ID for tracing
RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier; RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier;
} }
} }

@ -0,0 +1,31 @@
@page "/login"
@using WF_WebAdmin.Model
@using System.Globalization
<h1>▶@Localizer["LoginTitle"]◀</h1>
<div class="login">
<EditForm Model="userLogin" OnValidSubmit="validlogin">
<DataAnnotationsValidator />
<ValidationSummary />
<label for="name"><strong>@Localizer["LoginId"]*</strong></label>
<InputText @bind-Value="userLogin.Name" id="name" placeholder="@Localizer["LoginEnterPseudo"]" class="connexion" required />
<label for="mdp">
<strong>@Localizer["LoginPassWd"]*</strong></label>
<InputText @bind-Value="@userLogin.Mdp" type="password" placeholder="@Localizer["LoginEnterPassWd"]" class="connexion" required />
<div class="buttonSubmitDiv">
<button class="buttonSudmite" type="submit">@Localizer["LoginConnexion"]</button>
</div>
<p class="ErrorMsg"><i>@ErrorConnexion</i></p>
</EditForm>
</div>
<p><i>Indice de connexion : admin / admin</i></p>
@code {
}

@ -0,0 +1,88 @@
using Microsoft.AspNetCore.Components;
using Microsoft.Extensions.Configuration.UserSecrets;
using Microsoft.Extensions.Localization;
using WF_WebAdmin.Model;
namespace WF_WebAdmin.Pages
{
public partial class Login
{
[Inject]
public IStringLocalizer<Login> Localizer { get; set; }
private UserLogin userLogin = new UserLogin();
[Inject]
public UserLogin uLogin { get; set; }
private string ErrorConnexion;
private List<UserLogin> usersConnexion;
[Inject]
public HttpClient Http { get; set; }
[Inject]
public NavigationManager NavigationManager { get; set; }
/// <summary>
/// Asynchronously initializes the component by loading user login data.
/// This method retrieves a list of user login information from a JSON file located at the specified URI
/// and populates the `usersConnexion` list with the data.
/// </summary>
protected override async Task OnInitializedAsync()
{
// Fetch user login data from the specified JSON file.
usersConnexion = await Http.GetFromJsonAsync<List<UserLogin>>($"{NavigationManager.BaseUri}fake-dataUserLogin.json");
}
/// <summary>
/// Validates the login credentials of the user.
/// This method checks if the provided username and password match any user in the `usersConnexion` list.
/// If the credentials are correct and the user is an admin, it stores the user details and navigates to the home page.
/// If the credentials are incorrect, an error message is set for display.
/// </summary>
public void validlogin()
{
// Check if both the username and password are provided
if (!string.IsNullOrEmpty(userLogin.Name) || !string.IsNullOrEmpty(userLogin.Mdp))
{
// Loop through the list of connected users to find a match
foreach (var user in usersConnexion)
{
// Check if the username and password match the user credentials
if (userLogin.Name == user.Name && userLogin.Mdp == user.Mdp)
{
// Check if the user is an admin
if (user.IsAdmin)
{
// If the user is an admin, store their information and navigate to the home page
uLogin.Id = userLogin.Id;
uLogin.Name = user.Name;
uLogin.Image = user.Image;
// Redirect to the homepage
NavigationManager.NavigateTo(NavigationManager.BaseUri + "accueil");
return;
}
else
{
// If the user is not an admin, display an error message
ErrorConnexion = "Connexion échouée, le nom ou le mot de passe sont incorrectes";
}
}
else
{
// If credentials do not match, set the error message
ErrorConnexion = "Connexion échouée, le nom ou le mot de passe sont incorrectes";
}
}
}
}
}
}

@ -0,0 +1,31 @@
@page "/logs"
<h3>@Localizer["LogTitle"]</h3>
@if (logs is null)
{
<p>@Localizer["NotLog"]</p>
}
else
{
<p>@Localizer["Log"]</p>
<table>
<thead>
<tr>
<th>@Localizer["LogLvl"]</th>
<th>@Localizer["LogContent"]</th>
</tr>
</thead>
<tbody>
@foreach (var log in logs)
{
<tr>
<td>@log.LogLevel</td>
<td>@log.Message</td>
</tr>
}
</tbody>
</table>
}

@ -1,12 +1,12 @@
using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components;
using Microsoft.Extensions.Localization;
using WF_WebAdmin.Model; using WF_WebAdmin.Model;
namespace WF_WebAdmin.Pages namespace WF_WebAdmin.Pages
{ {
public partial class Accueil public partial class LogsPage
{ {
private Quote[] quotes; private Logs[] logs;
[Inject] [Inject]
public HttpClient Http { get; set; } public HttpClient Http { get; set; }
@ -14,9 +14,12 @@ namespace WF_WebAdmin.Pages
[Inject] [Inject]
public NavigationManager NavigationManager { get; set; } public NavigationManager NavigationManager { get; set; }
[Inject]
public IStringLocalizer<LogsPage> Localizer { get; set; }
protected override async Task OnInitializedAsync() protected override async Task OnInitializedAsync()
{ {
quotes = await Http.GetFromJsonAsync<Quote[]>($"{NavigationManager.BaseUri}fake-dataQuote.json"); logs = await Http.GetFromJsonAsync<Logs[]>($"{NavigationManager.BaseUri}fake_data_logs.json");
} }
} }
} }

@ -0,0 +1,69 @@
@using WF_WebAdmin.Model
@page "/modifquiz"
<PageTitle>@Localizer["TitlePage"]</PageTitle>
<h3>@Localizer["TitlePage"]</h3>
<div>
<NavLink class="btn btn-primary" href="Add" Match="NavLinkMatch.All">
<i class="fa fa-plus"></i> @Localizer["Add"]
</NavLink>
</div>
<DataGrid TItem="Quiz"
Data="@quiz"
PageSize="@MaxValue"
ReadData="@OnReadData"
TotalItems="@totalItem"
ShowPager
Responsive>
<DataGridColumn TItem="Quiz" Field="@nameof(Quiz.Id)" Caption="@Localizer["Id"]" />
<DataGridColumn TItem="Quiz" Field="@nameof(Quiz.Question)" Caption="@Localizer["Question"]" />
<DataGridColumn TItem="Quiz" Field="@nameof(Quiz.AnswerA)" Caption="@Localizer["AnswerA"]" />
<DataGridColumn TItem="Quiz" Field="@nameof(Quiz.AnswerB)" Caption="@Localizer["AnswerB"]" />
<DataGridColumn TItem="Quiz" Field="@nameof(Quiz.AnswerC)" Caption="@Localizer["AnswerC"]" />
<DataGridColumn TItem="Quiz" Field="@nameof(Quiz.AnswerD)" Caption="@Localizer["AnswerD"]" />
<DataGridColumn TItem="Quiz" Field="@nameof(Quiz.CAnswer)" Caption="@Localizer["GoodAnswer"]" />
<DataGridColumn TItem="Quiz" Field="@nameof(Quiz.Id)" Caption="@Localizer["Action"]">
<DisplayTemplate>
<button type="button" class="btn btn-primary" @onclick="() => OnEditButtonClicked(context)"><i class="fa fa-edit"></i> @Localizer["Edit"]</button>
<button type="button" class="btn btn-primary" @onclick="() => OnDelete(context)"><i class="fa fa-trash"></i> @Localizer["Delete"]</button>
</DisplayTemplate>
</DataGridColumn>
</DataGrid>
@if (showEditQuiz && selectedQuiz != null)
{
<div class="divPopup">
<div class="contentPopup">
<p>@Localizer["ModifInfoUser"]</p>
<label>@Localizer["Question"]</label>
<input type="text" @bind="selectedQuiz.Question"/>
<label>@Localizer["AnswerA"]</label>
<input type="text" @bind="selectedQuiz.AnswerA" />
<label>@Localizer["AnswerB"]</label>
<input type="text" @bind="selectedQuiz.AnswerB" />
<label>@Localizer["AnswerC"]</label>
<input type="text" @bind="selectedQuiz.AnswerC" />
<label>@Localizer["AnswerD"]</label>
<input type="text" @bind="selectedQuiz.AnswerD" />
<label>@Localizer["GoodAnswer"]</label>
<input type="text" @bind="selectedQuiz.CAnswer" />
<button @onclick="EditQuiz">@Localizer["Save"] </button>
<button @onclick="ClosePopup">@Localizer["Delete"]</button>
</div>
</div>
}
@if (showPopupDelete)
{
<div class="divPopup">
<div class="contentPopup">
<p>@Localizer["PopupQuestion"]</p>
<button @onclick="RemoveQuote">@Localizer["Yes"]</button>
<button @onclick="ClosePopup">@Localizer["Cancel"]</button>
</div>
</div>
}

@ -0,0 +1,162 @@
using Blazorise.DataGrid;
using Microsoft.AspNetCore.Components;
using Microsoft.Extensions.Localization;
using System.Security.Claims;
using WF_WebAdmin.Model;
using WF_WebAdmin.Service;
namespace WF_WebAdmin.Pages
{
public partial class ModifQuiz
{
private Quiz[] quiz;
private int MaxValue = 5;
private int totalItem;
private bool showEditQuiz = false;
private Quiz? selectedQuiz;
private bool showPopupDelete = false;
private int page = 1;
[Inject]
public ILogger<ModifQuiz>? Logger { get; set; }
[Inject]
public IStringLocalizer<ModifQuiz> Localizer { get; set; }
[Inject]
public IQuizService QuizService { get; set; }
/// <summary>
/// Handles the data reading event for a data grid, fetching quiz data based on the specified page and page size.
/// This method makes an asynchronous call to retrieve a specific page of quizzes and updates the `quiz` list and pagination details.
/// If the cancellation token is requested, it exits early without making further calls or updates.
/// </summary>
/// <param name="e">The event arguments containing pagination details such as page size and page number.</param>
private async Task OnReadData(DataGridReadDataEventArgs<Quiz> e)
{
// Check if the cancellation token has been requested
if (e.CancellationToken.IsCancellationRequested)
{
return;
}
// Fetch the quiz data for the specified page and page size
var response = await QuizService.getSommeQuiz(e.PageSize, e.Page);
// If cancellation hasn't been requested, process the data
if (!e.CancellationToken.IsCancellationRequested)
{
// Get the total number of quizzes for pagination purposes
totalItem = await QuizService.getNbQuiz();
// Update the quiz data for the current page
quiz = response.ToArray();
// Update the current page number
page = e.Page;
}
}
/// <summary>
/// Handles the event when the "Edit" button is clicked for a quiz.
/// This method checks if a valid quiz is passed. If so, it sets the `selectedQuiz` to the clicked quiz and shows the quiz edit modal.
/// </summary>
/// <param name="quiz">The quiz object that was clicked for editing.</param>
private void OnEditButtonClicked(Quiz quiz)
{
// If the quiz is null, return early
if (quiz == null) return;
// Set the selected quiz to the one clicked by the user
selectedQuiz = quiz;
// Show the modal or UI for editing the quiz
showEditQuiz = true;
}
/// <summary>
/// Closes the open popups and resets any related states.
/// This method hides the quiz edit popup, the delete confirmation popup, and resets the selected quiz to `null`.
/// </summary>
private void ClosePopup()
{
// Hide the edit quiz popup
showEditQuiz = false;
// Hide the delete confirmation popup
showPopupDelete = false;
// Reset the selected quiz to null
selectedQuiz = null;
}
/// <summary>
/// Edits the selected quiz by updating it in the quiz service.
/// This method asynchronously sends the updated quiz data to the service for persistence.
/// After updating the quiz, it clears the selected quiz and closes any open popups.
/// </summary>
private async Task EditQuiz()
{
// Update the quiz in the service
LoggerSaveStub.Log(Logger, LogLevel.Information, $"Editing the question {selectedQuiz.Question}");
await QuizService.updateQuiz(selectedQuiz);
// Clear the selected quiz after successful update
selectedQuiz = null;
// Close the popups after the edit operation
ClosePopup();
}
/// <summary>
/// Handles the event when the delete action is triggered for a quiz.
/// This method sets the selected quiz to the one passed as a parameter and shows the delete confirmation popup.
/// </summary>
/// <param name="q">The quiz to be deleted.</param>
private void OnDelete(Quiz q)
{
// Set the selected quiz to the one passed in
selectedQuiz = q;
// Show the delete confirmation popup
showPopupDelete = true;
}
/// <summary>
/// Removes the selected quiz from the quiz service and updates the quiz list.
/// This method first checks if a quiz is selected, and if so, it deletes the quiz by calling the service.
/// After removal, it clears the `selectedQuiz`, updates the quiz list, and closes the delete confirmation popup.
/// </summary>
private async Task RemoveQuote()
{
// Check if a quiz is selected for deletion
if (selectedQuiz != null)
{
// Remove the selected quiz from the service by its ID
LoggerSaveStub.Log(Logger, LogLevel.Information, $"Delete the question {selectedQuiz.Question}");
await QuizService.removeQuiz(selectedQuiz.Id);
// Clear the selected quiz after successful removal
selectedQuiz = null;
// Update the quiz list by fetching the latest data
var response = await QuizService.getSommeQuiz(MaxValue, page);
quiz = response.ToArray();
}
// Close the delete confirmation popup
showPopupDelete = false;
}
}
}

@ -1,24 +1,58 @@
@using WF_WebAdmin.Model @using WF_WebAdmin.Model
@page "/modifquote" @page "/modifquote"
<PageTitle>Corection des citation</PageTitle> <PageTitle>@Localizer["TitlePage"]</PageTitle>
<h3>Corection des citation</h3> <h3>@Localizer["TitlePage"]</h3>
<p>Ajouter une recherche</p> <DataGrid TItem="Quote"
@if (quotes != null)
{
<DataGrid TItem="Quote"
Data="@quotes" Data="@quotes"
PageSize="int.MaxValue" PageSize="@MaxValue"
ReadData="@OnReadData"
TotalItems="@totalItem"
ShowPager
Responsive> Responsive>
<DataGridColumn TItem="Quote" Field="@nameof(Quote.Id)" Caption="Id"/> <DataGridColumn TItem="Quote" Field="@nameof(Quote.Id)" Caption="@Localizer["Id"]" />
<DataGridColumn TItem="Quote" Field="@nameof(Quote.Content)" Caption="Citation"/> <DataGridColumn TItem="Quote" Field="@nameof(Quote.Content)" Caption="@Localizer["Quote"]" />
<DataGridColumn TItem="Quote" Field="@nameof(Quote.Charac)" Caption="Personage"/> <DataGridColumn TItem="Quote" Field="@nameof(Quote.Charac)" Caption="@Localizer["Character"]" />
<DataGridColumn TItem="Quote" Field="@nameof(Quote.TitleSrc)" Caption="Source" /> <DataGridColumn TItem="Quote" Field="@nameof(Quote.TitleSrc)" Caption="@Localizer["Source"]" />
<DataGridColumn TItem="Quote" Field="@nameof(Quote.Langue)" Caption="Langue" /> <DataGridColumn TItem="Quote" Field="@nameof(Quote.Langue)" Caption="@Localizer["Language"]" />
<DataGridColumn TItem="Quote" Field="@nameof(Quote.DateSrc)" Caption="Date" DisplayFormat="{0:d}" DisplayFormatProvider="@System.Globalization.CultureInfo.GetCultureInfo("fr-FR")" /> <DataGridColumn TItem="Quote" Field="@nameof(Quote.DateSrc)" Caption="@Localizer["Date"]" DisplayFormat="{0:d}" DisplayFormatProvider="@System.Globalization.CultureInfo.GetCultureInfo("fr-FR")" />
</DataGrid> <DataGridColumn TItem="Quote" Field="@nameof(Quote.Id)" Caption="@Localizer["Action"]">
<DisplayTemplate>
@* <button @onclick="() => OnEditButtonClicked(context) " style="background-color: lightgray; padding: 0">
<img alt="Bouton Modifier" src="edit.png" width="30" height="30"/>
</button> *@
<a href="Edit/@(context.Id)" class="btn btn-primary"><i class="fa fa-edit"></i> @Localizer["Edit"]</a>
<button type="button" class="btn btn-primary" @onclick="() => OnDelete(context)"><i class="fa fa-trash"></i> @Localizer["Delete"]</button>
</DisplayTemplate>
</DataGridColumn>
</DataGrid>
@* @if (showEditQuote && selectedQuote != null)
{
<div class="divPopup">
<div class="contentPopup">
<p>Modifier les informations de l'utilisateur :</p>
<label>Citation:</label>
<input type="text" @bind="selectedQuote.Content"/>
<label>Personnage:</label>
<input type="text" @bind="selectedQuote.Charac" />
<label>Source:</label>
<input type="text" @bind="selectedQuote.TitleSrc" />
<button @onclick="EditQuote">Sauvegarder </button>
<button @onclick="ClosePopup">Annuler</button>
</div>
</div> *@
@if (showPopupDelete)
{
<div class="divPopup">
<div class="contentPopup">
<p>@Localizer["PopupQuestion"]</p>
<button @onclick="RemoveQuote">@Localizer["Yes"]</button>
<button @onclick="ClosePopup">@Localizer["Cancel"]</button>
</div>
</div>
} }

@ -1,5 +1,10 @@
using Blazorise.DataGrid;
using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components;
using Microsoft.Extensions.Localization;
using Microsoft.Extensions.Logging;
using System.Security.Claims;
using WF_WebAdmin.Model; using WF_WebAdmin.Model;
using WF_WebAdmin.Service;
namespace WF_WebAdmin.Pages namespace WF_WebAdmin.Pages
{ {
@ -9,15 +14,122 @@ namespace WF_WebAdmin.Pages
private int MaxValue = 5; private int MaxValue = 5;
private int totalItem;
/*private bool showEditQuote = false;*/
private Quote? selectedQuote;
private bool showPopupDelete = false;
private int page = 1;
[Inject] [Inject]
public HttpClient Http { get; set; } public ILogger<ModifQuote>? Logger { get; set; }
[Inject] [Inject]
public NavigationManager NavigationManager { get; set; } public IStringLocalizer<ModifQuote> Localizer { get; set; }
[Inject]
public IQuoteService QuoteService { get; set; }
/// <summary>
/// Handles the data reading event for a data grid, fetching quote data based on the specified page and page size.
/// This method makes an asynchronous call to retrieve a specific page of quotes and updates the `quotes` list and pagination details.
/// If the cancellation token is requested, it exits early without making further calls or updates.
/// </summary>
/// <param name="e">The event arguments containing pagination details such as page size and page number.</param>
private async Task OnReadData(DataGridReadDataEventArgs<Quote> e)
{
// Check if the cancellation token has been requested
if (e.CancellationToken.IsCancellationRequested)
{
return;
}
// Fetch the quote data for the specified page and page size
var response = await QuoteService.getSomeQuote(e.PageSize, e.Page);
// If cancellation hasn't been requested, process the data
if (!e.CancellationToken.IsCancellationRequested)
{
// Get the total number of quotes for pagination purposes
totalItem = await QuoteService.getNbQuote();
// Update the quotes data for the current page
quotes = response.ToArray();
// Update the current page number
page = e.Page;
}
}
/*private void OnEditButtonClicked(Quote quote)
{
if (selectedQuote == null) return;
selectedQuote = quote;
showEditQuote = true;
}*/
/// <summary>
/// Closes the open popups and resets any related states.
/// This method hides the delete confirmation popup and clears the selected quote.
/// </summary>
private void ClosePopup()
{
// Hide the delete confirmation popup
showPopupDelete = false;
// Reset the selected quote to null
selectedQuote = null;
}
/*private async Task EditQuote()
{
await QuoteService.updateQuote(selectedQuote);
selectedQuote = null;
ClosePopup();
}*/
protected override async Task OnInitializedAsync() /// <summary>
/// Handles the event when the delete action is triggered for a quote.
/// This method sets the selected quote to the one passed as a parameter and displays the delete confirmation popup.
/// </summary>
/// <param name="q">The quote that is being deleted.</param>
private void OnDelete(Quote q)
{ {
quotes = await Http.GetFromJsonAsync<Quote[]>($"{NavigationManager.BaseUri}fake-dataModifQuote.json"); // Set the selected quote to the one passed in
selectedQuote = q;
// Display the delete confirmation popup
showPopupDelete = true;
}
/// <summary>
/// Removes the selected quote by calling the remove service and updates the quote list.
/// This method checks if a quote is selected. If so, it removes the quote using the `QuoteService`, clears the selected quote,
/// and fetches the updated list of quotes. It also closes the delete confirmation popup after the operation.
/// </summary>
private async Task RemoveQuote()
{
// Check if a quote is selected for removal
if (selectedQuote != null)
{
// Remove the selected quote using the QuoteService
LoggerSaveStub.Log(Logger, LogLevel.Information, $"The quote {selectedQuote.Content} has been deleted");
await QuoteService.removeQuote(selectedQuote);
// Clear the selected quote after removal
selectedQuote = null;
// Update the quotes list by fetching the latest quotes data
var response = await QuoteService.getSomeQuote(MaxValue, page);
quotes = response.ToArray();
}
// Close the delete confirmation popup
showPopupDelete = false;
} }
} }
} }

@ -2,28 +2,28 @@
@using System.Dynamic @using System.Dynamic
@using WF_WebAdmin.Model @using WF_WebAdmin.Model
<h3> Quiz à valider </h3> <h3>@Localizer["TitleQuiz"]</h3>
@if (quizzes == null) @if (quizzes == null)
{ {
<p> Chargement des quiz ... </p> <p> @Localizer["LoadQuiz"] </p>
} }
else else
{ {
<p> Quizs en attente de validation : </p> <p>@Localizer["QuizAwait"] </p>
<table> <table>
<thead> <thead>
<tr> <tr>
<th>#</th> <th>#</th>
<th>Question</th> <th>@Localizer["Question"]</th>
<th>Réponse A</th> <th>@Localizer["AnswerA"]</th>
<th>Réponse B</th> <th>@Localizer["AnswerB"]</th>
<th>Réponse C</th> <th>@Localizer["AnswerC"]</th>
<th>Réponse D</th> <th>@Localizer["AnswerD"]</th>
<th>Réponse Correcte</th> <th>@Localizer["GoodAnswer"]</th>
<th>Utilisateur</th> <th>@Localizer["User"]</th>
<th>Actions</th> <th>@Localizer["Action"]</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>

@ -1,13 +1,21 @@
using Blazorise.DataGrid; using Blazorise.DataGrid;
using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components;
using Microsoft.Extensions.Localization;
using Microsoft.Extensions.Logging;
using System.Security.Claims;
using WF_WebAdmin.Model; using WF_WebAdmin.Model;
using WF_WebAdmin.Service;
namespace WF_WebAdmin.Pages namespace WF_WebAdmin.Pages
{ {
public partial class ValidQuiz public partial class ValidQuiz
{ {
private Quiz[] quizzes; private List<Quiz> quizzes;
private int totalQuizzes; [Inject]
public ILogger<ValidQuiz>? Logger { get; set; }
[Inject]
public IStringLocalizer<ValidQuiz> Localizer { get; set; }
[Inject] [Inject]
public HttpClient Http { get; set; } public HttpClient Http { get; set; }
@ -15,29 +23,78 @@ namespace WF_WebAdmin.Pages
[Inject] [Inject]
public NavigationManager NavigationManager { get; set; } public NavigationManager NavigationManager { get; set; }
[Inject]
public IQuizService QuizService { get; set; }
/// <summary>
/// Initializes the component asynchronously by fetching the quizzes that need validation.
/// This method retrieves a list of quizzes from the `QuizService` that are pending validation when the component is initialized.
/// </summary>
protected override async Task OnInitializedAsync() protected override async Task OnInitializedAsync()
{ {
quizzes = await Http.GetFromJsonAsync<Quiz[]>($"{NavigationManager.BaseUri}fake-dataQuiz.json"); // Fetch quizzes that need validation
quizzes = await QuizService.getQuizzesToValidate();
} }
/// <summary>
/// Handles the event when the "Validate" button is clicked for a quiz.
/// This method calls the `ValidateQuiz` method, passing the specified quiz for validation.
/// </summary>
/// <param name="quiz">The quiz that is being validated.</param>
private void OnValidButton(Quiz quiz) private void OnValidButton(Quiz quiz)
{ {
// Call the ValidateQuiz method to validate the quiz
ValidateQuiz(quiz); ValidateQuiz(quiz);
} }
/// <summary>
/// Validates the specified quiz by setting its `IsValid` property to true and updating its state in the service.
/// This method logs a message to the console indicating the quiz has been validated, then updates the quiz's validation status.
/// It then calls the `QuizService.updateQuiz` method to persist the changes.
/// </summary>
/// <param name="quiz">The quiz that is being validated.</param>
private void ValidateQuiz(Quiz quiz) private void ValidateQuiz(Quiz quiz)
{ {
// Log the validation action to the console
LoggerSaveStub.Log(Logger, LogLevel.Information, $"Quiz {quiz.Id} validated!");
Console.WriteLine($"Quiz {quiz.Id} validated!"); Console.WriteLine($"Quiz {quiz.Id} validated!");
// Create a new quiz instance (or modify the existing one)
Quiz newQuiz = quiz;
newQuiz.IsValid = true;
// Update the quiz state in the QuizService
QuizService.updateQuiz(quiz);
} }
/// <summary>
/// Handles the event when the "Reject" button is clicked for a quiz.
/// This method calls the `RejectQuiz` method, passing the specified quiz to be rejected.
/// </summary>
/// <param name="quiz">The quiz that is being rejected.</param>
private void OnRejectButton(Quiz quiz) private void OnRejectButton(Quiz quiz)
{ {
// Call the RejectQuiz method to reject the quiz
RejectQuiz(quiz); RejectQuiz(quiz);
} }
/// <summary>
/// Rejects the specified quiz by logging a rejection message and removing it from the QuizService.
/// This method logs a message to the console indicating the quiz has been rejected, and then calls the `QuizService.removeQuiz`
/// method to remove the quiz from the system.
/// </summary>
/// <param name="quiz">The quiz that is being rejected.</param>
private void RejectQuiz(Quiz quiz) private void RejectQuiz(Quiz quiz)
{ {
// Log the rejection action to the console
LoggerSaveStub.Log(Logger, LogLevel.Information, $"Quiz {quiz.Id} rejected");
Console.WriteLine($"Quiz {quiz.Id} rejected!"); Console.WriteLine($"Quiz {quiz.Id} rejected!");
// Remove the rejected quiz from the QuizService
QuizService.removeQuiz(quiz.Id);
} }
} }
} }

@ -1,36 +1,35 @@
@page "/ValidQuote" @page "/ValidQuote"
@using WF_WebAdmin.Model @using WF_WebAdmin.Model
<h3>Citations non validées</h3> <h3>@Localizer["TitleValid"]</h3>
@if (quotes is null) @if (quotes is null)
{ {
<p>Chargement des citations...</p> <p>@Localizer["LoginQuote"]</p>
} }
else if (quotes.Count == 0) @* else if (quotes.Count == 0)
{ {
<p>Aucune citation en attente de validation.</p> <p>Aucune citation en attente de validation.</p>
} } *@
else else
{ {
<p>Citations en attente de validation :</p> <p>@Localizer["QuoteValid"]</p>
@foreach (var quote in quotes) @foreach (var quote in quotes)
{ {
<div class="QuoteDiv"> <div class="QuoteDiv">
<p><strong>ID :</strong> @quote.Id</p> <p><strong>@Localizer["Id"]</strong> @quote.Id</p>
<p><strong>Contenu :</strong> @quote.Content</p> <p><strong>@Localizer["Content"]</strong> @quote.Content</p>
<p><strong>Langue :</strong> @quote.Langue</p> <p><strong>@Localizer["Language"]</strong> @quote.Langue</p>
<p><strong>Likes :</strong> @quote.Like</p>
<p><strong>Personnage :</strong> @quote.Charac</p> <p><strong>@Localizer["Character"]</strong> @quote.Charac</p>
<p><strong>Image :</strong> @quote.ImgPath</p> <p><strong>@Localizer["Image"]</strong> @quote.ImgPath</p>
<p><strong>Source :</strong> @quote.TitleSrc</p> <p><strong>@Localizer["Source"]</strong> @quote.TitleSrc</p>
<p><strong>Date de source :</strong> @quote.DateSrc.ToShortDateString()</p> <p><strong>@Localizer["Date"]</strong> @quote.DateSrc.ToShortDateString()</p>
<p><strong>Utilisateur proposition :</strong> @quote.UserProposition</p> <p><strong>@Localizer["User"]</strong> @quote.UserProposition</p>
<button @onclick="() => ValiderQuote(quote.Id)">Valider</button> @* <button @onclick="() => ValiderQuote(quote.Id)">Valider</button>
<button @onclick="() => RejeterQuote(quote.Id)">Rejeter</button> <button @onclick="() => RejeterQuote(quote.Id)">Rejeter</button> *@
</div> </div>
} }
} }

@ -6,134 +6,32 @@ using System.Collections.Generic;
using System; using System;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Linq; using System.Linq;
using Microsoft.Extensions.Localization;
namespace WF_WebAdmin.Pages namespace WF_WebAdmin.Pages
{ {
public partial class ValidQuote public partial class ValidQuote
{ {
// Chaîne de connexion à adapter private Quote[] quotes;
private const string connectionString =
"Host=localhost;Port=5432;Database=wikifantasy3;Username=postgres;Password=postgres";
private List<Quote> quotes; [Inject]
public IStringLocalizer<ValidQuote> Localizer { get; set; }
protected override async Task OnInitializedAsync() [Inject]
{ public HttpClient Http { get; set; }
// On charge toutes les citations dont isValide = false
quotes = await LoadNotValidatedQuotesAsync();
}
/// <summary> [Inject]
/// Charge toutes les citations non validées (isValide = false) public NavigationManager NavigationManager { get; set; }
/// et mappe les colonnes vers ton modèle.
/// </summary>
private async Task<List<Quote>> LoadNotValidatedQuotesAsync()
{
var result = new List<Quote>();
try
{
using var con = new NpgsqlConnection(connectionString);
await con.OpenAsync();
// Sélection des colonnes réellement présentes en DB
// + placeholders pour les autres
var sql = @"
SELECT
id_quote AS Id,
content AS Content,
likes AS ""Like"",
langue AS Langue,
-- Champs pas vraiment en DB : placeholders
'' AS Charac,
'' AS ImgPath,
'' AS TitleSrc,
now() AS DateSrc,
'' AS UserProposition
FROM quote
WHERE isValide = false
";
using var cmd = new NpgsqlCommand(sql, con);
using var reader = await cmd.ExecuteReaderAsync();
while (await reader.ReadAsync())
{
var q = new Quote
{
Id = reader.GetInt32(reader.GetOrdinal("Id")),
Content = reader.GetString(reader.GetOrdinal("Content")),
Like = reader.GetInt32(reader.GetOrdinal("Like")),
Langue = reader.GetString(reader.GetOrdinal("Langue")),
// placeholders
Charac = reader.GetString(reader.GetOrdinal("Charac")),
ImgPath = reader.GetString(reader.GetOrdinal("ImgPath")),
TitleSrc = reader.GetString(reader.GetOrdinal("TitleSrc")),
DateSrc = reader.GetDateTime(reader.GetOrdinal("DateSrc")),
UserProposition = reader.GetString(reader.GetOrdinal("UserProposition"))
};
result.Add(q);
}
}
catch (Exception ex)
{
Console.WriteLine($"[Erreur] LoadNotValidatedQuotesAsync : {ex.Message}");
}
return result;
}
/// <summary> /// <summary>
/// Met à jour isValide = true pour la citation. /// Initializes the component asynchronously by fetching a list of quotes from a JSON file.
/// This method makes an asynchronous HTTP request to retrieve an array of `Quote` objects from a specified JSON file
/// located at the base URI, and then assigns the result to the `quotes` variable.
/// </summary> /// </summary>
private async Task ValiderQuote(int quoteId) protected override async Task OnInitializedAsync()
{
try
{
using var con = new NpgsqlConnection(connectionString);
await con.OpenAsync();
var sql = "UPDATE quote SET isValide = true WHERE id_quote = @Id";
using var cmd = new NpgsqlCommand(sql, con);
cmd.Parameters.AddWithValue("Id", quoteId);
int rowsAffected = await cmd.ExecuteNonQueryAsync();
if (rowsAffected > 0)
{
// Supprime la quote de la liste pour l'enlever de l'affichage
quotes.RemoveAll(q => q.Id == quoteId);
}
}
catch (Exception ex)
{
Console.WriteLine($"[Erreur] ValiderQuote : {ex.Message}");
}
}
/// <summary>
/// Supprime complètement la citation de la base.
/// </summary>
private async Task RejeterQuote(int quoteId)
{
try
{
using var con = new NpgsqlConnection(connectionString);
await con.OpenAsync();
var sql = "DELETE FROM quote WHERE id_quote = @Id";
using var cmd = new NpgsqlCommand(sql, con);
cmd.Parameters.AddWithValue("Id", quoteId);
int rowsAffected = await cmd.ExecuteNonQueryAsync();
if (rowsAffected > 0)
{
quotes.RemoveAll(q => q.Id == quoteId);
}
}
catch (Exception ex)
{ {
Console.WriteLine($"[Erreur] RejeterQuote : {ex.Message}"); // Fetch the list of quotes from the JSON file located at the base URI
} quotes = await Http.GetFromJsonAsync<Quote[]>($"{NavigationManager.BaseUri}fake-dataQuote.json");
} }
} }
} }

@ -1,4 +1,13 @@
@page "/" @*
File: _Host.cshtml
Project: WF_WebAdmin
Description: ...
Author: What The Fantasy
Created: 10/02/2025
Last Modified: 10/02/2025
*@
@page "/"
@namespace WF_WebAdmin.Pages @namespace WF_WebAdmin.Pages
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@{ @{
@ -6,3 +15,7 @@
} }
<component type="typeof(App)" render-mode="ServerPrerendered" /> <component type="typeof(App)" render-mode="ServerPrerendered" />
<body>
<script src="https://cdn.syncfusion.com/blazor/22.1.38/syncfusion-blazor.min.js" type="text/javascript"></script>
</body>

@ -1,10 +1,20 @@
@using Microsoft.AspNetCore.Components.Web @*
File: _Layout.cshtml
Project: WF_WebAdmin
Description: ...
Author: What The Fantasy
Created: 10/02/2025
Last Modified: 10/02/2025
*@
@using Microsoft.AspNetCore.Components.Web
@namespace WF_WebAdmin.Pages @namespace WF_WebAdmin.Pages
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>
<title>layout</title>
<meta charset="utf-8" /> <meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<base href="~/" /> <base href="~/" />
@ -12,6 +22,7 @@
<link href="css/site.css" rel="stylesheet" /> <link href="css/site.css" rel="stylesheet" />
<link href="WF-WebAdmin.styles.css" rel="stylesheet" /> <link href="WF-WebAdmin.styles.css" rel="stylesheet" />
<component type="typeof(HeadOutlet)" render-mode="ServerPrerendered" /> <component type="typeof(HeadOutlet)" render-mode="ServerPrerendered" />
<link rel="icon" type="image/svg" href="../Shared/iconwf.svg" />
</head> </head>
<body> <body>
@RenderBody() @RenderBody()
@ -23,7 +34,7 @@
<environment include="Development"> <environment include="Development">
An unhandled exception has occurred. See browser dev tools for details. An unhandled exception has occurred. See browser dev tools for details.
</environment> </environment>
<a href="" class="reload">Reload</a> <a href="" class="reload">reload</a>
<a class="dismiss">🗙</a> <a class="dismiss">🗙</a>
</div> </div>
@ -33,5 +44,6 @@
<link href="_content/Blazorise/blazorise.css" rel="stylesheet" /> <link href="_content/Blazorise/blazorise.css" rel="stylesheet" />
<link href="_content/Blazorise.Bootstrap/blazorise.bootstrap.css" rel="stylesheet" /> <link href="_content/Blazorise.Bootstrap/blazorise.bootstrap.css" rel="stylesheet" />
</body> </body>
</html> </html>

@ -1,18 +1,32 @@
using Blazorise; using Blazorise;
using Blazorise.Bootstrap; using Blazorise.Bootstrap;
using Blazorise.Icons.FontAwesome; using Blazorise.Icons.FontAwesome;
using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Localization;
using Microsoft.AspNetCore.Components.Web; using System.Globalization;
using WF_WebAdmin.Data; using WF_WebAdmin.Data;
using WF_WebAdmin.Service;
using WF_WebAdmin.Model;
using Microsoft.Extensions.Localization;
using Microsoft.Extensions.Options;
using Blazored.Modal;
using MudBlazor.Services;
[assembly: RootNamespace("WF_WebAdmin")]
var builder = WebApplication.CreateBuilder(args); var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddRazorPages(); builder.Services.AddRazorPages();
builder.Services.AddServerSideBlazor(); builder.Services.AddServerSideBlazor();
builder.Services.AddSingleton<WeatherForecastService>(); builder.Services.AddSingleton<WeatherForecastService>();
builder.Services.AddScoped<IQuoteService,QuoteServiceStub>();
builder.Services.AddScoped<IQuizService,QuizServiceStub>();
builder.Services.AddScoped<IUserService, UserServiceStub>();
builder.Services.AddScoped<ICommentaryService, CommentaryServiceStub>();
builder.Services.AddHttpClient(); builder.Services.AddHttpClient();
builder.Services.AddScoped<UserLogin>();
builder.Services.AddMudServices();
builder.Logging.AddConfiguration(builder.Configuration.GetSection("Logging"));
builder.Services builder.Services
.AddBlazorise() .AddBlazorise()
@ -20,6 +34,25 @@ builder.Services
.AddHttpClient() .AddHttpClient()
.AddFontAwesomeIcons(); .AddFontAwesomeIcons();
builder.Services.AddBlazoredModal();
// Add the controller of the app
builder.Services.AddControllers();
// Add the localization to the app and specify the resources path
builder.Services.AddLocalization(opts => { opts.ResourcesPath = "Resources"; });
// Configure the localtization
builder.Services.Configure<RequestLocalizationOptions>(options =>
{
var supportedCultures = new[] { "en-US", "fr-FR" };
options.DefaultRequestCulture = new RequestCulture(new CultureInfo("en-US"));
options.SupportedCultures = supportedCultures.Select(c=>new CultureInfo(c)).ToList();
options.SupportedUICultures = supportedCultures.Select(c => new CultureInfo(c)).ToList();
});
var app = builder.Build(); var app = builder.Build();
// Configure the HTTP request pipeline. // Configure the HTTP request pipeline.
@ -36,6 +69,21 @@ app.UseStaticFiles();
app.UseRouting(); app.UseRouting();
// Get the current localization options
var options = ((IApplicationBuilder)app).ApplicationServices.GetService<IOptions<RequestLocalizationOptions>>();
if (options?.Value != null)
{
// use the default localization
app.UseRequestLocalization(options.Value);
}
// Add the controller to the endpoint
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
app.MapBlazorHub(); app.MapBlazorHub();
app.MapFallbackToPage("/_Host"); app.MapFallbackToPage("/_Host");

@ -0,0 +1,141 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="AccueilAddRandomQuote" xml:space="preserve">
<value>Put a New Random Quote</value>
</data>
<data name="AccueilCharacter" xml:space="preserve">
<value>Character:</value>
</data>
<data name="AccueilManualChange" xml:space="preserve">
<value>Changed Quote Manually</value>
</data>
<data name="AccueilNoQuote" xml:space="preserve">
<value>No Quote of the Day</value>
</data>
<data name="AccueilSrc" xml:space="preserve">
<value>Source:</value>
</data>
<data name="AccueilTitle" xml:space="preserve">
<value>Quote of the Day</value>
</data>
<data name="AccueilWelcome" xml:space="preserve">
<value>Welcome to the What the Fantasy Dashboard</value>
</data>
</root>

@ -0,0 +1,141 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="AccueilAddRandomQuote" xml:space="preserve">
<value>Mettre une nouvellement citation aléatoire</value>
</data>
<data name="AccueilCharacter" xml:space="preserve">
<value>Personnage :</value>
</data>
<data name="AccueilManualChange" xml:space="preserve">
<value>Changement de la citation manuellement</value>
</data>
<data name="AccueilNoQuote" xml:space="preserve">
<value>Aucune citation du jour</value>
</data>
<data name="AccueilSrc" xml:space="preserve">
<value>Source :</value>
</data>
<data name="AccueilTitle" xml:space="preserve">
<value>Citation du jour</value>
</data>
<data name="AccueilWelcome" xml:space="preserve">
<value>Bienvenu sur le tableau de bord de What the Fantasy</value>
</data>
</root>

@ -0,0 +1,144 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="AnswerA" xml:space="preserve">
<value>Answer A:</value>
</data>
<data name="AnswerB" xml:space="preserve">
<value>Answer B:</value>
</data>
<data name="AnswerC" xml:space="preserve">
<value>Answer C:</value>
</data>
<data name="AnswerD" xml:space="preserve">
<value>Answer D:</value>
</data>
<data name="GoodAnswer" xml:space="preserve">
<value>Good answer:</value>
</data>
<data name="Submit" xml:space="preserve">
<value>Submit</value>
</data>
<data name="TitleAddQuiz" xml:space="preserve">
<value>Add a question</value>
</data>
<data name="TitleQuestion" xml:space="preserve">
<value>Question:</value>
</data>
</root>

@ -0,0 +1,144 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="AnswerA" xml:space="preserve">
<value>Réponse A:</value>
</data>
<data name="AnswerB" xml:space="preserve">
<value>Réponse B:</value>
</data>
<data name="AnswerC" xml:space="preserve">
<value>Réponse C:</value>
</data>
<data name="AnswerD" xml:space="preserve">
<value>Réponse D:</value>
</data>
<data name="GoodAnswer" xml:space="preserve">
<value>Bonne réponse:</value>
</data>
<data name="Submit" xml:space="preserve">
<value>Valider</value>
</data>
<data name="TitleAddQuiz" xml:space="preserve">
<value>Ajouter une Question</value>
</data>
<data name="TitleQuestion" xml:space="preserve">
<value>Question:</value>
</data>
</root>

@ -0,0 +1,169 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="TitleUser" xml:space="preserve">
<value>User Management</value>
<comment>gestionaire user</comment>
</data>
<data name="UserAddAdmin" xml:space="preserve">
<value>Add as Admin</value>
</data>
<data name="UserAdmin" xml:space="preserve">
<value>Administrator</value>
</data>
<data name="UserComment" xml:space="preserve">
<value>Comment(s) Posted by</value>
</data>
<data name="UserConfirmButton" xml:space="preserve">
<value>Confirm</value>
</data>
<data name="UserDate" xml:space="preserve">
<value>Account Creation Date:</value>
</data>
<data name="UserDelete" xml:space="preserve">
<value>Delete User</value>
</data>
<data name="UserDeleteAdmin" xml:space="preserve">
<value>Remove as Admin</value>
</data>
<data name="UserDeleteButton" xml:space="preserve">
<value>Cancel</value>
</data>
<data name="UserEmail" xml:space="preserve">
<value>User Email:</value>
</data>
<data name="UserHere" xml:space="preserve">
<value>Users present:</value>
</data>
<data name="UserName" xml:space="preserve">
<value>Username</value>
</data>
<data name="UserNobody" xml:space="preserve">
<value>No users present on the site</value>
</data>
<data name="UserNoComment" xml:space="preserve">
<value>No comments on the site</value>
</data>
<data name="UserPopupTitle" xml:space="preserve">
<value>Are you sure you want to delete this user?</value>
</data>
<data name="UserPopupTitle2" xml:space="preserve">
<value>Are you sure you want to change this user's role?</value>
</data>
</root>

@ -0,0 +1,169 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="TitleUser" xml:space="preserve">
<value>Gestionnaire des utilisateurs</value>
<comment>gestion user</comment>
</data>
<data name="UserAddAdmin" xml:space="preserve">
<value>Ajouter en tant qu'administrateur</value>
</data>
<data name="UserAdmin" xml:space="preserve">
<value>Administrateur</value>
</data>
<data name="UserComment" xml:space="preserve">
<value>Commentaire(s) posté(s) par </value>
</data>
<data name="UserConfirmButton" xml:space="preserve">
<value>Confirmer</value>
</data>
<data name="UserDate" xml:space="preserve">
<value>Date de création du compte :</value>
</data>
<data name="UserDelete" xml:space="preserve">
<value>Supprimer l'utilisateur</value>
</data>
<data name="UserDeleteAdmin" xml:space="preserve">
<value>Retirer en tant qu'administrateur</value>
</data>
<data name="UserDeleteButton" xml:space="preserve">
<value>Annuler</value>
</data>
<data name="UserEmail" xml:space="preserve">
<value>Email de l'utilisateur :</value>
</data>
<data name="UserHere" xml:space="preserve">
<value>Utilisateurs présents:</value>
</data>
<data name="UserName" xml:space="preserve">
<value>Nom d'utilisateur :</value>
</data>
<data name="UserNobody" xml:space="preserve">
<value>Aucun utilisateur présent sur le site</value>
</data>
<data name="UserNoComment" xml:space="preserve">
<value>Aucun commentaire sur le site</value>
</data>
<data name="UserPopupTitle" xml:space="preserve">
<value>Êtes-vous sûr de vouloir supprimer cet utilisateur ?</value>
</data>
<data name="UserPopupTitle2" xml:space="preserve">
<value>Êtes-vous sûr de vouloir changer le rôle de cet utilisateur ?</value>
</data>
</root>

@ -0,0 +1,140 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="LoginConnexion" xml:space="preserve">
<value>Login</value>
</data>
<data name="LoginEnterPassWd" xml:space="preserve">
<value>Enter your password</value>
</data>
<data name="LoginEnterPseudo" xml:space="preserve">
<value>Enter your pseudo</value>
</data>
<data name="LoginId" xml:space="preserve">
<value>Pseudo</value>
<comment>id</comment>
</data>
<data name="LoginPassWd" xml:space="preserve">
<value>Password</value>
</data>
<data name="LoginTitle" xml:space="preserve">
<value>Login</value>
<comment>connexion</comment>
</data>
</root>

@ -0,0 +1,140 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="LoginConnexion" xml:space="preserve">
<value>Se Connecter</value>
</data>
<data name="LoginEnterPassWd" xml:space="preserve">
<value>Entrez votre mot de passe</value>
</data>
<data name="LoginEnterPseudo" xml:space="preserve">
<value>Entrez votre pseudo</value>
</data>
<data name="LoginId" xml:space="preserve">
<value>Identifiant</value>
<comment>id</comment>
</data>
<data name="LoginPassWd" xml:space="preserve">
<value>Mot de passe</value>
</data>
<data name="LoginTitle" xml:space="preserve">
<value>Connexion</value>
<comment>connexion</comment>
</data>
</root>

@ -0,0 +1,135 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="Log" xml:space="preserve">
<value>Current Logs</value>
</data>
<data name="LogContent" xml:space="preserve">
<value>Content</value>
</data>
<data name="LogLvl" xml:space="preserve">
<value>Type of Logs :</value>
</data>
<data name="LogTitle" xml:space="preserve">
<value>Logs</value>
</data>
<data name="NotLog" xml:space="preserve">
<value>No Log</value>
</data>
</root>

@ -0,0 +1,135 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="Log" xml:space="preserve">
<value>Logs actuels</value>
</data>
<data name="LogContent" xml:space="preserve">
<value>Contenu</value>
</data>
<data name="LogLvl" xml:space="preserve">
<value>Type de Logs :</value>
</data>
<data name="LogTitle" xml:space="preserve">
<value>Logs</value>
</data>
<data name="NotLog" xml:space="preserve">
<value>Aucun Log</value>
</data>
</root>

@ -0,0 +1,171 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="Action" xml:space="preserve">
<value>Action</value>
</data>
<data name="Add" xml:space="preserve">
<value>Add</value>
</data>
<data name="AnswerA" xml:space="preserve">
<value>Answer A</value>
</data>
<data name="AnswerB" xml:space="preserve">
<value>Answer B</value>
</data>
<data name="AnswerC" xml:space="preserve">
<value>Answer C</value>
</data>
<data name="AnswerD" xml:space="preserve">
<value>Answer D</value>
</data>
<data name="Cancel" xml:space="preserve">
<value>Cancel</value>
</data>
<data name="Delete" xml:space="preserve">
<value>Cancel</value>
</data>
<data name="Edit" xml:space="preserve">
<value>Edit</value>
</data>
<data name="GoodAnswer" xml:space="preserve">
<value>Good Answer</value>
</data>
<data name="Id" xml:space="preserve">
<value>ID</value>
</data>
<data name="ModifInfoUser" xml:space="preserve">
<value>Edit user information :</value>
</data>
<data name="PopupQuestion" xml:space="preserve">
<value>Are you sure you want to delete this quiz ?</value>
</data>
<data name="Question" xml:space="preserve">
<value>Question</value>
</data>
<data name="Save" xml:space="preserve">
<value>Save</value>
</data>
<data name="TitlePage" xml:space="preserve">
<value>Quiz Management</value>
</data>
<data name="Yes" xml:space="preserve">
<value>Confirm</value>
</data>
</root>

@ -0,0 +1,171 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="Action" xml:space="preserve">
<value>Action</value>
</data>
<data name="Add" xml:space="preserve">
<value>Ajouter</value>
</data>
<data name="AnswerA" xml:space="preserve">
<value>Réponse A</value>
</data>
<data name="AnswerB" xml:space="preserve">
<value>Réponse B</value>
</data>
<data name="AnswerC" xml:space="preserve">
<value>Réponse C</value>
</data>
<data name="AnswerD" xml:space="preserve">
<value>Réponse D</value>
</data>
<data name="Cancel" xml:space="preserve">
<value>Annuler</value>
</data>
<data name="Delete" xml:space="preserve">
<value>Supprimer</value>
</data>
<data name="Edit" xml:space="preserve">
<value>Editer</value>
</data>
<data name="GoodAnswer" xml:space="preserve">
<value>Bonne réponse</value>
</data>
<data name="Id" xml:space="preserve">
<value>ID</value>
</data>
<data name="ModifInfoUser" xml:space="preserve">
<value>Modifier les informations de l'utilisateur :</value>
</data>
<data name="PopupQuestion" xml:space="preserve">
<value>Êtes-vous sûr de vouloir supprimer ce quiz ?</value>
</data>
<data name="Question" xml:space="preserve">
<value>Question</value>
</data>
<data name="Save" xml:space="preserve">
<value>Sauvegarder</value>
</data>
<data name="TitlePage" xml:space="preserve">
<value>Gestion des quiz</value>
</data>
<data name="Yes" xml:space="preserve">
<value>Confirmer</value>
</data>
</root>

@ -0,0 +1,159 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="Action" xml:space="preserve">
<value>Action</value>
</data>
<data name="Cancel" xml:space="preserve">
<value>Cancel</value>
</data>
<data name="Character" xml:space="preserve">
<value>Character</value>
</data>
<data name="Date" xml:space="preserve">
<value>Date</value>
</data>
<data name="Delete" xml:space="preserve">
<value>Delete</value>
</data>
<data name="Edit" xml:space="preserve">
<value>Edit</value>
</data>
<data name="Id" xml:space="preserve">
<value>Id</value>
</data>
<data name="Language" xml:space="preserve">
<value>Language</value>
</data>
<data name="PopupQuestion" xml:space="preserve">
<value>Are you sure you want to delete this quote ?</value>
</data>
<data name="Quote" xml:space="preserve">
<value>Quote</value>
</data>
<data name="Source" xml:space="preserve">
<value>Source</value>
</data>
<data name="TitlePage" xml:space="preserve">
<value>Corrections of quotes</value>
</data>
<data name="Yes" xml:space="preserve">
<value>Confirm</value>
</data>
</root>

@ -0,0 +1,159 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="Action" xml:space="preserve">
<value>Action</value>
</data>
<data name="Cancel" xml:space="preserve">
<value>Annuler</value>
</data>
<data name="Character" xml:space="preserve">
<value>Personage</value>
</data>
<data name="Date" xml:space="preserve">
<value>Date</value>
</data>
<data name="Delete" xml:space="preserve">
<value>Supprimer</value>
</data>
<data name="Edit" xml:space="preserve">
<value>Editer</value>
</data>
<data name="Id" xml:space="preserve">
<value>Id</value>
</data>
<data name="Language" xml:space="preserve">
<value>Langue</value>
</data>
<data name="PopupQuestion" xml:space="preserve">
<value>Êtes-vous sûr de vouloir supprimer cette citation ?</value>
</data>
<data name="Quote" xml:space="preserve">
<value>Citation</value>
</data>
<data name="Source" xml:space="preserve">
<value>Source</value>
</data>
<data name="TitlePage" xml:space="preserve">
<value>Correction des citations</value>
</data>
<data name="Yes" xml:space="preserve">
<value>Confirmer</value>
</data>
</root>

@ -0,0 +1,153 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="Action" xml:space="preserve">
<value>Actions</value>
</data>
<data name="AnswerA" xml:space="preserve">
<value>Answer A</value>
</data>
<data name="AnswerB" xml:space="preserve">
<value>Answer B</value>
</data>
<data name="AnswerC" xml:space="preserve">
<value>Answer C</value>
</data>
<data name="AnswerD" xml:space="preserve">
<value>Answer D</value>
</data>
<data name="GoodAnswer" xml:space="preserve">
<value>Correct answer</value>
</data>
<data name="LoadQuiz" xml:space="preserve">
<value>Loading quizzes</value>
</data>
<data name="Question" xml:space="preserve">
<value>Question</value>
</data>
<data name="QuizAwait" xml:space="preserve">
<value>Quiz awaiting validation</value>
</data>
<data name="TitleQuiz" xml:space="preserve">
<value>Quiz to validate</value>
</data>
<data name="User" xml:space="preserve">
<value>User</value>
</data>
</root>

@ -0,0 +1,153 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="Action" xml:space="preserve">
<value>Actions</value>
</data>
<data name="AnswerA" xml:space="preserve">
<value>Réponse A </value>
</data>
<data name="AnswerB" xml:space="preserve">
<value>Réponse B</value>
</data>
<data name="AnswerC" xml:space="preserve">
<value>Réponse C</value>
</data>
<data name="AnswerD" xml:space="preserve">
<value>Réponse D</value>
</data>
<data name="GoodAnswer" xml:space="preserve">
<value>Réponse Correcte</value>
</data>
<data name="LoadQuiz" xml:space="preserve">
<value>Chargement des quiz ...</value>
</data>
<data name="Question" xml:space="preserve">
<value>Question</value>
</data>
<data name="QuizAwait" xml:space="preserve">
<value>Quizs en attente de validation :</value>
</data>
<data name="TitleQuiz" xml:space="preserve">
<value>Quiz à valider</value>
</data>
<data name="User" xml:space="preserve">
<value>Utilisateur</value>
</data>
</root>

@ -0,0 +1,153 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="Character" xml:space="preserve">
<value>Character :</value>
</data>
<data name="Content" xml:space="preserve">
<value>Content :</value>
</data>
<data name="Date" xml:space="preserve">
<value>Source date</value>
</data>
<data name="Id" xml:space="preserve">
<value>ID :</value>
</data>
<data name="Image" xml:space="preserve">
<value>Image :</value>
</data>
<data name="Language" xml:space="preserve">
<value>Language :</value>
</data>
<data name="LoginQuote" xml:space="preserve">
<value>Loading quotes</value>
</data>
<data name="QuoteValid" xml:space="preserve">
<value>Quotes awaiting validation</value>
</data>
<data name="Source" xml:space="preserve">
<value>Source :</value>
</data>
<data name="TitleValid" xml:space="preserve">
<value>Unvalidated quotes</value>
</data>
<data name="User" xml:space="preserve">
<value>User :</value>
</data>
</root>

@ -0,0 +1,153 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="Character" xml:space="preserve">
<value>Personnage :</value>
</data>
<data name="Content" xml:space="preserve">
<value>Contenu :</value>
</data>
<data name="Date" xml:space="preserve">
<value>Date de la source :</value>
</data>
<data name="Id" xml:space="preserve">
<value>ID :</value>
</data>
<data name="Image" xml:space="preserve">
<value>Image :</value>
</data>
<data name="Language" xml:space="preserve">
<value>Langue :</value>
</data>
<data name="LoginQuote" xml:space="preserve">
<value>Chargement des citations...</value>
</data>
<data name="QuoteValid" xml:space="preserve">
<value>Citations en attente de validation :</value>
</data>
<data name="Source" xml:space="preserve">
<value>Source :</value>
</data>
<data name="TitleValid" xml:space="preserve">
<value>Citations non validées</value>
</data>
<data name="User" xml:space="preserve">
<value>Utilisateur :</value>
</data>
</root>

@ -0,0 +1,32 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Text.Json;
using System.Threading.Tasks;
using WF_WebAdmin.Converter;
using WF_WebAdmin.Model;
namespace WF_WebAdmin.Service
{
public class CommentaryServiceStub : ICommentaryService
{
private readonly string? _jsonFilePath = Path.Combine(Environment.CurrentDirectory, "wwwroot", "fake-dataCommentary.json");
public async Task<List<Commentary>> GetCommentsAsync()
{
if (!File.Exists(_jsonFilePath))
{
Console.Out.WriteLine($"{_jsonFilePath} not found");
return new List<Commentary>();
}
var json = await File.ReadAllTextAsync(_jsonFilePath);
var dtoList = JsonSerializer.Deserialize<List<CommentaryDto>>(json) ?? new List<CommentaryDto>();
var comments = dtoList.ConvertAll(dto => dto.ToModel());
Console.Out.WriteLine($"Nombre de commentaires chargés : {comments.Count}");
return comments;
}
}
}

@ -0,0 +1,11 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using WF_WebAdmin.Model;
namespace WF_WebAdmin.Service
{
public interface ICommentaryService
{
Task<List<Commentary>> GetCommentsAsync();
}
}

@ -0,0 +1,17 @@
using WF_WebAdmin.Model;
namespace WF_WebAdmin.Service
{
public interface ILogsService
{
public Task removeLogs(Logs logs);
public Task<List<Logs>> getAllLogs();
public Task<List<Logs>> getSomeLogs(int nb, int page);
public Task addLogs(Logs logs);
public Task<int> getNbLogs();
}
}

@ -0,0 +1,26 @@
using WF_WebAdmin.Model;
namespace WF_WebAdmin.Service
{
public interface IQuizService
{
public Task addQuiz(Quiz quiz);
public Task updateQuiz(Quiz quiz);
public Task removeQuiz(int id);
public Task validateQuiz(int id);
public Task<List<Quiz>> getQuizzes();
public Task<List<Quiz>> getQuizzesToValidate();
public Task<Quiz> getQuiz(int id);
public Task<List<Quiz>> getSommeQuiz(int nb, int page);
public Task<int> getNbQuiz();
}
}

@ -0,0 +1,33 @@
using WF_WebAdmin.Model;
namespace WF_WebAdmin.Service
{
public interface IQuoteService
{
public Task addQuote(Quote quote);
public Task removeQuote(Quote quote);
public Task validQuote(Quote? quote);
public Task updateQuote(Quote? quote);
public Task<List<Quote>> getAllQuote();
public Task<List<Quote>> getSomeQuote(int nb, int page);
public Task<Quote?> getOnequote(int id);
public Task<List<Quote>> reserchQuote(string reserch, List<string> argument);
public Task<List<Quote>> getAllQuoteInvalid();
public Task<List<Quote>> getSomeQuoteInvalid(int nb, int page);
public Task<int> getNbQuote();
public Task<List<Character>> getChar();
public Task<List<Source>> getSrc();
}
}

@ -0,0 +1,25 @@
using WF_WebAdmin.Model;
namespace WF_WebAdmin.Service
{
public interface IUserService
{
public Task removeUser(User user);
public Task updateRole(User? user);
public Task downgradeRole(User? user);
public Task updateUser(User? user);
public Task<List<User>> getAllUser();
public Task<List<User>?> getSomeUser(int nb, int page);
public Task<User> getOneUser(int id);
public Task<List<User>> reserchUsers(string reserch, List<string> args);
public Task<int> getNbUser();
}
}

@ -0,0 +1,67 @@
using Microsoft.AspNetCore.Mvc.RazorPages;
using System.Text.Json;
using WF_WebAdmin.Model;
namespace WF_WebAdmin.Service
{
public class LogsServiceStub : ILogsService
{
private readonly string _jsonFilePath = Path.Combine(Environment.CurrentDirectory, "wwwroot", "fake_data_logs.json");
public async Task saveLogsJson(List<Logs> logs)
{
var json = JsonSerializer.Serialize(logs, new JsonSerializerOptions { WriteIndented = true });
await File.WriteAllTextAsync(_jsonFilePath, json);
}
public async Task addLogs(Logs logs)
{
var data = await getAllLogs();
data.Add(logs);
await saveLogsJson(data);
}
public async Task<List<Logs>> getAllLogs()
{
if (!File.Exists(_jsonFilePath))
{
Console.Out.WriteLine($"{_jsonFilePath} not found");
return new List<Logs>();
}
var json = await File.ReadAllTextAsync(_jsonFilePath);
return JsonSerializer.Deserialize<List<Logs>>(json) ?? new List<Logs>();
}
public Task<int> getNbLogs()
{
throw new NotImplementedException();
}
public async Task<List<Logs>> getSomeLogs(int nb, int page)
{
var logs = await getAllLogs();
if ((page - 1) * nb + nb > logs.Count)
{
return logs.GetRange(logs.Count - nb, nb);
}
return logs.GetRange((page - 1) * nb, nb);
}
public async Task removeLogs(Logs logs)
{
var data = await getAllLogs();
var l = data.FirstOrDefault(p => p.Message ==logs.Message && p.LogLevel==logs.LogLevel);
if (l != null)
{
data.Remove(l);
await saveLogsJson(data);
}
}
}
}

@ -1,25 +0,0 @@
using WF_WebAdmin.Model;
namespace WF_WebAdmin.Service;
public class QuizService
{
public List<Quiz> GetQuizToConfirm()
{
var res = new List<Quiz>();
return res;
}
public bool AddQuiz(Quiz quiz)
{
var res = false;
return res;
}
public bool RemoveQuiz(Quiz quiz)
{
var res = false;
return res;
}
}

@ -0,0 +1,202 @@
using System.Text.Json;
using WF_WebAdmin.Model;
namespace WF_WebAdmin.Service;
public class QuizServiceStub: IQuizService
{
private readonly string _jsonFilePath = Path.Combine(Environment.CurrentDirectory, "wwwroot", "fake_data_quiz.json");
/// <summary>
/// Asynchronously saves a list of quiz objects to a JSON file.
/// </summary>
/// <param name="quizzes">A list of <see cref="Quiz"/> objects to be serialized and saved.</param>
/// <returns>A task representing the asynchronous operation.</returns>
/// <remarks>
/// This method serializes the list of quizzes to a well-formatted JSON string and saves it
/// to a specified file path. The <paramref name="quizzes"/> list is serialized using
/// <see cref="JsonSerializer"/> with indented formatting to make the JSON human-readable.
/// </remarks>
public async Task saveQuizJson(List<Quiz> quizzes)
{
var json = JsonSerializer.Serialize(quizzes, new JsonSerializerOptions { WriteIndented = true });
await File.WriteAllTextAsync(_jsonFilePath, json);
}
/// <summary>
/// Asynchronously adds a new quiz to the list of quizzes and saves the updated list to a JSON file.
/// </summary>
/// <param name="quiz">The <see cref="Quiz"/> object to be added to the list of quizzes.</param>
/// <returns>A task representing the asynchronous operation.</returns>
/// <remarks>
/// This method retrieves the current list of quizzes using <see cref="getQuizzes"/>, assigns a unique ID to the
/// new quiz (based on the highest existing ID), and adds the new quiz to the list. Afterward, the updated list
/// of quizzes is saved back to the JSON file using <see cref="saveQuizJson"/>. The new quiz will have an ID
/// that's one greater than the highest existing ID or 1 if no quizzes exist.
/// </remarks>
public async Task addQuiz(Quiz quiz)
{
var data = await getQuizzes();
quiz.Id = data.Count > 0 ? data.Max(p => p.Id) + 1 : 1;
data.Add(quiz);
await saveQuizJson(data);
}
/// <summary>
/// Asynchronously updates an existing quiz in the list of quizzes and saves the updated list to a JSON file.
/// </summary>
/// <param name="quiz">The <see cref="Quiz"/> object containing the updated data.</param>
/// <returns>A task representing the asynchronous operation.</returns>
/// <remarks>
/// This method retrieves the current list of quizzes using <see cref="getQuizzes"/>, searches for the quiz
/// with the same ID as the one provided, and updates its properties with the new values from the given quiz object.
/// If the quiz is found, the updated list is saved back to the JSON file using <see cref="saveQuizJson"/>.
/// If no quiz with the matching ID is found, no update is performed.
/// </remarks>
public async Task updateQuiz(Quiz quiz)
{
var data = await getQuizzes();
var existingQuiz = data.FirstOrDefault(q => q.Id == quiz.Id);
if (existingQuiz != null)
{
existingQuiz.Question = quiz.Question;
existingQuiz.AnswerA = quiz.AnswerA;
existingQuiz.AnswerB = quiz.AnswerB;
existingQuiz.AnswerC = quiz.AnswerC;
existingQuiz.AnswerD = quiz.AnswerD;
existingQuiz.CAnswer = quiz.CAnswer;
existingQuiz.IsValid = quiz.IsValid;
existingQuiz.UserProposition = quiz.UserProposition;
await saveQuizJson(data);
}
}
/// <summary>
/// Asynchronously removes a quiz from the list of quizzes by its ID and saves the updated list to a JSON file.
/// </summary>
/// <param name="id">The ID of the <see cref="Quiz"/> to be removed.</param>
/// <returns>A task representing the asynchronous operation.</returns>
/// <remarks>
/// This method retrieves the current list of quizzes using <see cref="getQuizzes"/>, searches for the quiz
/// with the specified ID, and removes it from the list if found. After removal, the updated list of quizzes is
/// saved back to the JSON file using <see cref="saveQuizJson"/>. If no quiz with the matching ID is found,
/// no changes are made.
/// </remarks>
public async Task removeQuiz(int id)
{
var data = await getQuizzes();
var quiz = data.FirstOrDefault(q => q.Id == id);
if (quiz != null)
{
data.Remove(quiz);
await saveQuizJson(data);
}
}
public Task validateQuiz(int id)
{
throw new NotImplementedException();
}
/// <summary>
/// Asynchronously retrieves the list of quizzes from a JSON file.
/// </summary>
/// <returns>A task representing the asynchronous operation, with a <see cref="List{Quiz}"/> result containing the quizzes.</returns>
/// <remarks>
/// This method checks if the JSON file exists at the specified file path. If the file does not exist, it logs a
/// message to the console and returns an empty list of quizzes. If the file exists, it reads the JSON content,
/// deserializes it into a list of <see cref="Quiz"/> objects, and returns the list. If the deserialization is
/// unsuccessful or the file is empty, it returns an empty list instead.
/// </remarks>
public async Task<List<Quiz>> getQuizzes()
{
if (!File.Exists(_jsonFilePath))
{
Console.Out.WriteLine($"{_jsonFilePath} not found");
return new List<Quiz>();
}
var json = await File.ReadAllTextAsync(_jsonFilePath);
return JsonSerializer.Deserialize<List<Quiz>>(json) ?? new List<Quiz>();
}
/// <summary>
/// Asynchronously retrieves the list of quizzes that are marked as invalid and need validation.
/// </summary>
/// <returns>A task representing the asynchronous operation, with a <see cref="List{Quiz}"/> result containing quizzes that are not valid.</returns>
/// <remarks>
/// This method retrieves the full list of quizzes using <see cref="getQuizzes"/> and filters it to return only those
/// quizzes where the <see cref="Quiz.IsValid"/> property is set to <c>false</c>. The filtered list is then returned.
/// If no quizzes are invalid, an empty list will be returned.
/// </remarks>
public async Task<List<Quiz>> getQuizzesToValidate()
{
var quizzes = await getQuizzes();
return quizzes.Where(quiz => !quiz.IsValid).ToList();
}
/// <summary>
/// Asynchronously retrieves a specific quiz by its ID from the list of quizzes.
/// </summary>
/// <param name="id">The ID of the <see cref="Quiz"/> to retrieve.</param>
/// <returns>A task representing the asynchronous operation, with a <see cref="Quiz"/> result containing the matching quiz, or <c>null</c> if not found.</returns>
/// <remarks>
/// This method retrieves the full list of quizzes using <see cref="getQuizzes"/> and searches for a quiz with
/// the specified ID. If a quiz with the matching ID is found, it is returned; otherwise, the method returns <c>null</c>.
/// </remarks>
public async Task<Quiz> getQuiz(int id)
{
var data = await getQuizzes();
var q = data.FirstOrDefault(p => p.Id == id);
if (q == null)
{
throw new KeyNotFoundException($"Quiz with ID {id} not found.");
}
return q;
}
/// <summary>
/// Asynchronously retrieves a paginated list of quizzes, returning a specific number of quizzes for the given page.
/// </summary>
/// <param name="nb">The number of quizzes to retrieve per page.</param>
/// <param name="page">The page number to retrieve, where the first page is 1.</param>
/// <returns>A task representing the asynchronous operation, with a <see cref="List{Quiz}"/> result containing the quizzes for the specified page.</returns>
/// <remarks>
/// This method retrieves the full list of quizzes using <see cref="getQuizzes"/> and returns a subset of quizzes based
/// on the specified page number and the number of quizzes per page. If the requested page exceeds the available quizzes,
/// the method returns the last page with the remaining quizzes. If the number of quizzes requested per page exceeds the
/// total number of quizzes, the method will return all quizzes available.
/// </remarks>
public async Task<List<Quiz>> getSommeQuiz(int nb, int page)
{
var data = await getQuizzes();
if ((page - 1) * nb + nb > data.Count)
{
if (nb > data.Count)
{
return data.GetRange(0, data.Count - 1);
}
return data.GetRange(data.Count - nb, nb);
}
return data.GetRange((page - 1) * nb, nb);
}
/// <summary>
/// Asynchronously retrieves the total number of quizzes in the list.
/// </summary>
/// <returns>A task representing the asynchronous operation, with an <see cref="int"/> result containing the total number of quizzes.</returns>
/// <remarks>
/// This method retrieves the full list of quizzes using <see cref="getQuizzes"/> and returns the count of quizzes in the list.
/// It simply returns the number of quizzes available in the data source.
/// </remarks>
public async Task<int> getNbQuiz()
{
var data = await getQuizzes();
return data.Count;
}
}

@ -0,0 +1,198 @@
using WF_WebAdmin.Converter;
using WF_WebAdmin.Model;
using Npgsql;
namespace WF_WebAdmin.Service
{
public class QuoteServiceLocal: IQuoteService
{
private readonly string? _connectionString = "Host=localhost;Port=5432;Username=;Password=;Database=";
/// <summary>
/// Asynchronously adds a new quote to the database and returns the corresponding <see cref="QuoteDto"/>.
/// </summary>
/// <param name="quote">The <see cref="Quote"/> object to be added to the database.</param>
/// <returns>A task representing the asynchronous operation, with a <see cref="QuoteDto"/> result containing the added quote's data.</returns>
/// <remarks>
/// This method converts the provided <see cref="Quote"/> object into a <see cref="QuoteDto"/> using <see cref="QuoteExtension"/>.
/// It then inserts the quote into the PostgreSQL database using a parameterized SQL query with the help of Npgsql.
/// After successfully inserting the quote, the corresponding <see cref="QuoteDto"/> is returned to the caller.
/// Error handling is in place to catch any issues during the database insertion process, with the exception message logged in case of failure.
/// </remarks>
public async Task<QuoteDto> AddQuoteAsync(Quote? quote)
{
QuoteExtension extension = new QuoteExtension();
QuoteDto quoteDTO = extension.QuoteToDTO(quote);
// Utilisation de NpgsqlConnection pour PostgreSQL
using (var connection = new NpgsqlConnection(_connectionString))
{
// Définir la requête SQL d'insertion
var commandText = "INSERT INTO Quote (content, langue, reason, id_source, id_caracter, id_user_verif, img_path) " +
"VALUES (@content, @langue, @reason, @source, @character, @user, @img_path)";
// Créer une commande Npgsql
var command = new NpgsqlCommand(commandText, connection);
/*
Ajouter des paramètres à la commande
command.Parameters.AddWithValue("@content", quote.Content);
command.Parameters.AddWithValue("@langue", quote.Langue);
command.Parameters.AddWithValue("@reason", "À vérifier"); // Vous pouvez changer ça si nécessaire
command.Parameters.AddWithValue("@source", quote.Source);
command.Parameters.AddWithValue("@character", quote.Character);
command.Parameters.AddWithValue("@user", quote.User); // Assurez-vous que `quote.User` est correctement défini
command.Parameters.AddWithValue("@img_path", quote.ImgPath);
*/
try
{
// Ouvrir la connexion à la base de données
await connection.OpenAsync();
// Exécuter la commande d'insertion
await command.ExecuteNonQueryAsync();
}
catch (Exception ex)
{
// Gérer les erreurs ici (par exemple, afficher ou enregistrer les erreurs)
Console.WriteLine($"Une erreur est survenue lors de l'ajout de la citation : {ex.Message}");
}
finally
{
// Fermer la connexion (automatiquement géré avec `using`, mais ajouté pour explicitement montrer le processus)
await connection.CloseAsync();
}
}
// Retourner l'objet DTO pour que vous puissiez l'utiliser ailleurs dans votre application
return quoteDTO;
}
/// <summary>
/// Asynchronously handles the removal of a quote and returns the corresponding <see cref="QuoteDto"/>.
/// </summary>
/// <param name="quote">The <see cref="Quote"/> object to be removed.</param>
/// <returns>A task representing the asynchronous operation, with a <see cref="QuoteDto"/> result corresponding to the removed quote.</returns>
/// <remarks>
/// This method takes a <see cref="Quote"/> object, converts it into a <see cref="QuoteDto"/> using the
/// <see cref="QuoteExtension"/>, and then returns the DTO. Note that while this function is named `RemoveQuote`,
/// it currently only converts the quote to a DTO and does not actually perform any database removal operation.
/// You may need to implement additional logic to remove the quote from the database.
/// </remarks>
public Task RemoveQuote(Quote? quote)
{
QuoteExtension extension = new QuoteExtension();
QuoteDto quoteDTO = extension.QuoteToDTO(quote);
// Return the DTO as the result of this asynchronous operation (though no removal logic is currently implemented)
return Task.FromResult(quoteDTO);
}
/// <summary>
/// Asynchronously validates a quote and returns the corresponding <see cref="QuoteDto"/>.
/// </summary>
/// <param name="quote">The <see cref="Quote"/> object to be validated.</param>
/// <returns>A task representing the asynchronous operation, with a <see cref="QuoteDto"/> result corresponding to the validated quote.</returns>
/// <remarks>
/// This method takes a <see cref="Quote"/> object, converts it into a <see cref="QuoteDto"/> using the
/// <see cref="QuoteExtension"/>, and returns the DTO. The method is named `validQuote`, but currently, it only
/// converts the quote into a DTO and does not perform any actual validation logic.
/// If you intend to validate the quote (e.g., updating its status in a database), you will need to implement
/// the actual validation logic separately.
/// </remarks>
public Task validQuote(Quote? quote)
{
QuoteExtension extension = new QuoteExtension();
QuoteDto quoteDto = extension.QuoteToDTO(quote);
// Return the DTO as the result of this asynchronous operation (though no validation logic is currently implemented)
return Task.FromResult(quoteDto);
}
/// <summary>
/// Asynchronously updates a quote and returns the corresponding <see cref="QuoteDto"/>.
/// </summary>
/// <param name="quote">The <see cref="Quote"/> object to be updated.</param>
/// <returns>A task representing the asynchronous operation, with a <see cref="QuoteDto"/> result corresponding to the updated quote.</returns>
/// <remarks>
/// This method takes a <see cref="Quote"/> object, converts it into a <see cref="QuoteDto"/> using the
/// <see cref="QuoteExtension"/>, and returns the DTO. The method is named `updateQuote`, but currently, it only
/// converts the quote into a DTO and does not perform any actual update logic.
/// If you intend to update the quote (e.g., modifying the quote in a database or data source),
/// you will need to implement the actual update logic separately.
/// </remarks>
public Task updateQuote(Quote? quote)
{
QuoteExtension extension = new QuoteExtension();
QuoteDto quoteDTO = extension.QuoteToDTO(quote);
// Return the DTO as the result of this asynchronous operation (though no update logic is currently implemented)
return Task.FromResult(quoteDTO);
}
public Task addQuote(Quote quote)
{
throw new NotImplementedException();
}
public Task removeQuote(Quote quote)
{
throw new NotImplementedException();
}
public Task<List<Quote>> getAllQuote()
{
throw new NotImplementedException();
}
public Task<List<Quote>> getSomeQuote(int nb, int page)
{
throw new NotImplementedException();
}
public Task<List<Quote>> reserchQuote(string reserch, List<string> argument)
{
throw new NotImplementedException();
}
public Task<List<Quote>> getAllQuoteInvalid()
{
throw new NotImplementedException();
}
public Task<List<Quote>> getSomeQuoteInvalid(int nb, int page)
{
throw new NotImplementedException();
}
public Task<Quote?> getOnequote(int id)
{
throw new NotImplementedException();
}
public Task<int> getNbQuote()
{
throw new NotImplementedException();
}
public Task<List<Character>> getChar()
{
throw new NotImplementedException();
}
public Task<List<Source>> getSrc()
{
throw new NotImplementedException();
}
}
}

@ -0,0 +1,293 @@
using System.Text.Json;
using WF_WebAdmin.Model;
namespace WF_WebAdmin.Service;
public class QuoteServiceStub : IQuoteService
{
private readonly string _jsonFilePath = Path.Combine(Environment.CurrentDirectory, "wwwroot", "fake-dataQuote.json");
private readonly string _char = Path.Combine(Environment.CurrentDirectory, "wwwroot", "fake-dataCaracter.json");
private readonly string _src = Path.Combine(Environment.CurrentDirectory, "wwwroot", "fake-dataSource.json");
/// <summary>
/// Asynchronously saves a list of quotes to a JSON file.
/// </summary>
/// <param name="quotes">The list of <see cref="Quote"/> objects to be serialized and saved to the file.</param>
/// <returns>A task representing the asynchronous operation of saving the quotes to the file.</returns>
/// <remarks>
/// This method serializes the provided list of <see cref="Quote"/> objects into JSON format using <see cref="JsonSerializer"/>.
/// The serialized JSON is then saved to the file path specified in the <see cref="_jsonFilePath"/> field. The JSON is written
/// with indentation for better readability.
/// If the file does not already exist, it will be created.
/// </remarks>
public async Task saveQuoteJson(List<Quote> quotes)
{
var json = JsonSerializer.Serialize(quotes, new JsonSerializerOptions { WriteIndented = true });
await File.WriteAllTextAsync(_jsonFilePath, json);
}
/// <summary>
/// Asynchronously adds a new quote to the list and saves it to a JSON file.
/// </summary>
/// <param name="quote">The <see cref="Quote"/> object to be added to the list.</param>
/// <returns>A task representing the asynchronous operation of adding the quote and saving the updated list to the file.</returns>
/// <remarks>
/// This method retrieves the current list of quotes using the <see cref="getAllQuote"/> method, assigns a new ID to the
/// provided quote (incremented from the maximum existing ID), and adds the quote to the list. After updating the list,
/// the method saves the updated list back to the JSON file using <see cref="saveQuoteJson"/>.
/// If the list is empty, the new quote is assigned an ID of 1.
/// </remarks>
public async Task addQuote(Quote quote)
{
var data = await getAllQuote();
quote.Id = data.Count > 0 ? data.Max(p => p.Id) + 1 : 1;
data.Add(quote);
await saveQuoteJson(data);
}
/// <summary>
/// Asynchronously removes a quote from the list and saves the updated list to a JSON file.
/// </summary>
/// <param name="quote">The <see cref="Quote"/> object to be removed from the list.</param>
/// <returns>A task representing the asynchronous operation of removing the quote and saving the updated list to the file.</returns>
/// <remarks>
/// This method retrieves the current list of quotes using the <see cref="getAllQuote"/> method.
/// It searches for the provided quote by its `Id` and, if found, removes it from the list.
/// After removing the quote, the method saves the updated list back to the JSON file using <see cref="saveQuoteJson"/>.
/// If the quote is not found in the list, no action is taken.
/// </remarks>
public async Task removeQuote(Quote quote)
{
var data = await getAllQuote();
var q = data.FirstOrDefault(p => p.Id == quote.Id);
if (q != null)
{
data.Remove(q);
await saveQuoteJson(data);
}
}
public Task validQuote(Quote? quote)
{
throw new NotImplementedException();
}
/// <summary>
/// Asynchronously updates the details of an existing quote and saves the updated list to a JSON file.
/// </summary>
/// <param name="quote">The <see cref="Quote"/> object containing the updated details of the quote.</param>
/// <returns>A task representing the asynchronous operation of updating the quote and saving the updated list to the file.</returns>
/// <remarks>
/// This method retrieves the current list of quotes using the <see cref="getAllQuote"/> method.
/// It searches for the quote with the provided `Id` and, if found, updates its properties (e.g., content, character, image path, etc.)
/// with the values from the provided `quote` object. After updating the quote, the method saves the updated list back to the JSON file
/// using <see cref="saveQuoteJson"/>. If the quote with the specified `Id` is not found, no action is taken.
/// </remarks>
public async Task updateQuote(Quote? quote)
{
var data = await getAllQuote();
var q = data.FirstOrDefault(p => p.Id == quote.Id);
if (q != null)
{
q.Content = quote.Content;
q.Charac = quote.Charac;
q.ImgPath = quote.ImgPath;
q.TitleSrc = quote.TitleSrc;
q.DateSrc = quote.DateSrc;
q.Langue = quote.Langue;
await saveQuoteJson(data);
}
}
/// <summary>
/// Asynchronously retrieves all quotes from a JSON file.
/// </summary>
/// <returns>A task representing the asynchronous operation, with a result of a list of <see cref="Quote"/> objects.</returns>
/// <remarks>
/// This method checks if the JSON file exists at the specified file path (<see cref="_jsonFilePath"/>).
/// If the file does not exist, it logs a message and returns an empty list of quotes.
/// If the file exists, it reads the JSON content, deserializes it into a list of <see cref="Quote"/> objects,
/// and returns that list. If the deserialization results in a null value, an empty list is returned.
/// </remarks>
public async Task<List<Quote>> getAllQuote()
{
if (!File.Exists(_jsonFilePath))
{
Console.Out.WriteLine($"{_jsonFilePath} not found");
return new List<Quote>();
}
var json = await File.ReadAllTextAsync(_jsonFilePath);
return JsonSerializer.Deserialize<List<Quote>>(json) ?? new List<Quote>();
}
/// <summary>
/// Asynchronously retrieves a subset of quotes based on the specified page number and the number of quotes per page.
/// </summary>
/// <param name="nb">The number of quotes to retrieve per page.</param>
/// <param name="page">The page number for pagination.</param>
/// <returns>A task representing the asynchronous operation, with a result of a list of <see cref="Quote"/> objects for the specified page.</returns>
/// <remarks>
/// This method retrieves all quotes using the <see cref="getAllQuote"/> method and then calculates the range of quotes
/// to be returned based on the provided `nb` (number of quotes per page) and `page` (the page number). It ensures that
/// the returned subset does not exceed the total number of quotes available.
///
/// If the calculated range is larger than the available quotes, it returns a subset of quotes from the end of the list.
/// If the requested page number exceeds the total number of pages, the method will return the last available page of quotes.
/// </remarks>
public async Task<List<Quote>> getSomeQuote(int nb, int page)
{
var quotes = await getAllQuote();
if ((page - 1) * nb + nb > quotes.Count())
{
if (nb > quotes.Count())
{
return quotes.GetRange(0, quotes.Count());
}
return quotes.GetRange(quotes.Count() - nb, nb);
}
return quotes.GetRange((page - 1) * nb, nb);
}
/// <summary>
/// Asynchronously retrieves a single quote based on its ID.
/// </summary>
/// <param name="id">The unique identifier of the <see cref="Quote"/> to be retrieved.</param>
/// <returns>A task representing the asynchronous operation, with a result of the <see cref="Quote"/> object if found, otherwise null.</returns>
/// <remarks>
/// This method retrieves all quotes using the <see cref="getAllQuote"/> method and searches for the quote that matches the provided `id`.
/// If a matching quote is found, it returns that quote; otherwise, it returns `null`.
/// </remarks>
public async Task<Quote?> getOnequote(int id)
{
var data = await getAllQuote();
var q = data.FirstOrDefault(p => p.Id == id);
if (q == null)
{
throw new KeyNotFoundException($"Quote with ID {id} not found.");
}
return q;
}
public Task<List<Quote>> reserchQuote(string reserch, List<string> argument)
{
throw new NotImplementedException();
}
/// <summary>
/// Asynchronously retrieves all invalid quotes from the list.
/// </summary>
/// <returns>A task representing the asynchronous operation, with a result of a list of invalid <see cref="Quote"/> objects.</returns>
/// <remarks>
/// This method retrieves all quotes using the <see cref="getAllQuote"/> method and filters them by the `IsValid` property.
/// It returns only those quotes where `IsValid` is set to `false`.
/// If no invalid quotes are found, an empty list is returned.
/// </remarks>
public async Task<List<Quote>> getAllQuoteInvalid()
{
var quotes = await getAllQuote();
quotes = quotes.Where(q => !q.IsValid).ToList();
return quotes;
}
/// <summary>
/// Asynchronously retrieves a subset of invalid quotes based on the specified page number and the number of quotes per page.
/// </summary>
/// <param name="nb">The number of invalid quotes to retrieve per page.</param>
/// <param name="page">The page number for pagination.</param>
/// <returns>A task representing the asynchronous operation, with a result of a list of invalid <see cref="Quote"/> objects for the specified page.</returns>
/// <remarks>
/// This method retrieves all invalid quotes using the <see cref="getAllQuoteInvalid"/> method and then calculates the range of invalid quotes
/// to be returned based on the provided `nb` (number of quotes per page) and `page` (the page number). It ensures that
/// the returned subset does not exceed the total number of invalid quotes available.
///
/// If the calculated range is larger than the available invalid quotes, it returns a subset of quotes from the end of the list.
/// If the requested page number exceeds the total number of pages, the method will return the last available page of invalid quotes.
/// </remarks>
public async Task<List<Quote>> getSomeQuoteInvalid(int nb, int page)
{
var quotes = await getAllQuoteInvalid();
if ((page - 1) * nb + nb > quotes.Count)
{
if (nb > quotes.Count)
{
return quotes.GetRange(0, quotes.Count);
}
return quotes.GetRange(quotes.Count - nb, nb);
}
return quotes.GetRange((page - 1) * nb, nb);
}
/// <summary>
/// Asynchronously retrieves the total number of quotes.
/// </summary>
/// <returns>A task representing the asynchronous operation, with a result of the total number of <see cref="Quote"/> objects.</returns>
/// <remarks>
/// This method retrieves all quotes using the <see cref="getAllQuote"/> method and returns the count of quotes.
/// It provides the total number of quotes currently available in the data source.
/// </remarks>
public async Task<int> getNbQuote()
{
var data = await getAllQuote();
return data.Count;
}
/// <summary>
/// Asynchronously retrieves a list of characters from a JSON file.
/// </summary>
/// <returns>A task representing the asynchronous operation, with a result of a list of <see cref="Character"/> objects.</returns>
/// <remarks>
/// This method checks if the JSON file containing character data exists at the specified file path (`_char`).
/// If the file does not exist, it logs a message to the console and returns an empty list of characters.
/// If the file exists, it reads the JSON content, deserializes it into a list of <see cref="Character"/> objects,
/// and returns that list. If the deserialization results in a null value, an empty list is returned.
/// </remarks>
public async Task<List<Character>> getChar()
{
if (!File.Exists(_char))
{
Console.Out.WriteLine($"{_char} not found");
return new List<Character>();
}
var json = await File.ReadAllTextAsync(_char);
return JsonSerializer.Deserialize<List<Character>>(json) ?? new List<Character>();
}
/// <summary>
/// Asynchronously retrieves a list of sources from a JSON file.
/// </summary>
/// <returns>A task representing the asynchronous operation, with a result of a list of <see cref="Source"/> objects.</returns>
/// <remarks>
/// This method checks if the JSON file containing source data exists at the specified file path (`_src`).
/// If the file does not exist, it logs a message to the console and returns an empty list of sources.
/// If the file exists, it reads the JSON content, deserializes it into a list of <see cref="Source"/> objects,
/// and returns that list. If the deserialization results in a null value, an empty list is returned.
/// </remarks>
public async Task<List<Source>> getSrc()
{
if (!File.Exists(_src))
{
Console.Out.WriteLine($"{_src} not found");
return new List<Source>();
}
var json = await File.ReadAllTextAsync(_src);
return JsonSerializer.Deserialize<List<Source>>(json) ?? new List<Source>();
}
}

@ -0,0 +1,193 @@
using System.Text.Json;
using WF_WebAdmin.Model;
namespace WF_WebAdmin.Service;
public class UserServiceStub : IUserService
{
private readonly string _jsonFilePath = Path.Combine(Environment.CurrentDirectory, "wwwroot", "fake_data_users.json");
/// <summary>
/// Asynchronously saves a list of users to a JSON file.
/// </summary>
/// <param name="users">The list of <see cref="User"/> objects to be saved to the file.</param>
/// <returns>A task representing the asynchronous operation.</returns>
/// <remarks>
/// This method serializes the provided list of <see cref="User"/> objects into a JSON format using the `JsonSerializer`.
/// It then writes the serialized JSON string to the file specified by the `_jsonFilePath`. The JSON is written with indentation for readability.
/// </remarks>
public async Task saveUsersJson(List<User> users)
{
var json = JsonSerializer.Serialize(users, new JsonSerializerOptions { WriteIndented = true });
await File.WriteAllTextAsync(_jsonFilePath, json);
}
/// <summary>
/// Asynchronously removes a user from the list of users and saves the updated list to a JSON file.
/// </summary>
/// <param name="user">The <see cref="User"/> object to be removed from the list.</param>
/// <returns>A task representing the asynchronous operation.</returns>
/// <remarks>
/// This method retrieves the list of all users using the <see cref="getAllUser"/> method,
/// then searches for the specified user by their `Id`. If a matching user is found,
/// they are removed from the list, and the updated list is saved back to the JSON file using the <see cref="saveUsersJson"/> method.
/// </remarks>
public async Task removeUser(User user)
{
var data = await getAllUser();
var u = data.FirstOrDefault(p => p.Id == user.Id);
if (u != null)
{
data.Remove(u);
await saveUsersJson(data);
}
}
/// <summary>
/// Asynchronously updates the role of a user, setting the user as an administrator.
/// </summary>
/// <param name="user">The <see cref="User"/> object whose role is to be updated.</param>
/// <returns>A task representing the asynchronous operation of updating the user's role.</returns>
/// <remarks>
/// This method updates the `IsAdmin` property of the specified user to `true`, indicating that the user is an administrator.
/// It then calls the <see cref="updateUser"/> method to persist the updated user information.
/// </remarks>
public Task updateRole(User? user)
{
user.IsAdmin = true;
return updateUser(user);
}
/// <summary>
/// Asynchronously downgrades the role of a user, removing their administrator privileges.
/// </summary>
/// <param name="user">The <see cref="User"/> object whose role is to be downgraded.</param>
/// <returns>A task representing the asynchronous operation of downgrading the user's role.</returns>
/// <remarks>
/// This method updates the `IsAdmin` property of the specified user to `false`, removing their administrator status.
/// It then calls the <see cref="updateUser"/> method to persist the updated user information.
/// </remarks>
public Task downgradeRole(User? user)
{
user.IsAdmin = false;
return updateUser(user);
}
/// <summary>
/// Asynchronously retrieves a list of all users from a JSON file.
/// </summary>
/// <returns>A task representing the asynchronous operation, with a result of a list of <see cref="User"/> objects.</returns>
/// <remarks>
/// This method checks if the JSON file containing user data exists at the specified file path (`_jsonFilePath`).
/// If the file does not exist, it logs a message to the console and returns an empty list of users.
/// If the file exists, it reads the JSON content, deserializes it into a list of <see cref="User"/> objects,
/// and returns that list. If the deserialization results in a null value, an empty list is returned.
/// </remarks>
public async Task<List<User>> getAllUser()
{
if (!File.Exists(_jsonFilePath))
{
Console.Out.WriteLine($"{_jsonFilePath} not found");
return new List<User>();
}
var json = await File.ReadAllTextAsync(_jsonFilePath);
return JsonSerializer.Deserialize<List<User>>(json) ?? new List<User>();
}
/// <summary>
/// Asynchronously retrieves a paginated list of users from a JSON file.
/// </summary>
/// <param name="nb">The number of users to retrieve per page.</param>
/// <param name="page">The page number for the data to retrieve.</param>
/// <returns>A task representing the asynchronous operation, with a result of a list of <see cref="User"/> objects.</returns>
/// <remarks>
/// This method retrieves all users using the <see cref="getAllUser"/> method, then calculates the range of users to return
/// based on the specified page number and the number of users per page (`nb`).
/// It returns the corresponding subset of users for the given page. If the page exceeds the available number of users,
/// it returns the last `nb` users available.
/// </remarks>
public async Task<List<User>?> getSomeUser(int nb, int page)
{
var users = await getAllUser();
if ((page - 1) * nb + nb > users.Count)
{
return users.GetRange(users.Count - nb, nb);
}
return users.GetRange((page - 1) * nb, nb);
}
/// <summary>
/// Asynchronously retrieves a single user by their ID from the JSON file.
/// </summary>
/// <param name="id">The ID of the user to retrieve.</param>
/// <returns>A task representing the asynchronous operation, with a result of the <see cref="User"/> object if found, otherwise null.</returns>
/// <remarks>
/// This method retrieves all users using the <see cref="getAllUser"/> method,
/// then searches for the user with the specified `id`. If a user with the given ID is found,
/// the user is returned. Otherwise, it returns null.
/// </remarks>
public async Task<User> getOneUser(int id)
{
var data = await getAllUser();
var user = data.FirstOrDefault(p => p.Id == id);
if (user == null)
{
throw new KeyNotFoundException($"User with ID {id} not found.");
}
return user;
}
public Task<List<User>> reserchUsers(string reserch, List<string> args)
{
throw new NotImplementedException();
}
/// <summary>
/// Asynchronously retrieves the total number of users from the JSON file.
/// </summary>
/// <returns>A task representing the asynchronous operation, with a result of the total number of users.</returns>
/// <remarks>
/// This method retrieves all users using the <see cref="getAllUser"/> method and returns the count of users in the list.
/// </remarks>
public async Task<int> getNbUser()
{
var data = await getAllUser();
return data.Count;
}
/// <summary>
/// Asynchronously updates the details of a user in the JSON file.
/// </summary>
/// <param name="user">The <see cref="User"/> object containing the updated user details.</param>
/// <returns>A task representing the asynchronous operation of updating the user.</returns>
/// <remarks>
/// This method retrieves all users using the <see cref="getAllUser"/> method, then searches for the user with the specified ID.
/// If a user with the given ID is found, it updates their details (Name, Email, Image, IsAdmin) based on the provided `user` object.
/// After updating the user, the modified list of users is saved back to the JSON file using the <see cref="saveUsersJson"/> method.
/// </remarks>
public async Task updateUser(User? user)
{
var data = await getAllUser();
var person = data.FirstOrDefault(p => p.Id == user.Id);
if (person != null)
{
person.Name = user.Name;
person.Email = user.Email;
person.Image = user.Image;
person.IsAdmin = user.IsAdmin;
await saveUsersJson(data);
}
}
}

@ -0,0 +1,54 @@
@using System.Globalization
@inject NavigationManager NavigationManager
<p>
<label>
Select your locale:
<select @bind="Culture">
@foreach (var culture in supportedCultures)
{
<option value="@culture">@culture.DisplayName</option>
}
</select>
</label>
</p>
@code
{
private CultureInfo[] supportedCultures = new[]
{
new CultureInfo("en-US"),
new CultureInfo("fr-FR")
};
/// <summary>
/// Gets or sets the current culture for the application, triggering a navigation to set the culture cookie when changed.
/// </summary>
/// <remarks>
/// The getter retrieves the current culture of the application using <see cref="CultureInfo.CurrentCulture"/>.
/// The setter checks if the current UI culture matches the provided value. If they are the same, no action is taken.
/// If the cultures differ, it constructs a query string that includes the new culture and a redirect URI,
/// and then navigates to a "/Culture/SetCulture" endpoint to set the culture cookie.
/// The user is redirected to the same page with the new culture applied after the redirect.
/// </remarks>
private CultureInfo Culture
{
get => CultureInfo.CurrentCulture;
set
{
if (CultureInfo.CurrentUICulture == value)
{
return;
}
var culture = value.Name.ToLower(CultureInfo.InvariantCulture);
var uri = new Uri(this.NavigationManager.Uri).GetComponents(UriComponents.PathAndQuery, UriFormat.Unescaped);
var query = $"?culture={Uri.EscapeDataString(culture)}&" + $"redirectUri={Uri.EscapeDataString(uri)}";
// Redirect the user to the culture controller to set the cookie
this.NavigationManager.NavigateTo("/Culture/SetCulture" + query, forceLoad: true);
}
}
}

@ -1,18 +1,40 @@
@inherits LayoutComponentBase @using WF_WebAdmin.Model
@inherits LayoutComponentBase
@inject UserLogin uLogin
<PageTitle>WF-WebAdmin</PageTitle> <PageTitle>WF-WebAdmin</PageTitle>
<MudThemeProvider />
<div class="page"> <div class="page">
@* @if (uLogin.Name != null)
{ *@
<div class="sidebar"> <div class="sidebar">
<NavMenu /> <NavMenu/>
</div> </div>
@*}*@
<main> <main>
<div class="top-row px-4"> <div class="top-row px-4">
<a href="https://docs.microsoft.com/aspnet/" target="_blank">About</a> <div class="px-4">
<CultureSelector />
</div>
@* @if (!string.IsNullOrEmpty(uLogin.Name))
{
<button class="buttonProfil" type="button"> <img class="imageProfil" src="@uLogin.Image" height="90" width="480" /></button>
@* <img class="imageProfil" src="@uLogin.Image" />
}
else
{*@
<img class="imageProfil" src="https://cdn-icons-png.flaticon.com/512/61/61205.png"/>
@* } *@
</div> </div>
<article class="content px-4"> <article class="content px-4">
@Body @Body
</article> </article>
</main> </main>
</div> </div>

@ -0,0 +1,13 @@
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Mvc;
using System;
using WF_WebAdmin.Model;
namespace WF_WebAdmin.Shared
{
public partial class MainLayout
{
}
}

@ -1,6 +1,10 @@
<div class="top-row ps-3 navbar navbar-dark"> @using WF_WebAdmin.Model
@inject UserLogin uLogin
<div class="top-row ps-3 navbar navbar-dark">
<div class="container-fluid"> <div class="container-fluid">
<a class="navbar-brand" href="">Wiki Fantasy</a> <a class="navbar-brand" href="">What the Fantasy</a>
<button title="Navigation menu" class="navbar-toggler" @onclick="ToggleNavMenu"> <button title="Navigation menu" class="navbar-toggler" @onclick="ToggleNavMenu">
<span class="navbar-toggler-icon"></span> <span class="navbar-toggler-icon"></span>
</button> </button>
@ -9,40 +13,57 @@
<div class="@NavMenuCssClass" @onclick="ToggleNavMenu"> <div class="@NavMenuCssClass" @onclick="ToggleNavMenu">
<nav class="flex-column"> <nav class="flex-column">
<div class="nav-item px-3"> <div class="nav-item px-3">
<NavLink class="nav-link" href="" Match="NavLinkMatch.All"> <NavLink class="nav-link" href="">
<span class="oi oi-home" aria-hidden="true"></span> Accueil 🏠 Accueil
</NavLink> </NavLink>
</div> </div>
<div class="nav-item px-3"> <div class="nav-item px-3">
<NavLink class="nav-link" href="ValidQuote"> <NavLink class="nav-link" href="ValidQuote">
<span class="oi oi-list-rich" aria-hidden="true"></span> Validation de citations 📜 Validation de citations
</NavLink> </NavLink>
</div> </div>
<div class="nav-item px-3"> <div class="nav-item px-3">
<NavLink class="nav-link" href="ValidQuiz"> <NavLink class="nav-link" href="ValidQuiz">
<span class="oi oi-list-rich" aria-hidden="true"></span> Validation de quiz 📝 Validation de quiz
</NavLink> </NavLink>
</div> </div>
<div class="nav-item px-3"> <div class="nav-item px-3">
<NavLink class="nav-link" href="deleteuser"> <NavLink class="nav-link" href="deleteuser">
<span class="oi oi-list-rich" aria-hidden="true"></span> Gestion des utilisateurs 👤 Gestion des utilisateurs
</NavLink> </NavLink>
</div> </div>
<div class="nav-item px-3"> <div class="nav-item px-3">
<NavLink class="nav-link" href="modifquote"> <NavLink class="nav-link" href="modifquote">
<span class="oi oi-list-rich" aria-hidden="true"></span> Correction des citations ✍️ Gestion des citations
</NavLink> </NavLink>
</div> </div>
<div class="nav-item px-3">
<NavLink class="nav-link" href="modifquiz">
❓ Gestion des questions
</NavLink>
</div>
<div class="nav-item px-3">
<NavLink class="nav-link" href="logs">
📊 Logs
</NavLink>
</div>
<div class="nav-item px-3">
<NavLink class="nav-link" href="/commentary-chart">
📈 Stats commentaires
</NavLink>
</div>
</nav> </nav>
</div> </div>
@code {
@code {
private bool collapseNavMenu = true; private bool collapseNavMenu = true;
private string? NavMenuCssClass => collapseNavMenu ? "collapse" : null; private string? NavMenuCssClass => collapseNavMenu ? "collapse" : null;
@ -51,4 +72,6 @@
{ {
collapseNavMenu = !collapseNavMenu; collapseNavMenu = !collapseNavMenu;
} }
} }

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 13 KiB

@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk.Web"> <Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup> <PropertyGroup>
<TargetFramework>net6.0</TargetFramework> <TargetFramework>net6.0</TargetFramework>
@ -8,11 +8,16 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Blazored.Modal" Version="7.2.0" />
<PackageReference Include="Blazorise.Bootstrap" Version="1.7.2" /> <PackageReference Include="Blazorise.Bootstrap" Version="1.7.2" />
<PackageReference Include="Blazorise.DataGrid" Version="1.7.2" /> <PackageReference Include="Blazorise.DataGrid" Version="1.7.2" />
<PackageReference Include="Blazorise.Icons.FontAwesome" Version="1.7.2" /> <PackageReference Include="Blazorise.Icons.FontAwesome" Version="1.7.2" />
<PackageReference Include="bootstrap" Version="5.3.3" /> <PackageReference Include="bootstrap" Version="5.3.3" />
<PackageReference Include="Microsoft.Extensions.Localization" Version="9.0.1" />
<PackageReference Include="Microsoft.Extensions.Localization.Abstractions" Version="9.0.1" />
<PackageReference Include="MudBlazor" Version="6.2.0" />
<PackageReference Include="Npgsql" Version="9.0.2" /> <PackageReference Include="Npgsql" Version="9.0.2" />
<PackageReference Include="Blazored.Modal" Version="7.2.0" />
</ItemGroup> </ItemGroup>
</Project> </Project>

@ -9,3 +9,6 @@
@using WF_WebAdmin @using WF_WebAdmin
@using WF_WebAdmin.Shared @using WF_WebAdmin.Shared
@using Blazorise.DataGrid @using Blazorise.DataGrid
@using Blazored.Modal
@using MudBlazor

@ -5,5 +5,8 @@
"Microsoft.AspNetCore": "Warning" "Microsoft.AspNetCore": "Warning"
} }
}, },
"AllowedHosts": "*" "AllowedHosts": "*",
"ConnectionStrings": {
"DefaultConnection": "Host=localhost;Port=5432;Database=wikifantasy3;Username=postgres;Password=postgres"
}
} }

@ -0,0 +1,5 @@
{
"version": "3.0",
"defaultProvider": "cdnjs",
"libraries": []
}

@ -1,4 +1,5 @@
@import url('open-iconic/font/css/open-iconic-bootstrap.min.css'); @import url('open-iconic/font/css/open-iconic-bootstrap.min.css');
@import url('https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100..900;1,100..900&display=swap');
html, body { html, body {
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
@ -6,6 +7,17 @@ html, body {
color: black; color: black;
} }
h1 {
text-align: center;
font-size: 32px;
margin-top: 10%;
font-family: "Roboto", serif;
}
h1:focus { h1:focus {
outline: none; outline: none;
} }
@ -82,8 +94,18 @@ button {
background-color: #C3C4C5; background-color: #C3C4C5;
} }
.imgProfil, .imgQuote { .imgProfil {
border-radius: 25px; border-radius: 25px;
width: 150px; /* Taille standard */
height: 150px; /* Taille standard */
object-fit: cover;
}
.imgQuote {
border-radius: 20px;
width: 300px; /* Taille standard */
height: 300px; /* Taille standard */
object-fit: cover;
} }
.pseudo, .mail, .idUser, .dateCrea, .idQuote, .contentQuote, .CaracterQuote, .SourceQuote, .langueQuote, .UserPropositionQuote { .pseudo, .mail, .idUser, .dateCrea, .idQuote, .contentQuote, .CaracterQuote, .SourceQuote, .langueQuote, .UserPropositionQuote {
@ -105,7 +127,6 @@ button {
left: 0; left: 0;
width: 100%; width: 100%;
height: 100%; height: 100%;
background-color: white;
border-radius:20px; border-radius:20px;
display: flex; display: flex;
justify-content: center; justify-content: center;
@ -114,10 +135,11 @@ button {
} }
.contentPopup { .contentPopup {
background-color: white;
padding: 20px; padding: 20px;
border-radius: 20px; border-radius: 20px;
border: 3px solid black;
display: flex; display: flex;
background-color: white;
flex-direction: column; flex-direction: column;
gap: 10px; gap: 10px;
width: 300px; width: 300px;
@ -152,3 +174,66 @@ td {
height: 24px; height: 24px;
object-fit: contain; object-fit: contain;
} }
.buttonSubmitDiv {
text-align: center;
}
p {
margin-bottom: 2%;
font-size: 20px;
font-family: "Roboto", serif;
}
.login {
width: 35vw;
margin-left: 30.5vw;
margin-top: 3vh;
border-radius: 25px;
padding: 2vw;
background-color: #cfcfcf;
}
/*Page login*/
.buttonSudmite {
border: none;
padding: 2%;
margin-top: 5%;
border-radius: 25px;
width: 50%;
font-size: 1.25em;
background-color: white;
font-family: "Roboto", serif;
}
.connexion {
width: 94%;
height: 40px;
padding-left: 3%;
margin-left: 1%;
margin-top: -1%;
border-radius: 25px;
border: none;
font-size: 15px;
}
.ErrorMsg {
color: red;
}
.imageProfil {
height: auto;
width: 30px;
border-radius: 45%;
}
.buttonProfil{
background-color:transparent;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.9 KiB

@ -0,0 +1,8 @@
[
{
"users": 1
},
{
"users": 4
}
]

@ -0,0 +1,52 @@
[
{
"id_caracter":82,
"caracter": "The Wolf",
"id_img": 1
},
{
"id_caracter":50,
"caracter": "Sirius Black",
"id_img": 2
},
{
"id_caracter":77,
"caracter": "Boromir",
"id_img": 3
},
{
"id_caracter": 29,
"caracter": "Maître Oogway",
"id_img": 4
},
{
"id_caracter":7,
"caracter": "Drago Malefoy",
"id_img": 5
},
{
"id_caracter":44,
"caracter": "TChalla / Black Panther",
"id_img": 6
},
{
"id_caracter":53,
"caracter": "Butch",
"id_img": 7
},
{
"id_caracter": 39,
"caracter": "Coco",
"id_img": 8
},
{
"id_caracter": 34,
"caracter": "John Coffey",
"id_img": 9
},
{
"id_caracter": 38,
"caracter": "Harold",
"id_img": 10
}
]

@ -0,0 +1,702 @@
[
{
"id_comment": 1,
"quote": 19,
"users": 29,
"dateC": "2024-01-22",
"comment": "Citation magnifique."
},
{
"id_comment": 2,
"quote": 6,
"users": 18,
"dateC": "2024-01-20",
"comment": "Paroles sages."
},
{
"id_comment": 3,
"quote": 2,
"users": 8,
"dateC": "2024-01-25",
"comment": "Citation puissante."
},
{
"id_comment": 4,
"quote": 11,
"users": 31,
"dateC": "2024-01-01",
"comment": "Très poétique."
},
{
"id_comment": 5,
"quote": 8,
"users": 6,
"dateC": "2024-02-06",
"comment": "Belle pensée."
},
{
"id_comment": 6,
"quote": 13,
"users": 37,
"dateC": "2024-02-01",
"comment": "Citation exceptionnelle."
},
{
"id_comment": 7,
"quote": 2,
"users": 33,
"dateC": "2024-02-11",
"comment": "Belle pensée."
},
{
"id_comment": 8,
"quote": 7,
"users": 28,
"dateC": "2024-02-07",
"comment": "Très émouvant."
},
{
"id_comment": 9,
"quote": 1,
"users": 48,
"dateC": "2024-03-05",
"comment": "Très motivant."
},
{
"id_comment": 10,
"quote": 16,
"users": 14,
"dateC": "2024-03-13",
"comment": "Très motivant."
},
{
"id_comment": 11,
"quote": 10,
"users": 9,
"dateC": "2024-03-13",
"comment": "Très touchant."
},
{
"id_comment": 12,
"quote": 4,
"users": 44,
"dateC": "2024-03-01",
"comment": "Très touchant."
},
{
"id_comment": 13,
"quote": 9,
"users": 8,
"dateC": "2024-04-04",
"comment": "Citation magnifique."
},
{
"id_comment": 14,
"quote": 3,
"users": 49,
"dateC": "2024-04-18",
"comment": "Très émouvant."
},
{
"id_comment": 15,
"quote": 19,
"users": 3,
"dateC": "2024-04-07",
"comment": "Très motivant."
},
{
"id_comment": 16,
"quote": 4,
"users": 9,
"dateC": "2024-04-25",
"comment": "Très motivant."
},
{
"id_comment": 17,
"quote": 17,
"users": 40,
"dateC": "2024-05-04",
"comment": "Très émouvant."
},
{
"id_comment": 18,
"quote": 6,
"users": 21,
"dateC": "2024-05-11",
"comment": "Très poétique."
},
{
"id_comment": 19,
"quote": 16,
"users": 3,
"dateC": "2024-05-08",
"comment": "Citation exceptionnelle."
},
{
"id_comment": 20,
"quote": 1,
"users": 17,
"dateC": "2024-05-04",
"comment": "Très touchant."
},
{
"id_comment": 21,
"quote": 14,
"users": 34,
"dateC": "2024-06-01",
"comment": "Citation magnifique."
},
{
"id_comment": 22,
"quote": 12,
"users": 23,
"dateC": "2024-06-03",
"comment": "Citation magnifique."
},
{
"id_comment": 23,
"quote": 11,
"users": 47,
"dateC": "2024-06-05",
"comment": "Citation magnifique."
},
{
"id_comment": 24,
"quote": 16,
"users": 28,
"dateC": "2024-06-07",
"comment": "Citation magnifique."
},
{
"id_comment": 25,
"quote": 19,
"users": 39,
"dateC": "2024-07-01",
"comment": "Citation magnifique."
},
{
"id_comment": 26,
"quote": 13,
"users": 31,
"dateC": "2024-07-02",
"comment": "Citation magnifique."
},
{
"id_comment": 27,
"quote": 1,
"users": 33,
"dateC": "2024-07-03",
"comment": "Citation magnifique."
},
{
"id_comment": 28,
"quote": 17,
"users": 20,
"dateC": "2024-07-04",
"comment": "Citation magnifique."
},
{
"id_comment": 29,
"quote": 13,
"users": 29,
"dateC": "2024-08-01",
"comment": "Citation magnifique."
},
{
"id_comment": 30,
"quote": 11,
"users": 27,
"dateC": "2024-08-02",
"comment": "Citation magnifique."
},
{
"id_comment": 31,
"quote": 18,
"users": 35,
"dateC": "2024-08-03",
"comment": "Citation magnifique."
},
{
"id_comment": 32,
"quote": 13,
"users": 32,
"dateC": "2024-08-04",
"comment": "Citation magnifique."
},
{
"id_comment": 33,
"quote": 13,
"users": 3,
"dateC": "2024-09-01",
"comment": "Citation magnifique."
},
{
"id_comment": 34,
"quote": 15,
"users": 43,
"dateC": "2024-09-02",
"comment": "Citation magnifique."
},
{
"id_comment": 35,
"quote": 11,
"users": 15,
"dateC": "2024-09-03",
"comment": "Citation magnifique."
},
{
"id_comment": 36,
"quote": 10,
"users": 22,
"dateC": "2024-09-04",
"comment": "Citation magnifique."
},
{
"id_comment": 37,
"quote": 17,
"users": 23,
"dateC": "2024-10-01",
"comment": "Citation magnifique."
},
{
"id_comment": 38,
"quote": 14,
"users": 40,
"dateC": "2024-10-02",
"comment": "Citation magnifique."
},
{
"id_comment": 39,
"quote": 15,
"users": 41,
"dateC": "2024-10-03",
"comment": "Citation magnifique."
},
{
"id_comment": 40,
"quote": 16,
"users": 42,
"dateC": "2024-10-04",
"comment": "Citation magnifique."
},
{
"id_comment": 41,
"quote": 10,
"users": 39,
"dateC": "2024-11-01",
"comment": "Citation magnifique."
},
{
"id_comment": 42,
"quote": 17,
"users": 43,
"dateC": "2024-11-02",
"comment": "Citation magnifique."
},
{
"id_comment": 43,
"quote": 13,
"users": 27,
"dateC": "2024-11-03",
"comment": "Citation magnifique."
},
{
"id_comment": 44,
"quote": 12,
"users": 29,
"dateC": "2024-11-04",
"comment": "Citation magnifique."
},
{
"id_comment": 45,
"quote": 11,
"users": 32,
"dateC": "2024-12-01",
"comment": "Citation magnifique."
},
{
"id_comment": 46,
"quote": 15,
"users": 31,
"dateC": "2024-12-02",
"comment": "Citation magnifique."
},
{
"id_comment": 47,
"quote": 18,
"users": 33,
"dateC": "2024-12-03",
"comment": "Citation magnifique."
},
{
"id_comment": 48,
"quote": 14,
"users": 34,
"dateC": "2024-12-04",
"comment": "Citation magnifique."
},
{
"id_comment": 49,
"quote": 19,
"users": 35,
"dateC": "2024-12-05",
"comment": "Citation magnifique."
},
{
"id_comment": 50,
"quote": 17,
"users": 36,
"dateC": "2024-12-06",
"comment": "Citation magnifique."
},
{
"id_comment": 51,
"quote": 16,
"users": 37,
"dateC": "2024-12-07",
"comment": "Citation magnifique."
},
{
"id_comment": 52,
"quote": 13,
"users": 38,
"dateC": "2024-12-08",
"comment": "Citation magnifique."
},
{
"id_comment": 53,
"quote": 12,
"users": 39,
"dateC": "2024-12-09",
"comment": "Citation magnifique."
},
{
"id_comment": 54,
"quote": 11,
"users": 40,
"dateC": "2024-12-10",
"comment": "Citation magnifique."
},
{
"id_comment": 55,
"quote": 10,
"users": 41,
"dateC": "2024-12-11",
"comment": "Citation magnifique."
},
{
"id_comment": 56,
"quote": 9,
"users": 42,
"dateC": "2024-12-12",
"comment": "Citation magnifique."
},
{
"id_comment": 57,
"quote": 8,
"users": 43,
"dateC": "2024-12-13",
"comment": "Citation magnifique."
},
{
"id_comment": 58,
"quote": 7,
"users": 44,
"dateC": "2024-12-14",
"comment": "Citation magnifique."
},
{
"id_comment": 59,
"quote": 6,
"users": 45,
"dateC": "2024-12-15",
"comment": "Citation magnifique."
},
{
"id_comment": 60,
"quote": 5,
"users": 46,
"dateC": "2024-12-16",
"comment": "Citation magnifique."
},
{
"id_comment": 61,
"quote": 4,
"users": 47,
"dateC": "2024-12-17",
"comment": "Citation magnifique."
},
{
"id_comment": 62,
"quote": 3,
"users": 48,
"dateC": "2024-12-18",
"comment": "Citation magnifique."
},
{
"id_comment": 63,
"quote": 2,
"users": 49,
"dateC": "2024-12-19",
"comment": "Citation magnifique."
},
{
"id_comment": 64,
"quote": 1,
"users": 50,
"dateC": "2024-12-20",
"comment": "Citation magnifique."
},
{
"id_comment": 65,
"quote": 19,
"users": 1,
"dateC": "2024-12-21",
"comment": "Citation magnifique."
},
{
"id_comment": 66,
"quote": 18,
"users": 2,
"dateC": "2024-12-22",
"comment": "Citation magnifique."
},
{
"id_comment": 67,
"quote": 17,
"users": 3,
"dateC": "2024-12-23",
"comment": "Citation magnifique."
},
{
"id_comment": 68,
"quote": 16,
"users": 4,
"dateC": "2024-12-24",
"comment": "Citation magnifique."
},
{
"id_comment": 69,
"quote": 15,
"users": 5,
"dateC": "2024-12-25",
"comment": "Citation magnifique."
},
{
"id_comment": 70,
"quote": 14,
"users": 6,
"dateC": "2024-12-26",
"comment": "Citation magnifique."
},
{
"id_comment": 71,
"quote": 13,
"users": 7,
"dateC": "2024-12-27",
"comment": "Citation magnifique."
},
{
"id_comment": 72,
"quote": 12,
"users": 8,
"dateC": "2024-12-28",
"comment": "Citation magnifique."
},
{
"id_comment": 73,
"quote": 11,
"users": 9,
"dateC": "2024-01-01",
"comment": "Citation magnifique."
},
{
"id_comment": 74,
"quote": 10,
"users": 10,
"dateC": "2024-01-02",
"comment": "Citation magnifique."
},
{
"id_comment": 75,
"quote": 9,
"users": 11,
"dateC": "2024-01-03",
"comment": "Citation magnifique."
},
{
"id_comment": 76,
"quote": 8,
"users": 12,
"dateC": "2024-01-04",
"comment": "Citation magnifique."
},
{
"id_comment": 77,
"quote": 7,
"users": 13,
"dateC": "2024-01-05",
"comment": "Citation magnifique."
},
{
"id_comment": 78,
"quote": 6,
"users": 14,
"dateC": "2024-01-06",
"comment": "Citation magnifique."
},
{
"id_comment": 79,
"quote": 5,
"users": 15,
"dateC": "2024-01-07",
"comment": "Citation magnifique."
},
{
"id_comment": 80,
"quote": 4,
"users": 16,
"dateC": "2024-01-08",
"comment": "Citation magnifique."
},
{
"id_comment": 81,
"quote": 3,
"users": 17,
"dateC": "2024-01-09",
"comment": "Citation magnifique."
},
{
"id_comment": 82,
"quote": 2,
"users": 18,
"dateC": "2024-01-10",
"comment": "Citation magnifique."
},
{
"id_comment": 83,
"quote": 15,
"users": 33,
"dateC": "2024-06-24",
"comment": "Citation exceptionnelle."
},
{
"id_comment": 84,
"quote": 19,
"users": 15,
"dateC": "2024-03-11",
"comment": "Citation merveilleuse."
},
{
"id_comment": 85,
"quote": 4,
"users": 16,
"dateC": "2024-01-19",
"comment": "Citation merveilleuse."
},
{
"id_comment": 86,
"quote": 10,
"users": 20,
"dateC": "2024-01-15",
"comment": "Très émouvant."
},
{
"id_comment": 87,
"quote": 3,
"users": 33,
"dateC": "2024-12-17",
"comment": "Très touchant."
},
{
"id_comment": 88,
"quote": 5,
"users": 8,
"dateC": "2024-07-01",
"comment": "Citation exceptionnelle."
},
{
"id_comment": 89,
"quote": 13,
"users": 28,
"dateC": "2024-02-20",
"comment": "Citation merveilleuse."
},
{
"id_comment": 90,
"quote": 18,
"users": 24,
"dateC": "2024-09-16",
"comment": "Citation merveilleuse."
},
{
"id_comment": 91,
"quote": 17,
"users": 43,
"dateC": "2024-06-20",
"comment": "Très réfléchi."
},
{
"id_comment": 92,
"quote": 13,
"users": 36,
"dateC": "2024-11-08",
"comment": "Super citation !"
},
{
"id_comment": 93,
"quote": 19,
"users": 41,
"dateC": "2024-01-20",
"comment": "Super citation !"
},
{
"id_comment": 94,
"quote": 13,
"users": 10,
"dateC": "2024-05-03",
"comment": "Citation magnifique."
},
{
"id_comment": 95,
"quote": 4,
"users": 49,
"dateC": "2024-07-01",
"comment": "Citation profonde."
},
{
"id_comment": 96,
"quote": 16,
"users": 21,
"dateC": "2024-11-08",
"comment": "Citation merveilleuse."
},
{
"id_comment": 97,
"quote": 14,
"users": 27,
"dateC": "2024-11-20",
"comment": "Citation puissante."
},
{
"id_comment": 98,
"quote": 4,
"users": 39,
"dateC": "2024-12-11",
"comment": "Très motivant."
},
{
"id_comment": 99,
"quote": 9,
"users": 26,
"dateC": "2024-09-27",
"comment": "Paroles sages."
},
{
"id_comment": 100,
"quote": 3,
"users": 42,
"dateC": "2024-02-12",
"comment": "Citation merveilleuse."
}
]

@ -0,0 +1,14 @@
[
{
"Id": 11,
"Content": "Vous ne pouvez pas vivre sans causer de dommages \u00E0 quelqu\u0027un d\u0027autre.",
"Like": 110,
"Langue": "fr",
"Charac": "test",
"ImgPath": "http://thematrix.com",
"TitleSrc": "The Matrix",
"DateSrc": "2025-01-21T00:00:00",
"UserProposition": "user11",
"IsValid": false
}
]

@ -0,0 +1,82 @@
[
{
"id_img": 1,
"imgPath": "https://tse4.mm.bing.net/th/id/OIP.fc5TQflh0cbxB1GUeOdk6gHaK8?w=123&h=180&c=7&r=0&o=5&pid=1.7"
},
{
"id_img": 2,
"imgPath": "https://tse2.mm.bing.net/th/id/OIP.MMpXBB5RDRYQm05FJmevGAHaKl?w=137&h=195&c=7&r=0&o=5&pid=1.7"
},
{
"id_img": 3,
"imgPath": "https://tse1.mm.bing.net/th/id/OIP._uHLsNbgnf1m1vK3ZWE2UAHaEo?w=217&h=180&c=7&r=0&o=5&pid=1.7"
},
{
"id_img": 4,
"imgPath": "https://tse4.mm.bing.net/th/id/OIP.QzDh_d2T5aADiDJ7uMFU6gHaHa?w=157&h=180&c=7&r=0&o=5&pid=1.7"
},
{
"id_img": 5,
"imgPath": "https://tse2.mm.bing.net/th/id/OIP.CthWIxuLm0a8THOguTDB_AAAAA?w=157&h=207&c=7&r=0&o=5&pid=1.7"
},
{
"id_img": 6,
"imgPath": "https://tse4.mm.bing.net/th/id/OIP.XNQPKwc1OUfvnSO9MsxDYgHaE7?w=202&h=180&c=7&r=0&o=5&pid=1.7"
},
{
"id_img": 7,
"imgPath": "https://tse1.mm.bing.net/th/id/OIP.luN_zVQJt2Kyf7H_kSrPyQHaJD?w=115&h=180&c=7&r=0&o=5&pid=1.7"
},
{
"id_img": 8,
"imgPath": "https://tse1.mm.bing.net/th/id/OIP.GPIbva8dEP6Kllx-sj5ysAHaK-?w=115&h=180&c=7&r=0&o=5&pid=1.7"
},
{
"id_img": 9,
"imgPath": "https://tse4.mm.bing.net/th/id/OIP.loqNhw71Vk_C-TiyWQJoKAHaKK?w=95&h=180&c=7&r=0&o=5&pid=1.7"
},
{
"id_img": 10,
"imgPath": "https://tse2.mm.bing.net/th/id/OIP._OiJHgI7cal4cWNHcCE9zAHaM2?w=115&h=180&c=7&r=0&o=5&pid=1.7"
},
{
"id_img": 11,
"imgPath": "https://tse2.mm.bing.net/th/id/OIP.B9RbuWnpmV-7fI8v-H0G8gHaEK?w=290&h=180&c=7&r=0&o=5&pid=1.7"
},
{
"id_img": 12,
"imgPath": "https://tse2.mm.bing.net/th/id/OIP.RrJkua2jY_o24eUG7wmk8QHaE-?w=232&h=180&c=7&r=0&o=5&pid=1.7"
},
{
"id_img": 13,
"imgPath": "https://tse3.mm.bing.net/th/id/OIP.-1Ds-2D5GPiu9uejDdmgNgHaH3?w=124&h=180&c=7&r=0&o=5&pid=1.7"
},
{
"id_img": 14,
"imgPath": "https://tse3.mm.bing.net/th/id/OIP.BeQYJEP1pQKzHDLGhTLBtgHaFj?w=243&h=182&c=7&r=0&o=5&pid=1.7"
},
{
"id_img": 15,
"imgPath": "https://tse3.mm.bing.net/th/id/OIP.lDzxwo1weGaA-hRMfV6bYwHaGp?w=194&h=174&c=7&r=0&o=5&pid=1.7"
},
{
"id_img": 16,
"imgPath": "https://tse2.mm.bing.net/th/id/OIP.3vXkEUJ9J8s-GsnBC6I3KAHaF0?w=185&h=180&c=7&r=0&o=5&pid=1.7"
},
{
"id_img": 17,
"imgPath": "https://tse4.mm.bing.net/th/id/OIP.omU-pPTNgHJEiTKJUpB1MAHaIw?w=114&h=180&c=7&r=0&o=5&pid=1.7"
},
{
"id_img": 18,
"imgPath": "https://tse2.mm.bing.net/th/id/OIP.Qoh2doQIigxyiOBuhgRx9gHaM7?w=115&h=186&c=7&r=0&o=5&pid=1.7"
},
{
"id_img": 19,
"imgPath": "https://tse3.mm.bing.net/th/id/OIP.hyDe8SvEEvDhmKfsQBqWEwHaJ8?w=194&h=261&c=7&r=0&o=5&pid=1.7"
},
{
"id_img": 20,
"imgPath": "https://tse3.mm.bing.net/th/id/OIP.S4q6m2na1Rxkc7xZ1lcfKQHaJe?w=135&h=180&c=7&r=0&o=5&pid=1.7"
}
]

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

Loading…
Cancel
Save