🎨 Better and safer error handling, general overhaul

This commit is contained in:
Florian Sylvain
2021-10-31 15:26:04 +01:00
parent 76c6f9026c
commit b4b3132ae7
5 changed files with 100 additions and 39 deletions
+8 -2
View File
@@ -3,18 +3,24 @@
require_once("class/dump.php"); require_once("class/dump.php");
if (!isset($_GET['q']) || !isset($_GET['author'])) { 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(); exit();
} }
$author_name = $_GET['author']; $author_name = filter_var($_GET['author'], FILTER_SANITIZE_ADD_SLASHES);
$q = $_GET['q']; $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) { $json_object = match ($q) {
"theses" => dump::getTheseByAuthor($author_name), "theses" => dump::getTheseByAuthor($author_name),
"authors" => dump::getAuthorsByAuthors($author_name), "authors" => dump::getAuthorsByAuthors($author_name),
default => NULL, default => NULL,
}; };
// TODO : Rajouter la structure status message data
$json = json_encode($json_object); $json = json_encode($json_object);
print_r($json); print_r($json);
+37 -10
View File
@@ -3,15 +3,24 @@ let searchBar = document.querySelector('#searchbar')
let searchBarButton = document.querySelector('#search-button') let searchBarButton = document.querySelector('#search-button')
let suggestions = document.querySelector('#suggestions') let suggestions = document.querySelector('#suggestions')
let loader = document.querySelector('.loader') 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 authorName = "";
let lastRequest = null
function requestToApi(author) { function requestToApi(author) {
if (lastRequest === null || (new Date().getTime() - lastRequest) > 1000) {
lastRequest = new Date().getTime()
loader.style.display = "block" loader.style.display = "block"
authorName = author authorName = author
fetch(`api.php?q=theses&author=${author}`) fetch(`api.php?q=theses&author=${author}`)
.then(response => response.json()) .then(response => response.json())
.then(data => displayResults(data)) .then(data => displayResults(data))
} else {
alert('Veuillez attendre une seconde entre chaque recherche.')
}
} }
let elementsToFade = null 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.. // 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) { 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 let count = 0
results.forEach(elem => { results.forEach(elem => {
@@ -54,15 +74,15 @@ function displayResults(results) {
} }
let lastSearch = "" let lastSearch = ""
let last = new Date().getTime() let lastSuggestion = new Date().getTime()
let suggestionsDisplayed = false let suggestionsDisplayed = false
function realTimeDisplay() { function realTimeDisplay() {
let search = document.getElementsByName("author")[0].value 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() showSuggestions()
lastSearch = search lastSearch = search
last = new Date().getTime() lastSuggestion = new Date().getTime()
fetch(`api.php?q=authors&author=${search}`) fetch(`api.php?q=authors&author=${search}`)
.then(response => response.json()) .then(response => response.json())
.then(function(data) { .then(function(data) {
@@ -71,8 +91,6 @@ function realTimeDisplay() {
let name = document.createElement('p') let name = document.createElement('p')
name.innerHTML = elem name.innerHTML = elem
name.addEventListener('click', () => { name.addEventListener('click', () => {
document.querySelector('#results-count').innerHTML = ""
document.querySelector('#results').innerHTML = ""
searchBar.value = elem searchBar.value = elem
requestToApi(elem) requestToApi(elem)
}) })
@@ -87,20 +105,18 @@ function showSuggestions() {
navbarForm.style.borderRadius = '15px 15px 0 0' navbarForm.style.borderRadius = '15px 15px 0 0'
suggestions.style.display = 'block' suggestions.style.display = 'block'
searchBarButton.style.boxShadow = 'none' searchBarButton.style.boxShadow = 'none'
searchBarButton.classList.remove('animation-in') searchBarButton.classList.replace('animation-in', 'animation-out')
searchBarButton.classList.add('animation-out')
suggestionsDisplayed = true suggestionsDisplayed = true
} }
} }
document.addEventListener('click', function (e){ document.addEventListener('click', e => {
if (e.target.id !== 'suggestions' && e.target !== searchBar && e.target !== searchBarButton) { if (e.target.id !== 'suggestions' && e.target !== searchBar && e.target !== searchBarButton) {
if (suggestionsDisplayed) { if (suggestionsDisplayed) {
navbarForm.style.borderRadius = '15px' navbarForm.style.borderRadius = '15px'
suggestions.style.display = 'none' suggestions.style.display = 'none'
searchBarButton.style.boxShadow = 'rgba(0, 0, 0, 0.15) 4px 2px 5px' searchBarButton.style.boxShadow = 'rgba(0, 0, 0, 0.15) 4px 2px 5px'
searchBarButton.classList.remove('animation-out') searchBarButton.classList.replace('animation-out', 'animation-in')
searchBarButton.classList.add('animation-in')
suggestionsDisplayed = false suggestionsDisplayed = false
} }
@@ -116,5 +132,16 @@ document.addEventListener('click', function (e){
cross.classList.remove('spin-fade') 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'))
})
+8 -13
View File
@@ -6,7 +6,7 @@
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge"> <meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="stylesheet" href="stylesheet.css"> <link rel="stylesheet" href="stylesheet.css">
<title>Document</title> <title>Theses FR</title>
</head> </head>
<body> <body>
<?php <?php
@@ -32,19 +32,14 @@
<div id="results-count"></div> <div id="results-count"></div>
<div id="results"></div> <div id="results"></div>
<script src="app.js"></script> <div id="error">
<div id="error-message"></div>
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" id="error-button">
<path d="M23.954 21.03l-9.184-9.095 9.092-9.174-2.832-2.807-9.09 9.179-9.176-9.088-2.81 2.81 9.186 9.105-9.095 9.184 2.81 2.81 9.112-9.192 9.18 9.1z"/>
</svg>
</div>
<?php <script src="app.js"></script>
if (isset($_GET['author'])) {
if (strlen($_GET['author']) < 3) {
echo "<p class='error'>Veuillez entrer 3 caractères minimum.</p>";
} else {
echo "<script>requestToApi('" . filter_var($_GET['author'], FILTER_SANITIZE_ADD_SLASHES) . "')</script>";
}
} else {
echo "<script>document.getElementsByClassName('loader')[0].style.display = \"none\"</script>";
}
?>
</body> </body>
</html> </html>
+3 -3
View File
@@ -9,10 +9,10 @@
</svg> </svg>
<div class="research-section"> <div class="research-section">
<form action="index.php" method="GET" class="navbar-form"> <form class="navbar-form">
<input type="text" name="author" placeholder="nom auteur" onkeyup="realTimeDisplay()" id="searchbar"> <input type="text" name="author" placeholder="nom auteur" onkeyup="realTimeDisplay()" id="searchbar">
<button> <button id="form-button">
<img src="assets/search.svg" alt="search" id="search-button"> <img src="assets/search.svg" alt="search" id="search-button" class="animation-in">
</button> </button>
</form> </form>
<div id="suggestions"></div> <div id="suggestions"></div>
+39 -6
View File
@@ -2,6 +2,7 @@
* { * {
box-sizing: border-box; box-sizing: border-box;
font-family: sans-serif;
} }
body { body {
@@ -23,7 +24,6 @@ body {
height: 75px; height: 75px;
padding: 10px; padding: 10px;
width: 100%; width: 100%;
font-family: sans-serif;
} }
.research-section { .research-section {
@@ -139,7 +139,6 @@ body {
} }
#results { #results {
font-family: sans-serif;
margin: 10px; margin: 10px;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
@@ -147,7 +146,6 @@ body {
} }
#results-count { #results-count {
font-family: sans-serif;
opacity: 50%; opacity: 50%;
margin: 0 15px 0 15px; margin: 0 15px 0 15px;
} }
@@ -168,14 +166,49 @@ body {
transform: translateX(0px); transform: translateX(0px);
animation-fill-mode: forwards; animation-fill-mode: forwards;
} }
.fade-out {
animation: fade-out 250ms linear;
transition: 250ms;
transform: translateX(0px);
animation-fill-mode: forwards;
}
@keyframes fade-in { @keyframes fade-in {
from { opacity: 0 } from { opacity: 0 }
to { opacity: 100% } to { opacity: 100% }
} }
@keyframes fade-out {
from { opacity: 100% }
to { opacity: 0 }
}
/*TODO : Faire une belle erreur*/ #error {
.error { opacity: 0;
color: red; 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 { .loader {