diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..d48c759d6c990444f193c0043ec9b316029d31bc --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.idea +.vscode \ No newline at end of file diff --git a/assets/css/create.css b/assets/css/create.css new file mode 100644 index 0000000000000000000000000000000000000000..d39ec0c61d042a4748ebcb93116cbf1586cd832d --- /dev/null +++ b/assets/css/create.css @@ -0,0 +1,31 @@ +form { + display: flex; + flex-direction: column; + align-items: stretch; + + padding: 1rem; + + input, textarea { + &.error { + border-color: red; + background-color: rgba(255, 0, 0, 0.1); + } + } + + p { + margin-top: 0; + } + + button { + align-self: flex-end; + padding: 1rem; + background-color: var(--primary-light); + border-radius: 1rem; + border: none; + cursor: pointer; + + &:hover { + box-shadow: 3px 3px 10px var(--text-action); + } + } +} \ No newline at end of file diff --git a/assets/css/style.css b/assets/css/style.css index 643890e17345c24ae4552d09d507aa0a9039e59a..c3ba58597bcc075badc2f03060111d0a7af6929c 100644 --- a/assets/css/style.css +++ b/assets/css/style.css @@ -8,6 +8,19 @@ body { margin: 0; } +.sr-only { + border: 0 !important; + clip: rect(1px, 1px, 1px, 1px) !important; + -webkit-clip-path: inset(50%) !important; + clip-path: inset(50%) !important; + height: 1px !important; + overflow: hidden !important; + padding: 0 !important; + position: absolute !important; + width: 1px !important; + white-space: nowrap !important; +} + .main_navbar { display: flex; justify-content: space-between; @@ -21,7 +34,7 @@ body { list-style: none; gap: 1rem; margin: 0; - padding: 0 ; + padding: 0; li { a { diff --git a/assets/img/save/1741938939.png b/assets/img/save/1741938939.png new file mode 100644 index 0000000000000000000000000000000000000000..570fddd340f82a5b54b5cb44a47fb718cf9ea91d Binary files /dev/null and b/assets/img/save/1741938939.png differ diff --git a/assets/img/save/1741939118.png b/assets/img/save/1741939118.png new file mode 100644 index 0000000000000000000000000000000000000000..570fddd340f82a5b54b5cb44a47fb718cf9ea91d Binary files /dev/null and b/assets/img/save/1741939118.png differ diff --git a/assets/img/save/1741942598.png b/assets/img/save/1741942598.png new file mode 100644 index 0000000000000000000000000000000000000000..570fddd340f82a5b54b5cb44a47fb718cf9ea91d Binary files /dev/null and b/assets/img/save/1741942598.png differ diff --git a/assets/js/form.js b/assets/js/form.js new file mode 100644 index 0000000000000000000000000000000000000000..f364c1a04cb7d7868c8d0b3e103c103b9012af8d --- /dev/null +++ b/assets/js/form.js @@ -0,0 +1,66 @@ +document.querySelector('form') + ?.addEventListener('submit', function (e) { + console.log(e); + e.preventDefault(); + + let hasError = false; + + const title = document.getElementById('title'); + if (title.value === '' || title.value.length > 100) { + hasError = true; + title.classList.add('error'); + + title.nextElementSibling.innerText = 'Le titre doit avoir entre 0 et 100 caractères'; + + title.addEventListener('input', () => { + if (title.value !== '' && title.value.length <= 100) { + if (title.classList.contains('error')) { + title.classList.remove('error'); + title.nextElementSibling.innerText = ''; + } + } else { + title.classList.add('error'); + title.nextElementSibling.innerText = 'Le titre doit avoir entre 0 et 100 caractères'; + } + }); + } + + const description = document.getElementById('description'); + if (description.value === '') { + hasError = true; + description.classList.add('error'); + + description.nextElementSibling.innerText = 'La description est obligatoire'; + + description.addEventListener('input', () => { + if (description.value !== '') { + if (description.classList.contains('error')) { + description.classList.remove('error'); + description.nextElementSibling.innerText = ''; + } + } else { + description.classList.add('error'); + description.nextElementSibling.innerText = 'La description est obligatoire'; + } + }); + } + + if (!hasError) { + this.submit(); + } + }); + +/*// Validation d'un champ avec format spécifique, exemple: email +const title = document.getElementById('title'); +title.addEventListener('input', () => { + // 1ère méthode + /^[a-zA-Z0-9.-_]+@[a-zA-Z0-9.-_]+\.[a-z]{2,}$/.test(title.value); + + // 2ème méthode + const reg = new RegExp(/^[a-zA-Z0-9.-_]+@[a-zA-Z0-9.-_]+\.[a-z]{2,}$/); + reg.test(title.value); + + // 3ème méthode + title.value.match(/^[a-zA-Z0-9.-_]+@[a-zA-Z0-9.-_]+\.[a-z]{2,}$/); +});*/ + diff --git a/assets/locales/en.php b/assets/locales/en.php new file mode 100644 index 0000000000000000000000000000000000000000..cafeda577c6b4be5b7bdc7ce327ebe2451c9ef61 --- /dev/null +++ b/assets/locales/en.php @@ -0,0 +1,10 @@ +<?php + +$t = [ + 'nav' => [ + 'home' => 'Home', + 'create' => 'Create a recipe', + 'login' => 'Login', + 'about' => 'About' + ] +]; diff --git a/assets/locales/fr.php b/assets/locales/fr.php new file mode 100644 index 0000000000000000000000000000000000000000..db7c5ba3f7e623ea482c3262bfcf9b752b02cd27 --- /dev/null +++ b/assets/locales/fr.php @@ -0,0 +1,20 @@ +<?php + +$t = [ + 'create' => [ + 'form' => [ + 'thumbnail' => 'Image de couverture', + 'title' => 'Titre', + 'description' => 'Description', + ], + ], + 'core' => [ + 'save' => 'Enregistrer', + ], + 'nav' => [ + 'home' => 'Accueil', + 'create' => 'Créer sa recette', + 'login' => 'Se connecter', + 'about' => 'À propos' + ], +]; diff --git a/assets/locales/trad.php b/assets/locales/trad.php new file mode 100644 index 0000000000000000000000000000000000000000..efe7a0466591cb3e80cb75b180401078912a98d3 --- /dev/null +++ b/assets/locales/trad.php @@ -0,0 +1,3 @@ +<?php + +require_once 'assets/locales/fr.php'; \ No newline at end of file diff --git a/assets/php/Recipe.php b/assets/php/Recipe.php index 0670e2df13587d2e4895f745945980cbf5c124f6..9963a38386494ce6edaa3611802c76a76dbfeb2b 100644 --- a/assets/php/Recipe.php +++ b/assets/php/Recipe.php @@ -4,10 +4,14 @@ require_once 'Database.php'; class Recipe extends Database { + private string $path; + public function __construct() { parent::__construct(); + $this->path = "{$_SERVER['DOCUMENT_ROOT']}/assets/img/save"; + $this->db->exec('CREATE TABLE IF NOT EXISTS recipe ( id INTEGER PRIMARY KEY AUTOINCREMENT, title VARCHAR(100) NOT NULL, @@ -17,12 +21,29 @@ class Recipe extends Database )'); } - public function save(string $title, string $description): void + public function getPath(): string + { + return $this->path; + } + + public function saveImg(): string + { + $time = time(); + $type = pathinfo($_FILES['thumbnail']['name'], PATHINFO_EXTENSION); + $name = "{$time}.{$type}"; + + move_uploaded_file($_FILES['thumbnail']['tmp_name'], "{$this->path}/{$name}"); + + return $name; + } + + public function save(string $title, string $description, string $name): void { - $statement = $this->db->prepare("INSERT INTO recipe ('title', 'description', 'thumbnail') VALUES (:title, :description, 'photo.jpg')"); + $statement = $this->db->prepare("INSERT INTO recipe ('title', 'description', 'thumbnail') VALUES (:title, :description, :thumbnail)"); $statement->bindValue(':title', $title); $statement->bindValue(':description', $description); + $statement->bindValue(':thumbnail', $name); $statement->execute(); } diff --git a/assets/php/db.sqlite b/assets/php/db.sqlite index 4587f5da33b47183c1566a3c16317baa079d1952..b75635b4ea953daaf6ec0d3e1ce5e5396923694e 100644 Binary files a/assets/php/db.sqlite and b/assets/php/db.sqlite differ diff --git a/assets/php/navbar.php b/assets/php/navbar.php index d39529b0b6417554a4f94a695b2ab4131a73c62f..bbbf57187447b25c769624b6ff9d444ed1ef2b4d 100644 --- a/assets/php/navbar.php +++ b/assets/php/navbar.php @@ -5,16 +5,24 @@ <menu> <li> - <a href="/">Accueil</a> + <a href="/"> + <?= $t['nav']['home'] ?> + </a> </li> <li> - <a href="/create.php">Créer sa recette</a> + <a href="/create.php"> + <?= $t['nav']['create'] ?> + </a> </li> <li> - <a href="#">Se connecter</a> + <a href="#"> + <?= $t['nav']['login'] ?> + </a> </li> <li> - <a href="#">À propos</a> + <a href="#"> + <?= $t['nav']['about'] ?> + </a> </li> </menu> </nav> \ No newline at end of file diff --git a/assets/php/saveRecipe.php b/assets/php/saveRecipe.php index 6107dc1b8d3cefd855de7215d2ab6787d856b333..a1da71d8dcdae34cd2912e590e6d18f421b5aaab 100644 --- a/assets/php/saveRecipe.php +++ b/assets/php/saveRecipe.php @@ -1,7 +1,10 @@ <?php - require_once 'Recipe.php'; +$recipe = new Recipe(); + +$name = $recipe->saveImg(); + $title = htmlspecialchars($_POST['title']); $description = htmlspecialchars($_POST['description']); @@ -10,7 +13,6 @@ if (strlen($title) > 100 || $title === '' || $description == '') { exit(); } -$recipe = new Recipe(); -$recipe->save($title, $description); +$recipe->save($title, $description, $name); header('Location: /create.php'); \ No newline at end of file diff --git a/create-old.php b/create-old.php new file mode 100644 index 0000000000000000000000000000000000000000..779f9738b6a8f06e584c0f97d0b9fbdd74c78d18 --- /dev/null +++ b/create-old.php @@ -0,0 +1,51 @@ +<?php +require_once 'assets/php/Recipe.php'; +$recipeObject = new Recipe(); +$recipes = $recipeObject->getAll(); +?> + +<!doctype html> +<html lang="fr"> +<head> + <meta charset="UTF-8"> + <meta name="viewport" content="width=device-width, initial-scale=1"> + <title>Créer une recette</title> + <style> + .sr-only { + border: 0 !important; + clip: rect(1px, 1px, 1px, 1px) !important; + -webkit-clip-path: inset(50%) !important; + clip-path: inset(50%) !important; + height: 1px !important; + overflow: hidden !important; + padding: 0 !important; + position: absolute !important; + width: 1px !important; + white-space: nowrap !important; + } + </style> +</head> +<body> +<form action="assets/php/saveRecipe.php" method="post"> + <label for="title">Titre</label> + <input name="title" type="text" placeholder="Titre" id="title"/> + + <label for="description">Description</label> + <textarea name="description" id="description" cols="30" rows="10"></textarea> + + <button type="submit">Enregistrer</button> +</form> + +<ul> + <?php foreach ($recipes as $recipe) : ?> + <li> + <article> + <h2><?= $recipe['title'] ?></h2> + <p><?php echo $recipe['description'] ?></p> + <p><a href="/recipe.php?id=<?= $recipe['id'] ?>">Voir plus</a></p> + </article> + </li> + <?php endforeach; ?> +</ul> +</body> +</html> \ No newline at end of file diff --git a/create.php b/create.php index 779f9738b6a8f06e584c0f97d0b9fbdd74c78d18..aa230e9e20d982c1ffc9bfd72d35d55c850c4fe2 100644 --- a/create.php +++ b/create.php @@ -1,7 +1,5 @@ <?php -require_once 'assets/php/Recipe.php'; -$recipeObject = new Recipe(); -$recipes = $recipeObject->getAll(); +require_once 'assets/locales/trad.php'; ?> <!doctype html> @@ -10,42 +8,40 @@ $recipes = $recipeObject->getAll(); <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Créer une recette</title> - <style> - .sr-only { - border: 0 !important; - clip: rect(1px, 1px, 1px, 1px) !important; - -webkit-clip-path: inset(50%) !important; - clip-path: inset(50%) !important; - height: 1px !important; - overflow: hidden !important; - padding: 0 !important; - position: absolute !important; - width: 1px !important; - white-space: nowrap !important; - } - </style> + + <link rel="stylesheet" href="assets/css/style.css"> + <link rel="stylesheet" href="assets/css/create.css"> + + <script type="module" src="assets/js/form.js"></script> </head> <body> -<form action="assets/php/saveRecipe.php" method="post"> - <label for="title">Titre</label> +<?php +include_once 'assets/php/navbar.php'; +?> + +<form action="assets/php/saveRecipe.php" method="post" enctype="multipart/form-data"> + <label for="thumbnail"> + <?= $t['create']['form']['thumbnail'] ?> + </label> + <input type="file" name="thumbnail" id="thumbnail" accept="image/*"/> + <p></p> + + <label for="title"> + <?= $t['create']['form']['title'] ?> + </label> <input name="title" type="text" placeholder="Titre" id="title"/> + <p></p> - <label for="description">Description</label> + <label for="description"> + <?= $t['create']['form']['description'] ?> + </label> <textarea name="description" id="description" cols="30" rows="10"></textarea> + <p></p> - <button type="submit">Enregistrer</button> + <button type="submit"> + <?= $t['core']['save'] ?> + </button> </form> -<ul> - <?php foreach ($recipes as $recipe) : ?> - <li> - <article> - <h2><?= $recipe['title'] ?></h2> - <p><?php echo $recipe['description'] ?></p> - <p><a href="/recipe.php?id=<?= $recipe['id'] ?>">Voir plus</a></p> - </article> - </li> - <?php endforeach; ?> -</ul> </body> </html> \ No newline at end of file diff --git a/index.php b/index.php index aa6171ae4da02b2211d4838177fbed9e3276684a..fcce97051b0cf4620fdfcc0054f7cf43ec166759 100644 --- a/index.php +++ b/index.php @@ -1,14 +1,18 @@ +<?php +require_once 'assets/locales/trad.php'; +?> + <!DOCTYPE html> <html lang="en"> <head> - <meta charset="UTF-8"/> - <meta name="viewport" content="width=device-width, initial-scale=1.0"/> - <title>Document</title> + <meta charset="UTF-8"/> + <meta name="viewport" content="width=device-width, initial-scale=1.0"/> + <title>Document</title> - <link rel="stylesheet" href="assets/css/style.css"> - <link rel="stylesheet" href="assets/css/index.css"> + <link rel="stylesheet" href="assets/css/style.css"> + <link rel="stylesheet" href="assets/css/index.css"> - <script src="assets/js/base.js" type="module"></script> + <script src="assets/js/base.js" type="module"></script> </head> <body> <?php