From b4b3132ae70ed68fb55e5f37833df49241a1a2ab Mon Sep 17 00:00:00 2001 From: Florian Sylvain Date: Sun, 31 Oct 2021 15:26:04 +0100 Subject: [PATCH] =?UTF-8?q?=F0=9F=8E=A8=20Better=20and=20safer=20error=20h?= =?UTF-8?q?andling,=20general=20overhaul?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ProjetProgWeb/api.php | 10 +++++-- ProjetProgWeb/app.js | 57 ++++++++++++++++++++++++++---------- ProjetProgWeb/index.php | 21 +++++-------- ProjetProgWeb/navbar.php | 6 ++-- ProjetProgWeb/stylesheet.css | 45 ++++++++++++++++++++++++---- 5 files changed, 100 insertions(+), 39 deletions(-) diff --git a/ProjetProgWeb/api.php b/ProjetProgWeb/api.php index f7e3885..8bfb4ab 100644 --- a/ProjetProgWeb/api.php +++ b/ProjetProgWeb/api.php @@ -3,18 +3,24 @@ require_once("class/dump.php"); if (!isset($_GET['q']) || !isset($_GET['author'])) { - print_r(json_encode(array("status" => 400, "message" => "Missing query type or attributs."))); + print_r(json_encode(array("status" => 400, "message" => "Missing query type or attributes."))); exit(); } -$author_name = $_GET['author']; +$author_name = filter_var($_GET['author'], FILTER_SANITIZE_ADD_SLASHES); $q = $_GET['q']; +if (strlen($author_name) < 3) { + print_r(json_encode(array("status" => 400, "message" => "Le nom de l'auteur doit comporter un minimum de 3 caractères."))); + exit(); +} + $json_object = match ($q) { "theses" => dump::getTheseByAuthor($author_name), "authors" => dump::getAuthorsByAuthors($author_name), default => NULL, }; +// TODO : Rajouter la structure status message data $json = json_encode($json_object); print_r($json); diff --git a/ProjetProgWeb/app.js b/ProjetProgWeb/app.js index 9a9a5d1..3e6484e 100644 --- a/ProjetProgWeb/app.js +++ b/ProjetProgWeb/app.js @@ -3,15 +3,24 @@ let searchBar = document.querySelector('#searchbar') let searchBarButton = document.querySelector('#search-button') let suggestions = document.querySelector('#suggestions') let loader = document.querySelector('.loader') +let error = document.querySelector("#error") +let errorMessage = document.querySelector("#error-message") +let errorButton = document.querySelector("#error-button") let authorName = ""; +let lastRequest = null function requestToApi(author) { - loader.style.display = "block" - authorName = author - fetch(`api.php?q=theses&author=${author}`) - .then(response => response.json()) - .then(data => displayResults(data)) + if (lastRequest === null || (new Date().getTime() - lastRequest) > 1000) { + lastRequest = new Date().getTime() + loader.style.display = "block" + authorName = author + fetch(`api.php?q=theses&author=${author}`) + .then(response => response.json()) + .then(data => displayResults(data)) + } else { + alert('Veuillez attendre une seconde entre chaque recherche.') + } } let elementsToFade = null @@ -26,6 +35,17 @@ function fadeIn() { // TODO : Faire un système de page plutôt que de charger 10000 résultats en une fois s'il y en a 10000.. function displayResults(results) { + + if (results.status === 400) { + loader.style.display = "none" + error.classList.add("fade-in"); + errorMessage.innerHTML = results.message + return; + } + + document.querySelector('#results-count').innerHTML = "" + document.querySelector('#results').innerHTML = "" + let count = 0 results.forEach(elem => { @@ -54,15 +74,15 @@ function displayResults(results) { } let lastSearch = "" -let last = new Date().getTime() +let lastSuggestion = new Date().getTime() let suggestionsDisplayed = false function realTimeDisplay() { let search = document.getElementsByName("author")[0].value - if (search.length > 3 && (search !== lastSearch || (new Date().getTime() - last) > 500)) { + if (search.length > 3 && (search !== lastSearch || (new Date().getTime() - lastSuggestion) > 500)) { showSuggestions() lastSearch = search - last = new Date().getTime() + lastSuggestion = new Date().getTime() fetch(`api.php?q=authors&author=${search}`) .then(response => response.json()) .then(function(data) { @@ -71,8 +91,6 @@ function realTimeDisplay() { let name = document.createElement('p') name.innerHTML = elem name.addEventListener('click', () => { - document.querySelector('#results-count').innerHTML = "" - document.querySelector('#results').innerHTML = "" searchBar.value = elem requestToApi(elem) }) @@ -87,20 +105,18 @@ function showSuggestions() { navbarForm.style.borderRadius = '15px 15px 0 0' suggestions.style.display = 'block' searchBarButton.style.boxShadow = 'none' - searchBarButton.classList.remove('animation-in') - searchBarButton.classList.add('animation-out') + searchBarButton.classList.replace('animation-in', 'animation-out') suggestionsDisplayed = true } } -document.addEventListener('click', function (e){ +document.addEventListener('click', e => { if (e.target.id !== 'suggestions' && e.target !== searchBar && e.target !== searchBarButton) { if (suggestionsDisplayed) { navbarForm.style.borderRadius = '15px' suggestions.style.display = 'none' searchBarButton.style.boxShadow = 'rgba(0, 0, 0, 0.15) 4px 2px 5px' - searchBarButton.classList.remove('animation-out') - searchBarButton.classList.add('animation-in') + searchBarButton.classList.replace('animation-out', 'animation-in') suggestionsDisplayed = false } @@ -116,5 +132,16 @@ document.addEventListener('click', function (e){ cross.classList.remove('spin-fade') } } + + if (e.target === errorButton) { + error.classList.replace('fade-in', 'fade-out') + } } }) + +navbarForm.addEventListener('submit', e => { + e.preventDefault() + let data = new FormData(navbarForm) + searchBar.blur() + requestToApi(data.get('author')) +}) diff --git a/ProjetProgWeb/index.php b/ProjetProgWeb/index.php index ee46469..3827ab2 100644 --- a/ProjetProgWeb/index.php +++ b/ProjetProgWeb/index.php @@ -6,7 +6,7 @@ content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> - Document + Theses FR
- +
+
+ + + +
- Veuillez entrer 3 caractères minimum.

"; - } else { - echo ""; - } - } else { - echo ""; - } - ?> + diff --git a/ProjetProgWeb/navbar.php b/ProjetProgWeb/navbar.php index fa07a2f..b3d6de7 100644 --- a/ProjetProgWeb/navbar.php +++ b/ProjetProgWeb/navbar.php @@ -9,10 +9,10 @@
-
diff --git a/ProjetProgWeb/stylesheet.css b/ProjetProgWeb/stylesheet.css index a3619ce..55c7be2 100644 --- a/ProjetProgWeb/stylesheet.css +++ b/ProjetProgWeb/stylesheet.css @@ -2,6 +2,7 @@ * { box-sizing: border-box; + font-family: sans-serif; } body { @@ -23,7 +24,6 @@ body { height: 75px; padding: 10px; width: 100%; - font-family: sans-serif; } .research-section { @@ -139,7 +139,6 @@ body { } #results { - font-family: sans-serif; margin: 10px; display: flex; flex-direction: column; @@ -147,7 +146,6 @@ body { } #results-count { - font-family: sans-serif; opacity: 50%; margin: 0 15px 0 15px; } @@ -168,14 +166,49 @@ body { transform: translateX(0px); animation-fill-mode: forwards; } +.fade-out { + animation: fade-out 250ms linear; + transition: 250ms; + transform: translateX(0px); + animation-fill-mode: forwards; +} @keyframes fade-in { from { opacity: 0 } to { opacity: 100% } } +@keyframes fade-out { + from { opacity: 100% } + to { opacity: 0 } +} -/*TODO : Faire une belle erreur*/ -.error { - color: red; +#error { + opacity: 0; + display: flex; + align-items: center; + background-color: #FF6F6F; + border: solid 3px #DE6161; + border-radius: 5px; + color: #302B2B; + width: 90%; + padding: 10px; + position: fixed; + bottom: 10px; + align-self: center; +} + +#error-button { + fill: #302B2B; + width: 20px; + height: 20px; + background: #DE6161; + border-radius: 1px; + padding: 2px; + margin-left: auto; + border: 1px solid #824D4D; +} + +#error-button:hover { + background: #CA5D5D; } .loader {