From 9f054145086908eddffbc515c55431aaa0989fa6 Mon Sep 17 00:00:00 2001 From: Kelly Dobbs Date: Mon, 7 Dec 2020 21:21:01 -0600 Subject: [PATCH 01/39] updated password --- src/main/resources/application.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 1529f2a..1a8f7b7 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1,7 +1,7 @@ # Datasource MySql spring.datasource.url=jdbc:mysql://localhost:3306/recipes spring.datasource.username=recipe-app -spring.datasource.password=1password +spring.datasource.password=1Password spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver # Specify the DBMS spring.jpa.database = MYSQL From a5246b38989fad8f93a6cf2a98e5594e90798a0c Mon Sep 17 00:00:00 2001 From: Oksana999 Date: Thu, 3 Dec 2020 15:22:46 -0600 Subject: [PATCH 02/39] Improved display of recipe creation form --- src/main/resources/static/css/style.css | 31 ++++-- .../resources/templates/recipes/create.html | 94 ++++++++----------- 2 files changed, 65 insertions(+), 60 deletions(-) diff --git a/src/main/resources/static/css/style.css b/src/main/resources/static/css/style.css index af3b406..f78095b 100644 --- a/src/main/resources/static/css/style.css +++ b/src/main/resources/static/css/style.css @@ -53,12 +53,6 @@ section { display: flex; justify-content: end; } -/*.carousel-control-prev-icon {*/ -/* background-image: url("photo/Left.png");*/ -/*}*/ -/*.carousel-control-next-icon {*/ -/* background-image: url("photo/Right.png");*/ -/*}*/ .carousel-item { width: 80%; @@ -67,3 +61,28 @@ section { width: 30%; } +label { + display: inline-block; + width: 200px; + margin: 5px; + text-align: left; + font-size: 25px; + color: #4d3b0b; + font-weight: bold; +} +input[type=text], input[type=password], select { + display: inline-block; + justify-content: center; + width: 442px; + height: 45px; +} +button { + padding: 5px; + margin: 10px; +} +h1 { + font-weight: bold; + color: #4d3b0b; + font-style: italic; + margin-left: 100px; +} diff --git a/src/main/resources/templates/recipes/create.html b/src/main/resources/templates/recipes/create.html index 535bbab..6f47a4d 100644 --- a/src/main/resources/templates/recipes/create.html +++ b/src/main/resources/templates/recipes/create.html @@ -6,68 +6,54 @@ -
- -

Recipe:

- -
- -
- - -
-
-
- - -
-
-
- - -
-
- -
- -
-
+
+
+ +
+
+
+
+ + - - -
-
- - -
- -
+
+
+
+ +
+
+
+
+ + +
+ + + +
- +// From 9765b73af92cc4f6b2e013374e744475574c4e4e Mon Sep 17 00:00:00 2001 From: Oksana999 Date: Sat, 5 Dec 2020 13:31:43 -0600 Subject: [PATCH 04/39] Add edit and delete features --- .../controllers/RecipeController.java | 60 +++++++++++++++++++ .../resources/templates/recipes/create.html | 33 ++++++---- .../resources/templates/recipes/edit.html | 47 +++++++++++++++ .../resources/templates/recipes/index.html | 11 +++- 4 files changed, 137 insertions(+), 14 deletions(-) diff --git a/src/main/java/org/launchcode/recipeapp/controllers/RecipeController.java b/src/main/java/org/launchcode/recipeapp/controllers/RecipeController.java index d087f3b..d934255 100644 --- a/src/main/java/org/launchcode/recipeapp/controllers/RecipeController.java +++ b/src/main/java/org/launchcode/recipeapp/controllers/RecipeController.java @@ -10,6 +10,7 @@ import org.springframework.validation.Errors; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.ModelAttribute; +import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; @@ -87,4 +88,63 @@ public String displayRecipe(@RequestParam Integer recipeId, Model model) { return "recipes/display"; } + @GetMapping("edit/{recipeId}") + public String displayEditForm(Model model, @PathVariable int recipeId) { + + Category[] categories = Category.values(); + Tag[] tags = Tag.values(); + Optional recipeOpt = recipeRepository.findById(recipeId); + if (recipeOpt.isPresent()) { + Recipe recipe = recipeOpt.get(); + model.addAttribute("recipe", recipe); + model.addAttribute("title", "Edit recipe " + recipe.getName()); + model.addAttribute("recipeId", recipe.getId()); + } else { + model.addAttribute("recipe", new Recipe()); + } + model.addAttribute("categories", categories); + model.addAttribute("tags", tags); + + return "recipes/edit"; + + } + + @PostMapping("edit") + public String processEditForm(Integer recipeId, @ModelAttribute @Valid Recipe newRecipe, + Errors errors, Model model, RedirectAttributes redirectAttrs) { + if (errors.hasErrors()) { + model.addAttribute("title", "Edit Recipe"); + return "recipes/edit"; + } + Optional recipeOpt = recipeRepository.findById(recipeId); + if (recipeOpt.isPresent()) { + Recipe recipe = recipeOpt.get(); + recipe.setCategory(newRecipe.getCategory()); + recipe.setDirections(newRecipe.getDirections()); + recipe.setImg(newRecipe.getImg()); + recipe.setIngredients(newRecipe.getIngredients()); + recipe.setName(newRecipe.getName()); + recipe.setTag(newRecipe.getTag()); + + + Recipe savedRecipe = recipeRepository.save(recipe); + Iterable recipes = recipeRepository.findAll(); + + redirectAttrs.addAttribute("recipes", recipes); + + } + return "redirect:"; + + } + + @RequestMapping("/delete/{recipeId}") + public String handleDeleteUser(@PathVariable Integer recipeId) { + Optional recipeOpt = recipeRepository.findById(recipeId); + if (recipeOpt.isPresent()) { + recipeRepository.deleteById(recipeId); + } + + return "redirect:/recipes"; + } + } diff --git a/src/main/resources/templates/recipes/create.html b/src/main/resources/templates/recipes/create.html index ef28e84..1ff6ca9 100644 --- a/src/main/resources/templates/recipes/create.html +++ b/src/main/resources/templates/recipes/create.html @@ -7,57 +7,64 @@
+



+

Create Recipe

-
+

-
-
+


-
-
+

+ + + +
-
-
+
-
-
+

-
-
+
- + + +
-// diff --git a/src/main/resources/templates/recipes/edit.html b/src/main/resources/templates/recipes/edit.html index 5b14525..5c7be1b 100644 --- a/src/main/resources/templates/recipes/edit.html +++ b/src/main/resources/templates/recipes/edit.html @@ -2,8 +2,55 @@ + Title + +
+



+ +
+

Edit Recipe

+
+
+ +
+

+
+ +
+

+
+ + +

+
+ + +

+
+ +
+

+
+ + +
+ + + + +
+
+
+ +
+ diff --git a/src/main/resources/templates/recipes/index.html b/src/main/resources/templates/recipes/index.html index 95a4189..7f5c65a 100644 --- a/src/main/resources/templates/recipes/index.html +++ b/src/main/resources/templates/recipes/index.html @@ -3,7 +3,7 @@ -
+

Recipes:

@@ -15,6 +15,14 @@

Recipes:

+ + Edit + + + + + Delete + @@ -22,3 +30,4 @@

Recipes:

+ From 9d4a4c9054282053bbfcbf32d4bfbbf7fe415938 Mon Sep 17 00:00:00 2001 From: Oksana999 Date: Mon, 7 Dec 2020 13:48:26 -0600 Subject: [PATCH 05/39] Add edit and delete features --- .../org/launchcode/recipeapp/controllers/RecipeController.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/org/launchcode/recipeapp/controllers/RecipeController.java b/src/main/java/org/launchcode/recipeapp/controllers/RecipeController.java index d934255..3dd569a 100644 --- a/src/main/java/org/launchcode/recipeapp/controllers/RecipeController.java +++ b/src/main/java/org/launchcode/recipeapp/controllers/RecipeController.java @@ -148,3 +148,4 @@ public String handleDeleteUser(@PathVariable Integer recipeId) { } } + From be1491a7502a1207460900a116767b52796b807c Mon Sep 17 00:00:00 2001 From: Oksana999 Date: Mon, 7 Dec 2020 13:51:20 -0600 Subject: [PATCH 06/39] Commented out css --- src/main/resources/static/css/carusel.css | 188 +++++++++++----------- src/main/resources/static/css/rating.css | 92 +++++------ src/main/resources/static/css/style.css | 166 +++++++++---------- 3 files changed, 223 insertions(+), 223 deletions(-) diff --git a/src/main/resources/static/css/carusel.css b/src/main/resources/static/css/carusel.css index 692fb42..f4d5112 100644 --- a/src/main/resources/static/css/carusel.css +++ b/src/main/resources/static/css/carusel.css @@ -1,108 +1,108 @@ -* {box-sizing:border-box} +/** {box-sizing:border-box}*/ -/* Контейнер слайд-шоу */ -.slideshow-container { - max-width: 800px; - position: relative; - margin: auto; -} - -/* Скрыть изображения по умолчанию */ -/*.mySlides {*/ -/* display: none;*/ +/*!* Контейнер слайд-шоу *!*/ +/*.slideshow-container {*/ +/* max-width: 800px;*/ +/* position: relative;*/ +/* margin: auto;*/ /*}*/ -/* Вперед иназад кнопки */ -.prev, .next { - cursor: pointer; - position: absolute; - top: 50%; - width: auto; - margin-top: -22px; - padding: 16px; - color: white; - font-weight: bold; - font-size: 18px; - transition: 0.6s ease; - border-radius: 0 3px 3px 0; - user-select: contain; -} +/*!* Скрыть изображения по умолчанию *!*/ +/*!*.mySlides {*!*/ +/*!* display: none;*!*/ +/*!*}*!*/ -/* Положение "next кнопки" справа */ -.next { - right: 0; - border-radius: 3px 0 0 3px; -} +/*!* Вперед иназад кнопки *!*/ +/*.prev, .next {*/ +/* cursor: pointer;*/ +/* position: absolute;*/ +/* top: 50%;*/ +/* width: auto;*/ +/* margin-top: -22px;*/ +/* padding: 16px;*/ +/* color: white;*/ +/* font-weight: bold;*/ +/* font-size: 18px;*/ +/* transition: 0.6s ease;*/ +/* border-radius: 0 3px 3px 0;*/ +/* user-select: contain;*/ +/*}*/ -/* При наведении курсора добавьте черный цвет фона с немного прозрачным */ -.prev:hover, .next:hover { - display: flex; - justify-content: center; - background-color: rgba(0,0,0,0.8); - padding-top: 150px; -} +/*!* Положение "next кнопки" справа *!*/ +/*.next {*/ +/* right: 0;*/ +/* border-radius: 3px 0 0 3px;*/ +/*}*/ -/* Подпись текст */ -.text { - color: #f2f2f2; - font-size: 15px; - padding: 8px 12px; - position: absolute; - bottom: 8px; - width: 100%; - text-align: center; -} +/*!* При наведении курсора добавьте черный цвет фона с немного прозрачным *!*/ +/*.prev:hover, .next:hover {*/ +/* display: flex;*/ +/* justify-content: center;*/ +/* background-color: rgba(0,0,0,0.8);*/ +/* padding-top: 150px;*/ +/*}*/ -/* Номер текста (1/3 и т.д.) */ -.numbertext { - color: #f2f2f2; - font-size: 12px; - padding: 8px 12px; - position: absolute; - top: 0; -} +/*!* Подпись текст *!*/ +/*.text {*/ +/* color: #f2f2f2;*/ +/* font-size: 15px;*/ +/* padding: 8px 12px;*/ +/* position: absolute;*/ +/* bottom: 8px;*/ +/* width: 100%;*/ +/* text-align: center;*/ +/*}*/ -/* Точки/пули/индикаторы */ -.dot { - cursor: pointer; - height: 15px; - width: 15px; - margin: 0 2px; - background-color: #bbb; - border-radius: 50%; - display: inline-block; - transition: background-color 0.6s ease; -} +/*!* Номер текста (1/3 и т.д.) *!*/ +/*.numbertext {*/ +/* color: #f2f2f2;*/ +/* font-size: 12px;*/ +/* padding: 8px 12px;*/ +/* position: absolute;*/ +/* top: 0;*/ +/*}*/ -.active, .dot:hover { - background-color: #717171; -} +/*!* Точки/пули/индикаторы *!*/ +/*.dot {*/ +/* cursor: pointer;*/ +/* height: 15px;*/ +/* width: 15px;*/ +/* margin: 0 2px;*/ +/* background-color: #bbb;*/ +/* border-radius: 50%;*/ +/* display: inline-block;*/ +/* transition: background-color 0.6s ease;*/ +/*}*/ -/* Исчезающая анимация */ -.fade { - -webkit-animation-name: fade; - -webkit-animation-duration: 2.5s; - animation-name: fade; - animation-duration: 1000.5s; - /*animation-duration: 20.5s;*/ -} +/*.active, .dot:hover {*/ +/* background-color: #717171;*/ +/*}*/ -@-webkit-keyframes fade { - from {opacity: .9} - to {opacity: 1} -} +/*!* Исчезающая анимация *!*/ +/*.fade {*/ +/* -webkit-animation-name: fade;*/ +/* -webkit-animation-duration: 2.5s;*/ +/* animation-name: fade;*/ +/* animation-duration: 1000.5s;*/ +/* !*animation-duration: 20.5s;*!*/ +/*}*/ + +/*@-webkit-keyframes fade {*/ +/* from {opacity: .9}*/ +/* to {opacity: 1}*/ +/*}*/ -@keyframes fade { - from {opacity: .9} - to {opacity: 1} -} -.carousel-control-next-icon, .carousel-control-prev-icon { - width: 30px; - height: 30px; -} -/*.carousel-control-prev-icon {*/ -/* background-image: url("photo/left-arrow.png");*/ +/*@keyframes fade {*/ +/* from {opacity: .9}*/ +/* to {opacity: 1}*/ /*}*/ -/*.carousel-control-next-icon {*/ -/* background-image: url("photo/right-arrow.png");*/ +/*.carousel-control-next-icon, .carousel-control-prev-icon {*/ +/* width: 30px;*/ +/* height: 30px;*/ /*}*/ +/*!*.carousel-control-prev-icon {*!*/ +/*!* background-image: url("photo/left-arrow.png");*!*/ +/*!*}*!*/ +/*!*.carousel-control-next-icon {*!*/ +/*!* background-image: url("photo/right-arrow.png");*!*/ +/*!*}*!*/ diff --git a/src/main/resources/static/css/rating.css b/src/main/resources/static/css/rating.css index cc7d6bd..00af996 100644 --- a/src/main/resources/static/css/rating.css +++ b/src/main/resources/static/css/rating.css @@ -1,50 +1,50 @@ -.rating-area { - overflow: hidden; - width: 900px; - margin: 0 auto; - background-color: #a89a76; +/*.rating-area {*/ +/* overflow: hidden;*/ +/* width: 900px;*/ +/* margin: 0 auto;*/ +/* background-color: #a89a76;*/ -} -.rating-area:not(:checked) > input { - display: none; -} -.rating-area:not(:checked) > label { - float: none ; - margin-left: 18px; - width: 42px; - padding: 0; - cursor: pointer; - font-size: 32px; - line-height: 32px; - color: lightgrey; - text-shadow: 1px 1px #bbb; -} -.rating-area:not(:checked) > label:before { - content: '★'; +/*}*/ +/*.rating-area:not(:checked) > input {*/ +/* display: none;*/ +/*}*/ +/*.rating-area:not(:checked) > label {*/ +/* float: none ;*/ +/* margin-left: 18px;*/ +/* width: 42px;*/ +/* padding: 0;*/ +/* cursor: pointer;*/ +/* font-size: 32px;*/ +/* line-height: 32px;*/ +/* color: lightgrey;*/ +/* text-shadow: 1px 1px #bbb;*/ +/*}*/ +/*.rating-area:not(:checked) > label:before {*/ +/* content: '★';*/ -} -.rating-area > input:checked ~ label { - color: gold; - text-shadow: 1px 1px #c60; +/*}*/ +/*.rating-area > input:checked ~ label {*/ +/* color: gold;*/ +/* text-shadow: 1px 1px #c60;*/ -} -.rating-area:not(:checked) > label:hover, -.rating-area:not(:checked) > label:hover ~ label { - color: gold; -} -.rating-area > input:checked + label:hover, -.rating-area > input:checked + label:hover ~ label, -.rating-area > input:checked ~ label:hover, -.rating-area > input:checked ~ label:hover ~ label, -.rating-area > label:hover ~ input:checked ~ label { - color: gold; - text-shadow: 1px 1px goldenrod; -} -.rate-area > label:active { - position: relative; - background-color: #a89a76; -} -.btn-primary { - width: 220px; -} +/*}*/ +/*.rating-area:not(:checked) > label:hover,*/ +/*.rating-area:not(:checked) > label:hover ~ label {*/ +/* color: gold;*/ +/*}*/ +/*.rating-area > input:checked + label:hover,*/ +/*.rating-area > input:checked + label:hover ~ label,*/ +/*.rating-area > input:checked ~ label:hover,*/ +/*.rating-area > input:checked ~ label:hover ~ label,*/ +/*.rating-area > label:hover ~ input:checked ~ label {*/ +/* color: gold;*/ +/* text-shadow: 1px 1px goldenrod;*/ +/*}*/ +/*.rate-area > label:active {*/ +/* position: relative;*/ +/* background-color: #a89a76;*/ +/*}*/ +/*.btn-primary {*/ +/* width: 220px;*/ +/*}*/ diff --git a/src/main/resources/static/css/style.css b/src/main/resources/static/css/style.css index f78095b..c68af1c 100644 --- a/src/main/resources/static/css/style.css +++ b/src/main/resources/static/css/style.css @@ -1,88 +1,88 @@ -body { +/*body {*/ - background-color: #c2abab; - background-image: url("photo/BG1.jpg"); - background-size: cover; -} -section { - margin-top: 72px; +/* background-color: #c2abab;*/ +/* background-image: url("photo/BG1.jpg");*/ +/* background-size: cover;*/ +/*}*/ +/*section {*/ +/* margin-top: 72px;*/ -} -.card-img-top { - width: 100%; - height: 420px; -} -.card { - margin-left: 190px; - width: 70%; - border: solid 2px; - border-radius: 5px; - border-color: #91701f; - /*height: 420px;*/ -} -.card-body { - background-color: #d1cab8; -} -.container-xxl { - width: 1200px; -} -.offset-md-1{ - width: 970px; -} -.centered { - display: flex; - justify-content: center; - color: #543f09; - font-weight: bold; -} -.img-big { - margin-left: 200px; - width: 900px; - height: 450px; - border: solid 1px; - border-radius: 7px; - border-color: #91701f; -} -.table-striped { - margin-left: 200px; - width: 900px; - background-color: #e6e2d8; -} -.save_button { - display: flex; - justify-content: end; -} +/*}*/ +/*.card-img-top {*/ +/* width: 100%;*/ +/* height: 420px;*/ +/*}*/ +/*.card {*/ +/* margin-left: 190px;*/ +/* width: 70%;*/ +/* border: solid 2px;*/ +/* border-radius: 5px;*/ +/* border-color: #91701f;*/ +/* !*height: 420px;*!*/ +/*}*/ +/*.card-body {*/ +/* background-color: #d1cab8;*/ +/*}*/ +/*.container-xxl {*/ +/* width: 1200px;*/ +/*}*/ +/*.offset-md-1{*/ +/* width: 970px;*/ +/*}*/ +/*.centered {*/ +/* display: flex;*/ +/* justify-content: center;*/ +/* color: #543f09;*/ +/* font-weight: bold;*/ +/*}*/ +/*.img-big {*/ +/* margin-left: 200px;*/ +/* width: 900px;*/ +/* height: 450px;*/ +/* border: solid 1px;*/ +/* border-radius: 7px;*/ +/* border-color: #91701f;*/ +/*}*/ +/*.table-striped {*/ +/* margin-left: 200px;*/ +/* width: 900px;*/ +/* background-color: #e6e2d8;*/ +/*}*/ +/*.save_button {*/ +/* display: flex;*/ +/* justify-content: end;*/ +/*}*/ -.carousel-item { - width: 80%; -} -.carousel-control-prev, .carousel-control-next { - width: 30%; -} +/*.carousel-item {*/ +/* width: 80%;*/ +/*}*/ +/*.carousel-control-prev, .carousel-control-next {*/ +/* width: 30%;*/ +/*}*/ -label { - display: inline-block; - width: 200px; - margin: 5px; - text-align: left; - font-size: 25px; - color: #4d3b0b; - font-weight: bold; -} -input[type=text], input[type=password], select { - display: inline-block; - justify-content: center; - width: 442px; - height: 45px; -} -button { - padding: 5px; - margin: 10px; -} -h1 { - font-weight: bold; - color: #4d3b0b; - font-style: italic; - margin-left: 100px; -} +/*label {*/ +/* display: inline-block;*/ +/* width: 200px;*/ +/* margin: 5px;*/ +/* text-align: left;*/ +/* font-size: 25px;*/ +/* color: #4d3b0b;*/ +/* font-weight: bold;*/ +/*}*/ +/*input[type=text], input[type=password], select {*/ +/* display: inline-block;*/ +/* justify-content: center;*/ +/* width: 442px;*/ +/* height: 45px;*/ +/*}*/ +/*button {*/ +/* padding: 5px;*/ +/* margin: 10px;*/ +/*}*/ +/*h1 {*/ +/* font-weight: bold;*/ +/* color: #4d3b0b;*/ +/* font-style: italic;*/ +/* margin-left: 100px;*/ +/*}*/ From ba9cde22e6ae08b40d5affbc8ea1fa65f877f21b Mon Sep 17 00:00:00 2001 From: Oksana999 Date: Mon, 7 Dec 2020 14:28:37 -0600 Subject: [PATCH 07/39] Starting to work on saving recipes for users --- .../launchcode/recipeapp/controllers/RecipeController.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/main/java/org/launchcode/recipeapp/controllers/RecipeController.java b/src/main/java/org/launchcode/recipeapp/controllers/RecipeController.java index 3dd569a..bbee964 100644 --- a/src/main/java/org/launchcode/recipeapp/controllers/RecipeController.java +++ b/src/main/java/org/launchcode/recipeapp/controllers/RecipeController.java @@ -147,5 +147,10 @@ public String handleDeleteUser(@PathVariable Integer recipeId) { return "redirect:/recipes"; } + @RequestMapping("/save/{recipeId}") + public String saveRecipeToUser(@PathVariable Integer recipeId) { + return "index"; + } + } From 62e7306b16571b93cd9142601ba98b8d71f98ad8 Mon Sep 17 00:00:00 2001 From: missAH16 Date: Mon, 7 Dec 2020 22:03:35 -0600 Subject: [PATCH 08/39] login and registration forms --- build.gradle | 1 + .../recipeapp/AuthenticationFilter.java | 59 ++++++++ .../recipeapp/WebApplicationConfig.java | 20 +++ .../controllers/AuthenticationController.java | 134 ++++++++++++++++++ .../recipeapp/controllers/HomeController.java | 2 +- .../controllers/RecipeController.java | 2 +- .../launchcode/recipeapp/models/Category.java | 2 +- .../org/launchcode/recipeapp/models/User.java | 37 ++--- .../{ => models}/data/RecipeRepository.java | 5 +- .../{ => models}/data/UserRepository.java | 15 +- .../recipeapp/models/dto/LoginFormDTO.java | 35 +++++ .../models/dto/RegistrationFormDTO.java | 15 ++ src/main/resources/application.properties | 16 ++- src/main/resources/templates/fragments.html | 20 +-- src/main/resources/templates/login.html | 24 ++++ src/main/resources/templates/register.html | 32 +++++ 16 files changed, 366 insertions(+), 53 deletions(-) create mode 100644 src/main/java/org/launchcode/recipeapp/AuthenticationFilter.java create mode 100644 src/main/java/org/launchcode/recipeapp/WebApplicationConfig.java create mode 100644 src/main/java/org/launchcode/recipeapp/controllers/AuthenticationController.java rename src/main/java/org/launchcode/recipeapp/{ => models}/data/RecipeRepository.java (71%) rename src/main/java/org/launchcode/recipeapp/{ => models}/data/UserRepository.java (62%) create mode 100644 src/main/java/org/launchcode/recipeapp/models/dto/LoginFormDTO.java create mode 100644 src/main/java/org/launchcode/recipeapp/models/dto/RegistrationFormDTO.java create mode 100644 src/main/resources/templates/login.html create mode 100644 src/main/resources/templates/register.html diff --git a/build.gradle b/build.gradle index b1e9824..13730be 100644 --- a/build.gradle +++ b/build.gradle @@ -22,6 +22,7 @@ repositories { dependencies { implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'org.springframework.boot:spring-boot-starter-data-jpa' + implementation 'org.springframework.security:spring-security-crypto' developmentOnly 'org.springframework.boot:spring-boot-devtools' runtimeOnly 'mysql:mysql-connector-java' testImplementation('org.springframework.boot:spring-boot-starter-test') { diff --git a/src/main/java/org/launchcode/recipeapp/AuthenticationFilter.java b/src/main/java/org/launchcode/recipeapp/AuthenticationFilter.java new file mode 100644 index 0000000..a8aa2f7 --- /dev/null +++ b/src/main/java/org/launchcode/recipeapp/AuthenticationFilter.java @@ -0,0 +1,59 @@ +package org.launchcode.recipeapp; + + + +import org.launchcode.recipeapp.controllers.AuthenticationController; +import org.launchcode.recipeapp.models.User; +import org.launchcode.recipeapp.models.data.UserRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; +import java.io.IOException; +import java.util.Arrays; +import java.util.List; + +public class AuthenticationFilter extends HandlerInterceptorAdapter { + + @Autowired + UserRepository userRepository; + + @Autowired + AuthenticationController authenticationController; + + private static final List whitelist = Arrays.asList("/login", "/register", "/logout", "/css"); + + private static boolean isWhitelisted(String path) { + for (String pathRoot : whitelist) { + if (path.startsWith(pathRoot)) { + return true; + } + } + return false; + } + + @Override + public boolean preHandle(HttpServletRequest request, + HttpServletResponse response, + Object handler) throws IOException { + + if (isWhitelisted(request.getRequestURI())) { + return true; + + } + + HttpSession session = request.getSession(); + User user = authenticationController.getUserFromSession(session); + + // The user is logged in + if (user != null) { + return true; + } + + // The user is NOT logged in + response.sendRedirect("/login"); + return false; + } +} \ No newline at end of file diff --git a/src/main/java/org/launchcode/recipeapp/WebApplicationConfig.java b/src/main/java/org/launchcode/recipeapp/WebApplicationConfig.java new file mode 100644 index 0000000..433ea72 --- /dev/null +++ b/src/main/java/org/launchcode/recipeapp/WebApplicationConfig.java @@ -0,0 +1,20 @@ +package org.launchcode.recipeapp; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.InterceptorRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +@Configuration +public class WebApplicationConfig implements WebMvcConfigurer { + + @Bean + public AuthenticationFilter authenticationFilter() { + return new AuthenticationFilter(); + } + + @Override + public void addInterceptors(InterceptorRegistry registry) { + registry.addInterceptor(authenticationFilter()); + } +} \ No newline at end of file diff --git a/src/main/java/org/launchcode/recipeapp/controllers/AuthenticationController.java b/src/main/java/org/launchcode/recipeapp/controllers/AuthenticationController.java new file mode 100644 index 0000000..f27a915 --- /dev/null +++ b/src/main/java/org/launchcode/recipeapp/controllers/AuthenticationController.java @@ -0,0 +1,134 @@ +package org.launchcode.recipeapp.controllers; + +import org.launchcode.recipeapp.models.data.UserRepository; +import org.launchcode.recipeapp.models.dto.LoginFormDTO; +import org.launchcode.recipeapp.models.User; +import org.launchcode.recipeapp.models.dto.RegistrationFormDTO; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.validation.Errors; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.ModelAttribute; +import org.springframework.web.bind.annotation.PostMapping; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpSession; +import javax.validation.Valid; +import java.util.Optional; + +@Controller +public class +AuthenticationController { + + @Autowired + UserRepository userRepository; + + private static final String userSessionKey = "user"; + + public User getUserFromSession(HttpSession session) { + Integer userId = (Integer) session.getAttribute(userSessionKey); + if (userId == null) { + return null; + } + + Optional user = userRepository.findById(userId); + + if (user.isEmpty()) { + return null; + } + + return user.get(); + } + + private static void setUserInSession(HttpSession session, User user) { + session.setAttribute(userSessionKey, user.getId()); + } + + @GetMapping("/register") + public String displayRegistrationForm(Model model) { + model.addAttribute(new RegistrationFormDTO()); + model.addAttribute("title", "Register"); + return "register"; + } + + @PostMapping("/register") + public String processRegistrationForm(@ModelAttribute @Valid RegistrationFormDTO registrationFormDTO, + Errors errors, HttpServletRequest request, + Model model) { + + if (errors.hasErrors()) { + model.addAttribute("title", "Register"); + return "register"; + } + + User existingUser = userRepository.findByUsername(registrationFormDTO.getUsername()); + + if (existingUser != null) { + errors.rejectValue("username", "username.already exists", "A user with that username already exists"); + model.addAttribute("title", "Register"); + return "register"; + } + + String password = registrationFormDTO.getPassword(); + String verifyPassword = registrationFormDTO.getVerifyPassword(); + if (!password.equals(verifyPassword)) { + errors.rejectValue("password", "passwords.mismatch", "Passwords do not match"); + model.addAttribute("title", "Register"); + return "register"; + } + + User newUser = new User(registrationFormDTO.getUsername(), registrationFormDTO.getPassword()); + userRepository.save(newUser); + setUserInSession(request.getSession(), newUser); + + return "redirect:"; + } + + @GetMapping("/login") + public String displayLoginForm(Model model) { + model.addAttribute(new LoginFormDTO()); + model.addAttribute("title", "Log In"); + return "login"; + } + + @PostMapping("/login") + public String processLoginForm(@ModelAttribute @Valid LoginFormDTO loginFormDTO, + Errors errors, HttpServletRequest request, + Model model) { + + if (errors.hasErrors()) { + model.addAttribute("title", "Log In"); + return "login"; + } + + + User theUser = userRepository.findByUsername(loginFormDTO.getUsername()); + + if (theUser == null) { + errors.rejectValue("username", "user.invalid", "The given username does not exist"); + model.addAttribute("title", "Log In"); + return "login"; + } + + String password = loginFormDTO.getPassword(); + + if (!theUser.isMatchingPassword(password)) { + errors.rejectValue("password", "password.invalid", "Invalid password"); + model.addAttribute("title", "Log In"); + return "login"; + } + + setUserInSession(request.getSession(), theUser); + + return "redirect:"; + } + + + @GetMapping("/logout") + public String logout(HttpServletRequest request){ + request.getSession().invalidate(); + return "redirect:/login"; + } + +} \ No newline at end of file diff --git a/src/main/java/org/launchcode/recipeapp/controllers/HomeController.java b/src/main/java/org/launchcode/recipeapp/controllers/HomeController.java index 60ae7b5..ed1a4ff 100644 --- a/src/main/java/org/launchcode/recipeapp/controllers/HomeController.java +++ b/src/main/java/org/launchcode/recipeapp/controllers/HomeController.java @@ -1,7 +1,7 @@ package org.launchcode.recipeapp.controllers; -import org.launchcode.recipeapp.data.RecipeRepository; +import org.launchcode.recipeapp.models.data.RecipeRepository; import org.launchcode.recipeapp.models.Recipe; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; diff --git a/src/main/java/org/launchcode/recipeapp/controllers/RecipeController.java b/src/main/java/org/launchcode/recipeapp/controllers/RecipeController.java index d087f3b..5863b04 100644 --- a/src/main/java/org/launchcode/recipeapp/controllers/RecipeController.java +++ b/src/main/java/org/launchcode/recipeapp/controllers/RecipeController.java @@ -1,6 +1,6 @@ package org.launchcode.recipeapp.controllers; -import org.launchcode.recipeapp.data.RecipeRepository; +import org.launchcode.recipeapp.models.data.RecipeRepository; import org.launchcode.recipeapp.models.Category; import org.launchcode.recipeapp.models.Recipe; import org.launchcode.recipeapp.models.Tag; diff --git a/src/main/java/org/launchcode/recipeapp/models/Category.java b/src/main/java/org/launchcode/recipeapp/models/Category.java index 2ea0a1b..c549a84 100644 --- a/src/main/java/org/launchcode/recipeapp/models/Category.java +++ b/src/main/java/org/launchcode/recipeapp/models/Category.java @@ -5,7 +5,7 @@ */ public enum Category { - BEVERAGES, APPETIZER, ENTREE, SOUP, SALAD, DESSERT; + BEVERAGES, APPETIZER, ENTREE, SOUP, SIDES, DESSERT; } diff --git a/src/main/java/org/launchcode/recipeapp/models/User.java b/src/main/java/org/launchcode/recipeapp/models/User.java index ff9bf7d..0ae32ac 100644 --- a/src/main/java/org/launchcode/recipeapp/models/User.java +++ b/src/main/java/org/launchcode/recipeapp/models/User.java @@ -1,5 +1,7 @@ package org.launchcode.recipeapp.models; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; + import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; @@ -7,6 +9,7 @@ import javax.persistence.Table; import javax.validation.constraints.Email; import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; import java.util.ArrayList; import java.util.List; @@ -17,12 +20,14 @@ @Table public class User extends AbstractEntity { - @NotBlank(message = "User userName name is required") + /* @updated AH*/ + + private static final BCryptPasswordEncoder encoder = new BCryptPasswordEncoder(); + + + @NotBlank(message = "UserName name is required") private String username; - @NotBlank(message = "Email is required") - @Email(message = "Invalid email. Try again.") - private String email; @NotBlank(message = "Password is required") private String pwHash; @@ -37,34 +42,18 @@ public class User extends AbstractEntity { public User() { } - public User(String username, String email, String pwHash) { + public User(String username, String password) { this.username = username; - this.email = email; - this.pwHash = pwHash; + this.pwHash = encoder.encode(password); } public String getUsername() { return username; } - public void setUsername(String username) { - this.username = username; - } - - public String getEmail() { - return email; - } - - public void setEmail(String email) { - this.email = email; - } - - public String getPwHash() { - return pwHash; - } + public boolean isMatchingPassword(String password) { + return encoder.matches(password, pwHash); - public void setPwHash(String pwHash) { - this.pwHash = pwHash; } public Role getRole() { diff --git a/src/main/java/org/launchcode/recipeapp/data/RecipeRepository.java b/src/main/java/org/launchcode/recipeapp/models/data/RecipeRepository.java similarity index 71% rename from src/main/java/org/launchcode/recipeapp/data/RecipeRepository.java rename to src/main/java/org/launchcode/recipeapp/models/data/RecipeRepository.java index 0b34639..0ec92ae 100644 --- a/src/main/java/org/launchcode/recipeapp/data/RecipeRepository.java +++ b/src/main/java/org/launchcode/recipeapp/models/data/RecipeRepository.java @@ -1,4 +1,5 @@ -package org.launchcode.recipeapp.data; +package org.launchcode.recipeapp.models.data; + import org.launchcode.recipeapp.models.Recipe; import org.springframework.data.repository.CrudRepository; @@ -7,5 +8,5 @@ * @author Oksana */ public interface RecipeRepository extends CrudRepository { - Recipe findByName (String name); + Recipe findByName (String name); } diff --git a/src/main/java/org/launchcode/recipeapp/data/UserRepository.java b/src/main/java/org/launchcode/recipeapp/models/data/UserRepository.java similarity index 62% rename from src/main/java/org/launchcode/recipeapp/data/UserRepository.java rename to src/main/java/org/launchcode/recipeapp/models/data/UserRepository.java index 950c202..208df7a 100644 --- a/src/main/java/org/launchcode/recipeapp/data/UserRepository.java +++ b/src/main/java/org/launchcode/recipeapp/models/data/UserRepository.java @@ -1,14 +1,13 @@ -package org.launchcode.recipeapp.data; +package org.launchcode.recipeapp.models.data; + import org.launchcode.recipeapp.models.User; import org.springframework.data.repository.CrudRepository; import org.springframework.stereotype.Repository; -/** - * @author Oksana - */ -@Repository -public interface UserRepository extends CrudRepository { +import javax.transaction.Transactional; - User findByUsername (String userName); -} +@Repository +public interface UserRepository extends CrudRepository{ + User findByUsername(String username); +} \ No newline at end of file diff --git a/src/main/java/org/launchcode/recipeapp/models/dto/LoginFormDTO.java b/src/main/java/org/launchcode/recipeapp/models/dto/LoginFormDTO.java new file mode 100644 index 0000000..0f71083 --- /dev/null +++ b/src/main/java/org/launchcode/recipeapp/models/dto/LoginFormDTO.java @@ -0,0 +1,35 @@ +package org.launchcode.recipeapp.models.dto; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; + +public class LoginFormDTO { + + @NotNull + @NotBlank + @Size(min = 3, max = 20, message = "Invalid username. Must be between 3 and 20 characters.") + private String username; + + @NotNull + @NotBlank + @Size(min = 5, max = 30, message = "Invalid password. Must be between 5 and 30 characters.") + private String password; + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + +} diff --git a/src/main/java/org/launchcode/recipeapp/models/dto/RegistrationFormDTO.java b/src/main/java/org/launchcode/recipeapp/models/dto/RegistrationFormDTO.java new file mode 100644 index 0000000..02ce0cb --- /dev/null +++ b/src/main/java/org/launchcode/recipeapp/models/dto/RegistrationFormDTO.java @@ -0,0 +1,15 @@ +package org.launchcode.recipeapp.models.dto; + +public class RegistrationFormDTO extends LoginFormDTO { + + private String verifyPassword; + + public String getVerifyPassword() { + return verifyPassword; + } + + public void setVerifyPassword(String verifyPassword) { + this.verifyPassword = verifyPassword; + } + +} \ No newline at end of file diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 6cb940e..1ed2e38 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1,14 +1,18 @@ -# Datasource MySql -spring.datasource.url=jdbc:mysql://localhost:3306/recipes -spring.datasource.username=${DB_USER} -spring.datasource.password=${DB_PASS} -spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver + +# Database connection settings +spring.datasource.url=jdbc:mysql://localhost:3306/recipe-app +spring.datasource.username=recipe-app +spring.datasource.password=1Password! + # Specify the DBMS spring.jpa.database = MYSQL + # Show or not log for each sql query -spring.jpa.show-sql = true +spring.jpa.show-sql = false + # Hibernate ddl auto (create, create-drop, update) spring.jpa.hibernate.ddl-auto = update + # Use spring.jpa.properties.* for Hibernate native properties (the prefix is # stripped before adding them to the entity manager) spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL8Dialect diff --git a/src/main/resources/templates/fragments.html b/src/main/resources/templates/fragments.html index ee4b292..61650ae 100644 --- a/src/main/resources/templates/fragments.html +++ b/src/main/resources/templates/fragments.html @@ -7,19 +7,19 @@ Famous Sent Louis Recipes - - - - + - - + + -

Hello Friends!

+

Hello Friends!

-
- - +
+ +
diff --git a/src/main/resources/templates/login.html b/src/main/resources/templates/login.html new file mode 100644 index 0000000..8c51d0c --- /dev/null +++ b/src/main/resources/templates/login.html @@ -0,0 +1,24 @@ + + +
+
+
+ +

+
+
+ +

+
+ + +
+ +

Don't have an account? Register for one.

+ + + \ No newline at end of file diff --git a/src/main/resources/templates/register.html b/src/main/resources/templates/register.html new file mode 100644 index 0000000..c23e4d7 --- /dev/null +++ b/src/main/resources/templates/register.html @@ -0,0 +1,32 @@ + + + + +
+ +
+
+
+
+ +

+
+
+ +

+
+
+ +
+ + +
+ + + From 826ac70bfb4fe99de6449c8e54ae7b878b40ee57 Mon Sep 17 00:00:00 2001 From: missAH16 Date: Thu, 10 Dec 2020 09:09:37 -0600 Subject: [PATCH 09/39] corrected_forms --- .../recipeapp/AuthenticationFilter.java | 2 +- .../org/launchcode/recipeapp/models/User.java | 1 - src/main/resources/application.properties | 2 +- src/main/resources/templates/fragments.html | 30 ++++++++++++++----- src/main/resources/templates/login.html | 8 ++++- src/main/resources/templates/register.html | 15 +++++----- 6 files changed, 39 insertions(+), 19 deletions(-) diff --git a/src/main/java/org/launchcode/recipeapp/AuthenticationFilter.java b/src/main/java/org/launchcode/recipeapp/AuthenticationFilter.java index a8aa2f7..5d7d2aa 100644 --- a/src/main/java/org/launchcode/recipeapp/AuthenticationFilter.java +++ b/src/main/java/org/launchcode/recipeapp/AuthenticationFilter.java @@ -53,7 +53,7 @@ public boolean preHandle(HttpServletRequest request, } // The user is NOT logged in - response.sendRedirect("/login"); + response.sendRedirect("/login "); return false; } } \ No newline at end of file diff --git a/src/main/java/org/launchcode/recipeapp/models/User.java b/src/main/java/org/launchcode/recipeapp/models/User.java index 0ae32ac..d228489 100644 --- a/src/main/java/org/launchcode/recipeapp/models/User.java +++ b/src/main/java/org/launchcode/recipeapp/models/User.java @@ -17,7 +17,6 @@ * @author Oksana */ @Entity -@Table public class User extends AbstractEntity { /* @updated AH*/ diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 1ed2e38..4ac8636 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -8,7 +8,7 @@ spring.datasource.password=1Password! spring.jpa.database = MYSQL # Show or not log for each sql query -spring.jpa.show-sql = false +spring.jpa.show-sql = true # Hibernate ddl auto (create, create-drop, update) spring.jpa.hibernate.ddl-auto = update diff --git a/src/main/resources/templates/fragments.html b/src/main/resources/templates/fragments.html index 61650ae..589db10 100644 --- a/src/main/resources/templates/fragments.html +++ b/src/main/resources/templates/fragments.html @@ -12,14 +12,30 @@ --> - - + + -

Hello Friends!

+
+
+

Recipes R Us

+
+ +
-
- - + +

Hello Friends!

+ +
+ +
- + \ No newline at end of file diff --git a/src/main/resources/templates/login.html b/src/main/resources/templates/login.html index 8c51d0c..bd1f4e1 100644 --- a/src/main/resources/templates/login.html +++ b/src/main/resources/templates/login.html @@ -1,5 +1,11 @@ + + +
+ +
+

@@ -19,6 +25,6 @@

Don't have an account? Register for one.

- +
\ No newline at end of file diff --git a/src/main/resources/templates/register.html b/src/main/resources/templates/register.html index c23e4d7..1c71eaa 100644 --- a/src/main/resources/templates/register.html +++ b/src/main/resources/templates/register.html @@ -1,27 +1,26 @@ - -
- + +


-

+

-

+

From f799652d61283e3738aa5a04d1282c1ec7255bd9 Mon Sep 17 00:00:00 2001 From: Kelly Dobbs Date: Sun, 13 Dec 2020 20:31:29 -0600 Subject: [PATCH 10/39] initial commit --- .../controllers/RecipeController.java | 28 +++++++++- .../launchcode/recipeapp/models/Recipe.java | 50 ++++++++++++++++- .../launchcode/recipeapp/models/Review.java | 56 +++++++++++++++++++ .../models/data/ReviewRepository.java | 10 ++++ src/main/resources/application.properties | 2 +- .../resources/templates/recipes/display.html | 46 ++++++++------- 6 files changed, 166 insertions(+), 26 deletions(-) create mode 100644 src/main/java/org/launchcode/recipeapp/models/Review.java create mode 100644 src/main/java/org/launchcode/recipeapp/models/data/ReviewRepository.java diff --git a/src/main/java/org/launchcode/recipeapp/controllers/RecipeController.java b/src/main/java/org/launchcode/recipeapp/controllers/RecipeController.java index f13bf3a..000c8cc 100644 --- a/src/main/java/org/launchcode/recipeapp/controllers/RecipeController.java +++ b/src/main/java/org/launchcode/recipeapp/controllers/RecipeController.java @@ -1,9 +1,11 @@ package org.launchcode.recipeapp.controllers; +import org.launchcode.recipeapp.models.Review; import org.launchcode.recipeapp.models.data.RecipeRepository; import org.launchcode.recipeapp.models.Category; import org.launchcode.recipeapp.models.Recipe; import org.launchcode.recipeapp.models.Tag; +import org.launchcode.recipeapp.models.data.ReviewRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; @@ -33,6 +35,9 @@ public RecipeController(RecipeRepository recipeRepository) { this.recipeRepository = recipeRepository; } + @Autowired + public ReviewRepository reviewRepository; + @GetMapping public String getListOfRecipes(Model model) { Iterable recipes = recipeRepository.findAll(); @@ -80,7 +85,6 @@ public String displayRecipe(@RequestParam Integer recipeId, Model model) { model.addAttribute("title", "Invalid Recipe ID: " + recipeId); } else { Recipe recipe = result.get(); - model.addAttribute("title", recipe.getName()); model.addAttribute("recipe", recipe); } @@ -88,7 +92,27 @@ public String displayRecipe(@RequestParam Integer recipeId, Model model) { return "recipes/display"; } - @GetMapping("edit/{recipeId}") + @PostMapping("display") + public String processReviewForm(@RequestParam Integer recipeId, @RequestParam String comment, @RequestParam Integer rating, Model model) { + Optional result = recipeRepository.findById(recipeId); + Recipe recipe = result.get(); + model.addAttribute("title", recipe.getName()); + model.addAttribute("recipe", recipe); + + Review newReview = new Review(recipe, rating,comment); // this works properly + + reviewRepository.save(newReview);// can't save to Repository + recipe.calculateAverageRating(); + + System.out.println("newreview: " + newReview); + + + + return "recipes/display"; + } + + + @GetMapping("edit/{recipeId}") public String displayEditForm(Model model, @PathVariable int recipeId) { Category[] categories = Category.values(); diff --git a/src/main/java/org/launchcode/recipeapp/models/Recipe.java b/src/main/java/org/launchcode/recipeapp/models/Recipe.java index f1ad6f6..ae8ede8 100644 --- a/src/main/java/org/launchcode/recipeapp/models/Recipe.java +++ b/src/main/java/org/launchcode/recipeapp/models/Recipe.java @@ -7,9 +7,6 @@ import java.util.ArrayList; import java.util.List; -/** - * @author Oksana - */ @Entity public class Recipe extends AbstractEntity { @@ -26,6 +23,10 @@ public class Recipe extends AbstractEntity { private Tag tag; private String img; + private Double averageRating; + + @OneToMany(mappedBy = "recipe") + private final List reviews = new ArrayList<>(); @OneToMany(mappedBy = "recipe", cascade = {CascadeType.MERGE, CascadeType.REMOVE}) @NotNull(message = "User is required") @@ -34,6 +35,22 @@ public class Recipe extends AbstractEntity { public Recipe() { } + + public double calculateAverageRating(){ + int numRatings = reviews.size(); + int sumRatings = 0; + + for( int i =0; i < numRatings; i++){ + int rating = reviews.get(i).getRating(); + sumRatings += rating; + } + double average = sumRatings / numRatings; + averageRating = average; + return averageRating; + } + + + public String getName() { return name; } @@ -90,4 +107,31 @@ public Tag getTag() { public void setTag(Tag tag) { this.tag = tag; } + + public Double getAverageRating() { + return averageRating; + } + + public void setAverageRating(Double averageRating) { + this.averageRating = averageRating; + } + + public List getReviews() { + return reviews; + } + + @Override + public String toString() { + return "Recipe{" + + "name='" + name + '\'' + + ", ingredients='" + ingredients + '\'' + + ", directions='" + directions + '\'' + + ", category=" + category + + ", tag=" + tag + + ", img='" + img + '\'' + + ", averageRating=" + averageRating + + ", reviews=" + reviews + + ", users=" + users + + '}'; + } } diff --git a/src/main/java/org/launchcode/recipeapp/models/Review.java b/src/main/java/org/launchcode/recipeapp/models/Review.java new file mode 100644 index 0000000..5811b96 --- /dev/null +++ b/src/main/java/org/launchcode/recipeapp/models/Review.java @@ -0,0 +1,56 @@ +package org.launchcode.recipeapp.models; + +import javax.persistence.Entity; +import javax.persistence.ManyToOne; + +@Entity +public class Review extends AbstractEntity{ + + @ManyToOne + private Recipe recipe; + + private Integer rating; + private String comment; + + public Review() { + } + + public Review(Recipe recipe, Integer rating, String comment) { + this.recipe = recipe; + this.rating = rating; + this.comment = comment; + } + + public Recipe getRecipe() { + return recipe; + } + + public void setRecipe(Recipe recipe) { + this.recipe = recipe; + } + + public Integer getRating() { + return rating; + } + + public void setRating(Integer rating) { + this.rating = rating; + } + + public String getComment() { + return comment; + } + + public void setComment(String comment) { + this.comment = comment; + } + + @Override + public String toString() { + return "Review{" + + "recipe=" + recipe + + ", rating=" + rating + + ", comment='" + comment + '\'' + + '}'; + } +} diff --git a/src/main/java/org/launchcode/recipeapp/models/data/ReviewRepository.java b/src/main/java/org/launchcode/recipeapp/models/data/ReviewRepository.java new file mode 100644 index 0000000..f1a1577 --- /dev/null +++ b/src/main/java/org/launchcode/recipeapp/models/data/ReviewRepository.java @@ -0,0 +1,10 @@ +package org.launchcode.recipeapp.models.data; + +import org.launchcode.recipeapp.models.Review; +import org.springframework.data.repository.CrudRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface ReviewRepository extends CrudRepository { + +} diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 4ac8636..c56879d 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -2,7 +2,7 @@ # Database connection settings spring.datasource.url=jdbc:mysql://localhost:3306/recipe-app spring.datasource.username=recipe-app -spring.datasource.password=1Password! +spring.datasource.password=1Password # Specify the DBMS spring.jpa.database = MYSQL diff --git a/src/main/resources/templates/recipes/display.html b/src/main/resources/templates/recipes/display.html index 1471c59..01d4955 100644 --- a/src/main/resources/templates/recipes/display.html +++ b/src/main/resources/templates/recipes/display.html @@ -5,30 +5,11 @@
-


+


- -
- - - - - - - - - - - - -
- - - - @@ -53,6 +34,31 @@
+

Rating:

+
+
+
+

Leave a Review

+ + + + + + + + + + + + + + + +
+ + + +
From 6e15c51523d1d7440ffe00fd94f9e89257afbcf9 Mon Sep 17 00:00:00 2001 From: Kelly Dobbs Date: Sun, 13 Dec 2020 21:30:32 -0600 Subject: [PATCH 11/39] calc avg and display --- .../controllers/RecipeController.java | 20 +++++++---- .../launchcode/recipeapp/models/Recipe.java | 33 +++++-------------- .../resources/templates/recipes/display.html | 6 ++-- 3 files changed, 25 insertions(+), 34 deletions(-) diff --git a/src/main/java/org/launchcode/recipeapp/controllers/RecipeController.java b/src/main/java/org/launchcode/recipeapp/controllers/RecipeController.java index 000c8cc..0a6fbb6 100644 --- a/src/main/java/org/launchcode/recipeapp/controllers/RecipeController.java +++ b/src/main/java/org/launchcode/recipeapp/controllers/RecipeController.java @@ -6,6 +6,7 @@ import org.launchcode.recipeapp.models.Recipe; import org.launchcode.recipeapp.models.Tag; import org.launchcode.recipeapp.models.data.ReviewRepository; +import org.springframework.aop.scope.ScopedProxyUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; @@ -19,6 +20,8 @@ import org.springframework.web.servlet.mvc.support.RedirectAttributes; import javax.validation.Valid; +import java.sql.SQLOutput; +import java.util.List; import java.util.Optional; /** @@ -87,6 +90,12 @@ public String displayRecipe(@RequestParam Integer recipeId, Model model) { Recipe recipe = result.get(); model.addAttribute("title", recipe.getName()); model.addAttribute("recipe", recipe); + if (recipe.getReviews().isEmpty()) { + model.addAttribute("averageRating", "no ratings yet"); + } else { + recipe.calcAverage(); + model.addAttribute("averageRating", recipe.getAverageRating()); + } } return "recipes/display"; @@ -98,15 +107,12 @@ public String processReviewForm(@RequestParam Integer recipeId, @RequestParam St Recipe recipe = result.get(); model.addAttribute("title", recipe.getName()); model.addAttribute("recipe", recipe); + Review newReview = new Review(recipe, rating, comment); - Review newReview = new Review(recipe, rating,comment); // this works properly - - reviewRepository.save(newReview);// can't save to Repository - recipe.calculateAverageRating(); - - System.out.println("newreview: " + newReview); - + reviewRepository.save(newReview); + recipe.calcAverage(); + model.addAttribute("averageRating", recipe.getAverageRating()); return "recipes/display"; } diff --git a/src/main/java/org/launchcode/recipeapp/models/Recipe.java b/src/main/java/org/launchcode/recipeapp/models/Recipe.java index ae8ede8..3357fea 100644 --- a/src/main/java/org/launchcode/recipeapp/models/Recipe.java +++ b/src/main/java/org/launchcode/recipeapp/models/Recipe.java @@ -23,6 +23,8 @@ public class Recipe extends AbstractEntity { private Tag tag; private String img; + + //should this have a 1-to-1 with an averageRating field in the Review class? private Double averageRating; @OneToMany(mappedBy = "recipe") @@ -35,22 +37,19 @@ public class Recipe extends AbstractEntity { public Recipe() { } - - public double calculateAverageRating(){ - int numRatings = reviews.size(); + public void calcAverage(){ + List reviewList = getReviews(); + int numRatings = reviewList.size(); int sumRatings = 0; - for( int i =0; i < numRatings; i++){ - int rating = reviews.get(i).getRating(); - sumRatings += rating; + for(int i =0; i < numRatings; i++){ + int reviewRating = reviewList.get(i).getRating(); + sumRatings += reviewRating; } double average = sumRatings / numRatings; - averageRating = average; - return averageRating; + setAverageRating(average); } - - public String getName() { return name; } @@ -120,18 +119,4 @@ public List getReviews() { return reviews; } - @Override - public String toString() { - return "Recipe{" + - "name='" + name + '\'' + - ", ingredients='" + ingredients + '\'' + - ", directions='" + directions + '\'' + - ", category=" + category + - ", tag=" + tag + - ", img='" + img + '\'' + - ", averageRating=" + averageRating + - ", reviews=" + reviews + - ", users=" + users + - '}'; - } } diff --git a/src/main/resources/templates/recipes/display.html b/src/main/resources/templates/recipes/display.html index 01d4955..b298af8 100644 --- a/src/main/resources/templates/recipes/display.html +++ b/src/main/resources/templates/recipes/display.html @@ -35,7 +35,7 @@

Rating:

-
+

Leave a Review

@@ -50,8 +50,8 @@ - - +
+
From ab2b8880fbbedde4dc8a27b4e928e707a254cb65 Mon Sep 17 00:00:00 2001 From: Kelly Dobbs Date: Sun, 13 Dec 2020 21:58:12 -0600 Subject: [PATCH 12/39] display comments and total reviews --- .../controllers/RecipeController.java | 7 ++++-- .../launchcode/recipeapp/models/Recipe.java | 2 +- .../resources/templates/recipes/display.html | 22 ++++++++++++++++--- 3 files changed, 25 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/launchcode/recipeapp/controllers/RecipeController.java b/src/main/java/org/launchcode/recipeapp/controllers/RecipeController.java index 0a6fbb6..fec18b5 100644 --- a/src/main/java/org/launchcode/recipeapp/controllers/RecipeController.java +++ b/src/main/java/org/launchcode/recipeapp/controllers/RecipeController.java @@ -92,9 +92,11 @@ public String displayRecipe(@RequestParam Integer recipeId, Model model) { model.addAttribute("recipe", recipe); if (recipe.getReviews().isEmpty()) { model.addAttribute("averageRating", "no ratings yet"); + model.addAttribute("numRatings", "no ratings yet"); } else { - recipe.calcAverage(); + recipe.calculateAverageRating(); model.addAttribute("averageRating", recipe.getAverageRating()); + model.addAttribute("numRatings", recipe.getReviews().size()); } } @@ -111,8 +113,9 @@ public String processReviewForm(@RequestParam Integer recipeId, @RequestParam St reviewRepository.save(newReview); - recipe.calcAverage(); + recipe.calculateAverageRating(); model.addAttribute("averageRating", recipe.getAverageRating()); + model.addAttribute("numRatings", recipe.getReviews().size()); return "recipes/display"; } diff --git a/src/main/java/org/launchcode/recipeapp/models/Recipe.java b/src/main/java/org/launchcode/recipeapp/models/Recipe.java index 3357fea..dcdfbe9 100644 --- a/src/main/java/org/launchcode/recipeapp/models/Recipe.java +++ b/src/main/java/org/launchcode/recipeapp/models/Recipe.java @@ -37,7 +37,7 @@ public class Recipe extends AbstractEntity { public Recipe() { } - public void calcAverage(){ + public void calculateAverageRating(){ List reviewList = getReviews(); int numRatings = reviewList.size(); int sumRatings = 0; diff --git a/src/main/resources/templates/recipes/display.html b/src/main/resources/templates/recipes/display.html index b298af8..df80cbf 100644 --- a/src/main/resources/templates/recipes/display.html +++ b/src/main/resources/templates/recipes/display.html @@ -34,8 +34,14 @@ -

Rating:

-
+ +
+ +
+
+ +
+

Leave a Review

@@ -51,11 +57,21 @@
-
+
+
+ + + + + + + +
Comments
+
From 37108f4fbffcab7e2209cee1cc1a9f22608f9f45 Mon Sep 17 00:00:00 2001 From: Oksana999 Date: Mon, 14 Dec 2020 02:15:50 -0600 Subject: [PATCH 13/39] Change language --- src/main/resources/templates/recipes/display.html | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/resources/templates/recipes/display.html b/src/main/resources/templates/recipes/display.html index 1471c59..503dc11 100644 --- a/src/main/resources/templates/recipes/display.html +++ b/src/main/resources/templates/recipes/display.html @@ -14,15 +14,15 @@
- + - + - + - + - +
From b1bdb9a6c8241c5fdcad6fd6c7c7c5138c6f310a Mon Sep 17 00:00:00 2001 From: Oksana999 Date: Mon, 14 Dec 2020 03:31:02 -0600 Subject: [PATCH 14/39] Add possibility to save favorite recipes --- .../controllers/AuthenticationController.java | 17 +- .../recipeapp/controllers/HomeController.java | 29 +- .../recipeapp/controllers/UserController.java | 97 ++++++ .../recipeapp/models/UserRecipe.java | 5 + .../models/data/UserRecipeRepository.java | 15 + .../recipeapp/models/data/UserRepository.java | 11 +- .../recipeapp/models/dto/ActiveRecipeDTO.java | 23 ++ src/main/resources/static/css/carusel.css | 188 +++++------ src/main/resources/static/css/rating.css | 92 ++--- src/main/resources/static/css/style.css | 316 +++++++++++++----- src/main/resources/templates/fragments.html | 10 +- src/main/resources/templates/index.html | 20 +- .../resources/templates/recipes/display.html | 86 +++-- .../resources/templates/users/profile.html | 36 ++ 14 files changed, 654 insertions(+), 291 deletions(-) create mode 100644 src/main/java/org/launchcode/recipeapp/controllers/UserController.java create mode 100644 src/main/java/org/launchcode/recipeapp/models/data/UserRecipeRepository.java create mode 100644 src/main/java/org/launchcode/recipeapp/models/dto/ActiveRecipeDTO.java create mode 100644 src/main/resources/templates/users/profile.html diff --git a/src/main/java/org/launchcode/recipeapp/controllers/AuthenticationController.java b/src/main/java/org/launchcode/recipeapp/controllers/AuthenticationController.java index f27a915..08dce97 100644 --- a/src/main/java/org/launchcode/recipeapp/controllers/AuthenticationController.java +++ b/src/main/java/org/launchcode/recipeapp/controllers/AuthenticationController.java @@ -27,22 +27,11 @@ private static final String userSessionKey = "user"; public User getUserFromSession(HttpSession session) { - Integer userId = (Integer) session.getAttribute(userSessionKey); - if (userId == null) { - return null; - } - - Optional user = userRepository.findById(userId); - - if (user.isEmpty()) { - return null; - } - - return user.get(); + return (User) session.getAttribute(userSessionKey); } private static void setUserInSession(HttpSession session, User user) { - session.setAttribute(userSessionKey, user.getId()); + session.setAttribute(userSessionKey, user); } @GetMapping("/register") @@ -131,4 +120,4 @@ public String logout(HttpServletRequest request){ return "redirect:/login"; } -} \ No newline at end of file +} diff --git a/src/main/java/org/launchcode/recipeapp/controllers/HomeController.java b/src/main/java/org/launchcode/recipeapp/controllers/HomeController.java index ed1a4ff..6fdb797 100644 --- a/src/main/java/org/launchcode/recipeapp/controllers/HomeController.java +++ b/src/main/java/org/launchcode/recipeapp/controllers/HomeController.java @@ -1,13 +1,18 @@ package org.launchcode.recipeapp.controllers; +import org.launchcode.recipeapp.models.User; +import org.launchcode.recipeapp.models.UserRecipe; import org.launchcode.recipeapp.models.data.RecipeRepository; import org.launchcode.recipeapp.models.Recipe; +import org.launchcode.recipeapp.models.data.UserRecipeRepository; +import org.launchcode.recipeapp.models.dto.ActiveRecipeDTO; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; +import javax.servlet.http.HttpServletRequest; import java.util.ArrayList; import java.util.List; @@ -19,18 +24,34 @@ public class HomeController { private final RecipeRepository recipeRepository; + private final UserRecipeRepository userRecipeRepository; + @Autowired - public HomeController(RecipeRepository recipeRepository) { + public HomeController(RecipeRepository recipeRepository, UserRecipeRepository userRecipeRepository) { this.recipeRepository = recipeRepository; + this.userRecipeRepository = userRecipeRepository; } @GetMapping("") - public String home(Model model) { + public String home(Model model, HttpServletRequest request) { + User user = (User) request.getSession().getAttribute("user"); model.addAttribute("title", "Saint Louis Best Recipes"); - List recipes = new ArrayList<>(); + List recipes = new ArrayList<>(); Iterable all = recipeRepository.findAll(); - all.forEach(recipes::add); + + List allByUser = userRecipeRepository.getAllByUser(user); + + + for (Recipe recipe : all) { + ActiveRecipeDTO activeRecipeDTO = new ActiveRecipeDTO(); + activeRecipeDTO.setRecipe(recipe); + boolean isActive = allByUser.stream() + .anyMatch(recipeByUser -> recipeByUser.getRecipe().equals(recipe)); + activeRecipeDTO.setActive(isActive); + recipes.add(activeRecipeDTO); + } + model.addAttribute("recipes", recipes); diff --git a/src/main/java/org/launchcode/recipeapp/controllers/UserController.java b/src/main/java/org/launchcode/recipeapp/controllers/UserController.java new file mode 100644 index 0000000..d039bd9 --- /dev/null +++ b/src/main/java/org/launchcode/recipeapp/controllers/UserController.java @@ -0,0 +1,97 @@ +package org.launchcode.recipeapp.controllers; + +import org.launchcode.recipeapp.models.data.RecipeRepository; +import org.launchcode.recipeapp.models.data.UserRecipeRepository; +import org.launchcode.recipeapp.models.data.UserRepository; +import org.launchcode.recipeapp.models.Recipe; +import org.launchcode.recipeapp.models.User; +import org.launchcode.recipeapp.models.UserRecipe; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; + +import javax.servlet.http.HttpServletRequest; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +/** + * @author Oksana + */ +@Controller +@RequestMapping("users") +public class UserController { + + @Autowired + private UserRepository userRepository; + + @Autowired + private UserRecipeRepository userRecipeRepository; + + @Autowired + private RecipeRepository recipeRepository; + + + @GetMapping() + public String getAllUsers(Model model) { + List users = new ArrayList<>(); + + Iterable usersIter = userRepository.findAll(); + + + usersIter.forEach(users::add); + + + model.addAttribute("users", users); + return "users/index"; + } + + @GetMapping("/profile") + public String getUserProfile(HttpServletRequest request, Model model) { + User sessionUser = (User) request.getSession().getAttribute("user"); + if (sessionUser == null) { + model.addAttribute("title", "No user found"); + } else { + List recipes = new ArrayList<>(); + List userRecipes = userRecipeRepository.getAllByUser(sessionUser); + + for (UserRecipe userRecipe : userRecipes) { + Recipe recipe = userRecipe.getRecipe(); + recipes.add(recipe); + } + + model.addAttribute("title", sessionUser.getUsername()); + model.addAttribute("user", sessionUser); + model.addAttribute("recipes", recipes); + + } + return "users/profile"; + } + + @PostMapping("/addRecipe/{id}") + public String addRecipe(@PathVariable Integer id, HttpServletRequest request, Model model) { + User sessionUser = (User) request.getSession().getAttribute("user"); + + Optional recipeOptional = recipeRepository.findById(id); + if (recipeOptional.isPresent()) { + User user = userRepository.getById(sessionUser.getId()); + Recipe recipe = recipeOptional.get(); + UserRecipe userRecipe = new UserRecipe(); + userRecipe.setUser(user); + userRecipe.setRecipe(recipe); + userRecipeRepository.save(userRecipe); + + + model.addAttribute("user", userRecipe.getUser()); + model.addAttribute("recipe", userRecipe.getRecipe()); + } + + + return "redirect:/users/profile"; + } + +} diff --git a/src/main/java/org/launchcode/recipeapp/models/UserRecipe.java b/src/main/java/org/launchcode/recipeapp/models/UserRecipe.java index 4904707..836ff6c 100644 --- a/src/main/java/org/launchcode/recipeapp/models/UserRecipe.java +++ b/src/main/java/org/launchcode/recipeapp/models/UserRecipe.java @@ -1,5 +1,8 @@ package org.launchcode.recipeapp.models; +import lombok.Data; +import lombok.EqualsAndHashCode; + import javax.persistence.CascadeType; import javax.persistence.Entity; import javax.persistence.FetchType; @@ -12,6 +15,8 @@ /** * @author Oksana */ +@Data +@EqualsAndHashCode(callSuper = true) @Entity @Table public class UserRecipe extends AbstractEntity { diff --git a/src/main/java/org/launchcode/recipeapp/models/data/UserRecipeRepository.java b/src/main/java/org/launchcode/recipeapp/models/data/UserRecipeRepository.java new file mode 100644 index 0000000..ef5b725 --- /dev/null +++ b/src/main/java/org/launchcode/recipeapp/models/data/UserRecipeRepository.java @@ -0,0 +1,15 @@ +package org.launchcode.recipeapp.models.data; + +import org.launchcode.recipeapp.models.User; +import org.launchcode.recipeapp.models.UserRecipe; +import org.springframework.data.repository.CrudRepository; + +import java.util.List; + +/** + * @author Oksana + */ +public interface UserRecipeRepository extends CrudRepository { + + List getAllByUser(User user); +} diff --git a/src/main/java/org/launchcode/recipeapp/models/data/UserRepository.java b/src/main/java/org/launchcode/recipeapp/models/data/UserRepository.java index 208df7a..0ec8100 100644 --- a/src/main/java/org/launchcode/recipeapp/models/data/UserRepository.java +++ b/src/main/java/org/launchcode/recipeapp/models/data/UserRepository.java @@ -1,13 +1,12 @@ package org.launchcode.recipeapp.models.data; - import org.launchcode.recipeapp.models.User; import org.springframework.data.repository.CrudRepository; import org.springframework.stereotype.Repository; -import javax.transaction.Transactional; - @Repository -public interface UserRepository extends CrudRepository{ - User findByUsername(String username); -} \ No newline at end of file +public interface UserRepository extends CrudRepository { + User findByUsername(String username); + + User getById(Integer id); +} diff --git a/src/main/java/org/launchcode/recipeapp/models/dto/ActiveRecipeDTO.java b/src/main/java/org/launchcode/recipeapp/models/dto/ActiveRecipeDTO.java new file mode 100644 index 0000000..e531b35 --- /dev/null +++ b/src/main/java/org/launchcode/recipeapp/models/dto/ActiveRecipeDTO.java @@ -0,0 +1,23 @@ +package org.launchcode.recipeapp.models.dto; + +import lombok.Data; +import org.launchcode.recipeapp.models.Recipe; + +/** + * @author Oksana + */ +@Data +public class ActiveRecipeDTO { + + private Recipe recipe; + + private boolean isActive; + + public Recipe getRecipe() { + return recipe; + } + + public boolean isActive() { + return isActive; + } +} diff --git a/src/main/resources/static/css/carusel.css b/src/main/resources/static/css/carusel.css index f4d5112..692fb42 100644 --- a/src/main/resources/static/css/carusel.css +++ b/src/main/resources/static/css/carusel.css @@ -1,108 +1,108 @@ -/** {box-sizing:border-box}*/ +* {box-sizing:border-box} -/*!* Контейнер слайд-шоу *!*/ -/*.slideshow-container {*/ -/* max-width: 800px;*/ -/* position: relative;*/ -/* margin: auto;*/ -/*}*/ - -/*!* Скрыть изображения по умолчанию *!*/ -/*!*.mySlides {*!*/ -/*!* display: none;*!*/ -/*!*}*!*/ +/* Контейнер слайд-шоу */ +.slideshow-container { + max-width: 800px; + position: relative; + margin: auto; +} -/*!* Вперед иназад кнопки *!*/ -/*.prev, .next {*/ -/* cursor: pointer;*/ -/* position: absolute;*/ -/* top: 50%;*/ -/* width: auto;*/ -/* margin-top: -22px;*/ -/* padding: 16px;*/ -/* color: white;*/ -/* font-weight: bold;*/ -/* font-size: 18px;*/ -/* transition: 0.6s ease;*/ -/* border-radius: 0 3px 3px 0;*/ -/* user-select: contain;*/ +/* Скрыть изображения по умолчанию */ +/*.mySlides {*/ +/* display: none;*/ /*}*/ -/*!* Положение "next кнопки" справа *!*/ -/*.next {*/ -/* right: 0;*/ -/* border-radius: 3px 0 0 3px;*/ -/*}*/ +/* Вперед иназад кнопки */ +.prev, .next { + cursor: pointer; + position: absolute; + top: 50%; + width: auto; + margin-top: -22px; + padding: 16px; + color: white; + font-weight: bold; + font-size: 18px; + transition: 0.6s ease; + border-radius: 0 3px 3px 0; + user-select: contain; +} -/*!* При наведении курсора добавьте черный цвет фона с немного прозрачным *!*/ -/*.prev:hover, .next:hover {*/ -/* display: flex;*/ -/* justify-content: center;*/ -/* background-color: rgba(0,0,0,0.8);*/ -/* padding-top: 150px;*/ -/*}*/ +/* Положение "next кнопки" справа */ +.next { + right: 0; + border-radius: 3px 0 0 3px; +} -/*!* Подпись текст *!*/ -/*.text {*/ -/* color: #f2f2f2;*/ -/* font-size: 15px;*/ -/* padding: 8px 12px;*/ -/* position: absolute;*/ -/* bottom: 8px;*/ -/* width: 100%;*/ -/* text-align: center;*/ -/*}*/ +/* При наведении курсора добавьте черный цвет фона с немного прозрачным */ +.prev:hover, .next:hover { + display: flex; + justify-content: center; + background-color: rgba(0,0,0,0.8); + padding-top: 150px; +} -/*!* Номер текста (1/3 и т.д.) *!*/ -/*.numbertext {*/ -/* color: #f2f2f2;*/ -/* font-size: 12px;*/ -/* padding: 8px 12px;*/ -/* position: absolute;*/ -/* top: 0;*/ -/*}*/ +/* Подпись текст */ +.text { + color: #f2f2f2; + font-size: 15px; + padding: 8px 12px; + position: absolute; + bottom: 8px; + width: 100%; + text-align: center; +} -/*!* Точки/пули/индикаторы *!*/ -/*.dot {*/ -/* cursor: pointer;*/ -/* height: 15px;*/ -/* width: 15px;*/ -/* margin: 0 2px;*/ -/* background-color: #bbb;*/ -/* border-radius: 50%;*/ -/* display: inline-block;*/ -/* transition: background-color 0.6s ease;*/ -/*}*/ +/* Номер текста (1/3 и т.д.) */ +.numbertext { + color: #f2f2f2; + font-size: 12px; + padding: 8px 12px; + position: absolute; + top: 0; +} -/*.active, .dot:hover {*/ -/* background-color: #717171;*/ -/*}*/ +/* Точки/пули/индикаторы */ +.dot { + cursor: pointer; + height: 15px; + width: 15px; + margin: 0 2px; + background-color: #bbb; + border-radius: 50%; + display: inline-block; + transition: background-color 0.6s ease; +} -/*!* Исчезающая анимация *!*/ -/*.fade {*/ -/* -webkit-animation-name: fade;*/ -/* -webkit-animation-duration: 2.5s;*/ -/* animation-name: fade;*/ -/* animation-duration: 1000.5s;*/ -/* !*animation-duration: 20.5s;*!*/ -/*}*/ +.active, .dot:hover { + background-color: #717171; +} -/*@-webkit-keyframes fade {*/ -/* from {opacity: .9}*/ -/* to {opacity: 1}*/ -/*}*/ +/* Исчезающая анимация */ +.fade { + -webkit-animation-name: fade; + -webkit-animation-duration: 2.5s; + animation-name: fade; + animation-duration: 1000.5s; + /*animation-duration: 20.5s;*/ +} + +@-webkit-keyframes fade { + from {opacity: .9} + to {opacity: 1} +} -/*@keyframes fade {*/ -/* from {opacity: .9}*/ -/* to {opacity: 1}*/ +@keyframes fade { + from {opacity: .9} + to {opacity: 1} +} +.carousel-control-next-icon, .carousel-control-prev-icon { + width: 30px; + height: 30px; +} +/*.carousel-control-prev-icon {*/ +/* background-image: url("photo/left-arrow.png");*/ /*}*/ -/*.carousel-control-next-icon, .carousel-control-prev-icon {*/ -/* width: 30px;*/ -/* height: 30px;*/ +/*.carousel-control-next-icon {*/ +/* background-image: url("photo/right-arrow.png");*/ /*}*/ -/*!*.carousel-control-prev-icon {*!*/ -/*!* background-image: url("photo/left-arrow.png");*!*/ -/*!*}*!*/ -/*!*.carousel-control-next-icon {*!*/ -/*!* background-image: url("photo/right-arrow.png");*!*/ -/*!*}*!*/ diff --git a/src/main/resources/static/css/rating.css b/src/main/resources/static/css/rating.css index 00af996..cc7d6bd 100644 --- a/src/main/resources/static/css/rating.css +++ b/src/main/resources/static/css/rating.css @@ -1,50 +1,50 @@ -/*.rating-area {*/ -/* overflow: hidden;*/ -/* width: 900px;*/ -/* margin: 0 auto;*/ -/* background-color: #a89a76;*/ +.rating-area { + overflow: hidden; + width: 900px; + margin: 0 auto; + background-color: #a89a76; -/*}*/ -/*.rating-area:not(:checked) > input {*/ -/* display: none;*/ -/*}*/ -/*.rating-area:not(:checked) > label {*/ -/* float: none ;*/ -/* margin-left: 18px;*/ -/* width: 42px;*/ -/* padding: 0;*/ -/* cursor: pointer;*/ -/* font-size: 32px;*/ -/* line-height: 32px;*/ -/* color: lightgrey;*/ -/* text-shadow: 1px 1px #bbb;*/ -/*}*/ -/*.rating-area:not(:checked) > label:before {*/ -/* content: '★';*/ +} +.rating-area:not(:checked) > input { + display: none; +} +.rating-area:not(:checked) > label { + float: none ; + margin-left: 18px; + width: 42px; + padding: 0; + cursor: pointer; + font-size: 32px; + line-height: 32px; + color: lightgrey; + text-shadow: 1px 1px #bbb; +} +.rating-area:not(:checked) > label:before { + content: '★'; -/*}*/ -/*.rating-area > input:checked ~ label {*/ -/* color: gold;*/ -/* text-shadow: 1px 1px #c60;*/ +} +.rating-area > input:checked ~ label { + color: gold; + text-shadow: 1px 1px #c60; -/*}*/ -/*.rating-area:not(:checked) > label:hover,*/ -/*.rating-area:not(:checked) > label:hover ~ label {*/ -/* color: gold;*/ -/*}*/ -/*.rating-area > input:checked + label:hover,*/ -/*.rating-area > input:checked + label:hover ~ label,*/ -/*.rating-area > input:checked ~ label:hover,*/ -/*.rating-area > input:checked ~ label:hover ~ label,*/ -/*.rating-area > label:hover ~ input:checked ~ label {*/ -/* color: gold;*/ -/* text-shadow: 1px 1px goldenrod;*/ -/*}*/ -/*.rate-area > label:active {*/ -/* position: relative;*/ -/* background-color: #a89a76;*/ -/*}*/ -/*.btn-primary {*/ -/* width: 220px;*/ -/*}*/ +} +.rating-area:not(:checked) > label:hover, +.rating-area:not(:checked) > label:hover ~ label { + color: gold; +} +.rating-area > input:checked + label:hover, +.rating-area > input:checked + label:hover ~ label, +.rating-area > input:checked ~ label:hover, +.rating-area > input:checked ~ label:hover ~ label, +.rating-area > label:hover ~ input:checked ~ label { + color: gold; + text-shadow: 1px 1px goldenrod; +} +.rate-area > label:active { + position: relative; + background-color: #a89a76; +} +.btn-primary { + width: 220px; +} diff --git a/src/main/resources/static/css/style.css b/src/main/resources/static/css/style.css index c68af1c..844f207 100644 --- a/src/main/resources/static/css/style.css +++ b/src/main/resources/static/css/style.css @@ -1,88 +1,244 @@ -/*body {*/ -/* background-color: #c2abab;*/ +body { + + background-color: white; /* background-image: url("photo/BG1.jpg");*/ -/* background-size: cover;*/ -/*}*/ -/*section {*/ -/* margin-top: 72px;*/ + background-size: cover; +} -/*}*/ -/*.card-img-top {*/ -/* width: 100%;*/ -/* height: 420px;*/ -/*}*/ -/*.card {*/ -/* margin-left: 190px;*/ -/* width: 70%;*/ -/* border: solid 2px;*/ -/* border-radius: 5px;*/ -/* border-color: #91701f;*/ -/* !*height: 420px;*!*/ -/*}*/ -/*.card-body {*/ -/* background-color: #d1cab8;*/ -/*}*/ -/*.container-xxl {*/ -/* width: 1200px;*/ -/*}*/ -/*.offset-md-1{*/ -/* width: 970px;*/ -/*}*/ -/*.centered {*/ -/* display: flex;*/ -/* justify-content: center;*/ -/* color: #543f09;*/ -/* font-weight: bold;*/ -/*}*/ -/*.img-big {*/ -/* margin-left: 200px;*/ -/* width: 900px;*/ -/* height: 450px;*/ -/* border: solid 1px;*/ -/* border-radius: 7px;*/ -/* border-color: #91701f;*/ -/*}*/ -/*.table-striped {*/ -/* margin-left: 200px;*/ -/* width: 900px;*/ -/* background-color: #e6e2d8;*/ -/*}*/ -/*.save_button {*/ -/* display: flex;*/ -/* justify-content: end;*/ -/*}*/ +.container-xxl { + max-width: 1700px; + /*background-color: blue;*/ -/*.carousel-item {*/ -/* width: 80%;*/ -/*}*/ -/*.carousel-control-prev, .carousel-control-next {*/ -/* width: 30%;*/ -/*}*/ +} +.navbar > .container-xxl { + display: flex; + flex-wrap: inherit; + align-items: center; + justify-content: flex-end; + flex-direction: row; + /*background-color: blue;*/ +} +section { + margin-top: 72px; -/*label {*/ -/* display: inline-block;*/ -/* width: 200px;*/ -/* margin: 5px;*/ -/* text-align: left;*/ -/* font-size: 25px;*/ -/* color: #4d3b0b;*/ -/* font-weight: bold;*/ -/*}*/ -/*input[type=text], input[type=password], select {*/ -/* display: inline-block;*/ -/* justify-content: center;*/ -/* width: 442px;*/ -/* height: 45px;*/ -/*}*/ -/*button {*/ -/* padding: 5px;*/ -/* margin: 10px;*/ +} +.card-img-top { + height: 420px; +} +.card { + margin-left: 190px; + width: 70%; + border: solid 2px; + border-radius: 5px; + border-color: #91701f; + /*height: 420px;*/ +} +.card-body { + background-color: #d1cab8; +} + +.container { + display: flex; + justify-content: center; + max-width: 1320px; +} +.offset-md-1{ + width: 970px; +} +.centered { + display: flex; + justify-content: center; + color: #4d3b0b; + font-weight: bold; +} +.img-big { + margin-left: 200px; + width: 750px; + /*width: 680px;*/ + height: 350px; + border: solid 1px; + border-radius: 7px; + border-color: #91701f; +} +.table-striped { + margin-left: 200px; + width: 680px; + background-color: bisque; +} +.save_button { + display: flex; + justify-content: end; +} + +.carousel-control-next-icon { + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23000' viewBox='0 0 16 16'%3e%3cpath d='M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e"); +} + +.carousel-control-prev-icon { + + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23000' viewBox='0 0 16 16'%3e%3cpath d='M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0z'/%3e%3c/svg%3e"); +} +/*.carousel-control-prev-icon {*/ +/* background-image: url("photo/Left.png");*/ /*}*/ -/*h1 {*/ -/* font-weight: bold;*/ -/* color: #4d3b0b;*/ -/* font-style: italic;*/ -/* margin-left: 100px;*/ +/*.carousel-control-next-icon {*/ +/* background-image: url("photo/Right.png");*/ /*}*/ + + +.carousel-item { + width: 80%; + margin-left: 210px; +} +.carousel-control-prev, .carousel-control-next { + width: 50%; +} + + +label { + display: inline-block; + width: 200px; + margin: 5px; + text-align: left; + font-size: 25px; + color: #4d3b0b; + font-weight: bold; +} +input[type=text], input[type=password], select { + display: inline-block; + justify-content: center; + width: 442px; + height: 45px; +} + +button { + padding: 5px; + margin: 10px; +} +h1 { + font-weight: bold; + color: #4d3b0b; + font-style: italic; + margin-left: 100px; +} +.img-smal { + width: 150px; +} + +input[type="text"], input[type="password"], select { + display: inline-block; + justify-content: center; + + height: 42px; +} +[type="button"]:not(:disabled), [type="reset"]:not(:disabled), [type="submit"]:not(:disabled), button:not(:disabled) { + height: 40px; + margin-top: 1px; + background-color: #afb3c9; +} +.d-flex { + width: 370px; + margin-bottom: 15px; + height: 42px; + margin-top: 4px; +} +.btn btn-light { + margin-bottom: 9px; +} +.container { + max-width: 700px; +} +.container-recipe { + max-width: 700px; +} + + +.forma { + display: flex; + flex-direction: row; + justify-content: center; +} +.form-group { + display: flex; + flex-direction: row; + justify-content: center; + +} +.alert alert-secondary { + display: flex; + flex-direction: row; + justify-content: center; +} + +.alert-secondary { + color: #383d41; + background-color: #e2e3e5; + border-color: #d6d8db; + width: 40%; + display: flex; + flex-direction: row; + justify-items: center; + height: 82px; + margin-top: 10px; +} + +.form-control { + width: 95%; +} + +.navbar navbar-expand-lg navbar-light bg-light{ + /*background-color: blue;*/ +} + +.img-med { + width: 85%; + display: flex; + margin: auto; +} + +.title-recipes { + text-align: center; + margin: 25px; + font-size: 3.5rem; + color: #a3220d; + font-weight: 600; +} + +.table { + width: 100%; + max-width: 100%; + margin-bottom: 1rem; + background-color: #f2f2f2 !important;; +} + +.table table-striped { + background-color: #bbbbbb; +} +.btn btn-primary { + background-color: #3c96ff; + width: 300px !important; +} +[type="button"]:not(:disabled), [type="reset"]:not(:disabled), [type="submit"]:not(:disabled), button:not(:disabled) { + width: 205px; + background-color: #3c96ff; +} +th { + width: 165px; +} +.row { + + margin-right: 1px !important; + margin-left: 1px !important; +} +.btn-primary { + width: 300px !important; +} + + + + + + + diff --git a/src/main/resources/templates/fragments.html b/src/main/resources/templates/fragments.html index 589db10..8bbb907 100644 --- a/src/main/resources/templates/fragments.html +++ b/src/main/resources/templates/fragments.html @@ -7,10 +7,10 @@ Famous Sent Louis Recipes - + + + + @@ -38,4 +38,4 @@

Hello Friends!

- \ No newline at end of file + diff --git a/src/main/resources/templates/index.html b/src/main/resources/templates/index.html index bb3b506..ead5aac 100644 --- a/src/main/resources/templates/index.html +++ b/src/main/resources/templates/index.html @@ -14,12 +14,20 @@


th:class="${iterstat.index} == 0 ? 'carousel-item active':'carousel-item'">
-
- ... -
-
-

- Recipe Info +
+ ... +
+
+

+ + + Recipe Info + + +
+ + +
diff --git a/src/main/resources/templates/recipes/display.html b/src/main/resources/templates/recipes/display.html index 503dc11..6a22d09 100644 --- a/src/main/resources/templates/recipes/display.html +++ b/src/main/resources/templates/recipes/display.html @@ -3,55 +3,69 @@ -
+
+
-


+

+
- +
- - - - - - - - - - - - -
- + + + + + + + + + + + +
+ + + + + -
+ + - - - - - - - - + - - - - - - - + + + + + + + + + - - -
Ingredients:
Ingredients:
Directions:
Category:
Tags:
Directions:
Category:Add to favorite
+ + + Tags: + + + + + +
+ + +
+ + + +
diff --git a/src/main/resources/templates/users/profile.html b/src/main/resources/templates/users/profile.html new file mode 100644 index 0000000..f5114d4 --- /dev/null +++ b/src/main/resources/templates/users/profile.html @@ -0,0 +1,36 @@ + + + + +
+ + +
+ +

+ +
+
+
+ +
+ + + + + + + + + +
Description
+
+ + +
+
+ + + + From 5842391479ce566d13e7f556d90f8bf320f699d4 Mon Sep 17 00:00:00 2001 From: reyna biyo Date: Mon, 14 Dec 2020 16:30:18 -0600 Subject: [PATCH 15/39] Added search feature, need to improve --- .../controllers/SearchController.java | 39 +++++++++++++++++++ src/main/resources/templates/fragments.html | 22 ++++++++++- src/main/resources/templates/search.html | 26 +++++++++++++ 3 files changed, 86 insertions(+), 1 deletion(-) create mode 100644 src/main/java/org/launchcode/recipeapp/controllers/SearchController.java create mode 100644 src/main/resources/templates/search.html diff --git a/src/main/java/org/launchcode/recipeapp/controllers/SearchController.java b/src/main/java/org/launchcode/recipeapp/controllers/SearchController.java new file mode 100644 index 0000000..2866f78 --- /dev/null +++ b/src/main/java/org/launchcode/recipeapp/controllers/SearchController.java @@ -0,0 +1,39 @@ +package org.launchcode.recipeapp.controllers; + + +import org.launchcode.recipeapp.models.Recipe; +import org.launchcode.recipeapp.models.data.RecipeRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; + +import java.util.ArrayList; +import java.util.List; + +@Controller +@RequestMapping("search") +public class SearchController { + + @Autowired + private RecipeRepository recipeRepository; + + @PostMapping + public String searchByKeyword(Model model, @RequestParam String keyword) { + + List recipeList = new ArrayList<>(); + Iterable recipesIter = recipeRepository.findAll(); + recipesIter.forEach(recipeList::add); + List foundRecipes = new ArrayList<>(); + for (Recipe recipe : recipeList) { + if (recipe.getName().toLowerCase().contains(keyword.toLowerCase())) { + foundRecipes.add(recipe); + } + } + model.addAttribute("recipes", foundRecipes); + return "search"; + } + +} diff --git a/src/main/resources/templates/fragments.html b/src/main/resources/templates/fragments.html index 589db10..b8662b6 100644 --- a/src/main/resources/templates/fragments.html +++ b/src/main/resources/templates/fragments.html @@ -5,7 +5,7 @@ - Famous Sent Louis Recipes + Famous Saint Louis Recipes + + + + + + + + + + + +
diff --git a/src/main/resources/templates/search.html b/src/main/resources/templates/search.html new file mode 100644 index 0000000..2a8df04 --- /dev/null +++ b/src/main/resources/templates/search.html @@ -0,0 +1,26 @@ + + + + +
+ + +

+ +

Click on the recipe name to view recipe details

+ +
+
+
+ +
+ +
+ + +
+
+
+
+ + \ No newline at end of file From 512fbe9a46d8db094a684dcd081d070d13fdc85a Mon Sep 17 00:00:00 2001 From: Kelly Dobbs Date: Mon, 14 Dec 2020 17:32:57 -0600 Subject: [PATCH 16/39] updated average calculation --- .../recipeapp/controllers/RecipeController.java | 6 ------ .../java/org/launchcode/recipeapp/models/Recipe.java | 11 +++++++---- src/main/resources/templates/recipes/display.html | 12 +++++------- 3 files changed, 12 insertions(+), 17 deletions(-) diff --git a/src/main/java/org/launchcode/recipeapp/controllers/RecipeController.java b/src/main/java/org/launchcode/recipeapp/controllers/RecipeController.java index fec18b5..f325c2e 100644 --- a/src/main/java/org/launchcode/recipeapp/controllers/RecipeController.java +++ b/src/main/java/org/launchcode/recipeapp/controllers/RecipeController.java @@ -6,7 +6,6 @@ import org.launchcode.recipeapp.models.Recipe; import org.launchcode.recipeapp.models.Tag; import org.launchcode.recipeapp.models.data.ReviewRepository; -import org.springframework.aop.scope.ScopedProxyUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; @@ -20,13 +19,8 @@ import org.springframework.web.servlet.mvc.support.RedirectAttributes; import javax.validation.Valid; -import java.sql.SQLOutput; -import java.util.List; import java.util.Optional; -/** - * @author Oksana - */ @Controller @RequestMapping("recipes") public class RecipeController { diff --git a/src/main/java/org/launchcode/recipeapp/models/Recipe.java b/src/main/java/org/launchcode/recipeapp/models/Recipe.java index dcdfbe9..bc2f0cc 100644 --- a/src/main/java/org/launchcode/recipeapp/models/Recipe.java +++ b/src/main/java/org/launchcode/recipeapp/models/Recipe.java @@ -39,14 +39,17 @@ public Recipe() { public void calculateAverageRating(){ List reviewList = getReviews(); - int numRatings = reviewList.size(); - int sumRatings = 0; + double numRatings = reviewList.size(); + double sumRatings = 0.0; for(int i =0; i < numRatings; i++){ - int reviewRating = reviewList.get(i).getRating(); + double reviewRating = reviewList.get(i).getRating(); sumRatings += reviewRating; } - double average = sumRatings / numRatings; + // double average = sumRatings / numRatings; + double average = Double.parseDouble(String.format("%.1f",(double)sumRatings / numRatings)) ; + + System.out.println(average); setAverageRating(average); } diff --git a/src/main/resources/templates/recipes/display.html b/src/main/resources/templates/recipes/display.html index df80cbf..b683725 100644 --- a/src/main/resources/templates/recipes/display.html +++ b/src/main/resources/templates/recipes/display.html @@ -32,18 +32,16 @@ Add to favorite - +
-
- +
-
-
-
+ +

Leave a Review

@@ -60,7 +58,7 @@
-
+
From 3de6f6c7f19ee106d8e465a697f86097e0fa2174 Mon Sep 17 00:00:00 2001 From: Kelly Dobbs Date: Tue, 15 Dec 2020 23:15:30 -0600 Subject: [PATCH 17/39] merged master --- .../launchcode/recipeapp/models/UserRecipe.java | 16 ++++++++++++++++ src/main/resources/templates/fragments.html | 4 ++-- .../resources/templates/recipes/display.html | 9 +++++---- 3 files changed, 23 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/launchcode/recipeapp/models/UserRecipe.java b/src/main/java/org/launchcode/recipeapp/models/UserRecipe.java index 836ff6c..9322cc7 100644 --- a/src/main/java/org/launchcode/recipeapp/models/UserRecipe.java +++ b/src/main/java/org/launchcode/recipeapp/models/UserRecipe.java @@ -38,4 +38,20 @@ public class UserRecipe extends AbstractEntity { foreignKey = @ForeignKey(name = "FK_USER_RECIPE")) @NotNull(message = "") private Recipe recipe; + + public User getUser() { + return user; + } + + public void setUser(User user) { + this.user = user; + } + + public Recipe getRecipe() { + return recipe; + } + + public void setRecipe(Recipe recipe) { + this.recipe = recipe; + } } diff --git a/src/main/resources/templates/fragments.html b/src/main/resources/templates/fragments.html index 8bbb907..17e33e0 100644 --- a/src/main/resources/templates/fragments.html +++ b/src/main/resources/templates/fragments.html @@ -6,11 +6,11 @@ Famous Sent Louis Recipes - + diff --git a/src/main/resources/templates/recipes/display.html b/src/main/resources/templates/recipes/display.html index b683725..c48c53e 100644 --- a/src/main/resources/templates/recipes/display.html +++ b/src/main/resources/templates/recipes/display.html @@ -9,7 +9,12 @@ +
+ + + +
@@ -28,10 +33,6 @@ - - - -
Tags:
Add to favorite

From 1e0928ae3eaef23003d5fea8ea5c9eff990e70ca Mon Sep 17 00:00:00 2001 From: Kelly Dobbs Date: Wed, 16 Dec 2020 21:29:20 -0600 Subject: [PATCH 18/39] added timestamp and name field --- .../controllers/RecipeController.java | 30 ++++++++---- .../launchcode/recipeapp/models/Recipe.java | 49 +++++++++++-------- .../launchcode/recipeapp/models/Review.java | 46 +++++++++++++---- .../resources/templates/recipes/display.html | 20 ++++++-- 4 files changed, 101 insertions(+), 44 deletions(-) diff --git a/src/main/java/org/launchcode/recipeapp/controllers/RecipeController.java b/src/main/java/org/launchcode/recipeapp/controllers/RecipeController.java index f325c2e..c685e7a 100644 --- a/src/main/java/org/launchcode/recipeapp/controllers/RecipeController.java +++ b/src/main/java/org/launchcode/recipeapp/controllers/RecipeController.java @@ -88,7 +88,6 @@ public String displayRecipe(@RequestParam Integer recipeId, Model model) { model.addAttribute("averageRating", "no ratings yet"); model.addAttribute("numRatings", "no ratings yet"); } else { - recipe.calculateAverageRating(); model.addAttribute("averageRating", recipe.getAverageRating()); model.addAttribute("numRatings", recipe.getReviews().size()); } @@ -98,17 +97,28 @@ public String displayRecipe(@RequestParam Integer recipeId, Model model) { } @PostMapping("display") - public String processReviewForm(@RequestParam Integer recipeId, @RequestParam String comment, @RequestParam Integer rating, Model model) { - Optional result = recipeRepository.findById(recipeId); - Recipe recipe = result.get(); - model.addAttribute("title", recipe.getName()); - model.addAttribute("recipe", recipe); - Review newReview = new Review(recipe, rating, comment); + public String processReviewForm(@RequestParam Integer recipeId, + @Valid @RequestParam String comment, + @RequestParam Integer rating, + @Valid @RequestParam String name, + Errors errors, Model model) { + // not working + if (errors.hasErrors()) { + return "recipes/display"; + } + + Recipe recipe = recipeRepository.findById(recipeId).get(); - reviewRepository.save(newReview); + // Ratings and Reviews + Review review = new Review(recipe, rating, comment, name); + review.setTimestamp(); + reviewRepository.save(review); + recipe.setAverageRating(); + recipeRepository.save(recipe); - recipe.calculateAverageRating(); - model.addAttribute("averageRating", recipe.getAverageRating()); + model.addAttribute("title", recipe.getName()); + model.addAttribute("recipe", recipe); + model.addAttribute("review", review); model.addAttribute("numRatings", recipe.getReviews().size()); return "recipes/display"; diff --git a/src/main/java/org/launchcode/recipeapp/models/Recipe.java b/src/main/java/org/launchcode/recipeapp/models/Recipe.java index bc2f0cc..1392e31 100644 --- a/src/main/java/org/launchcode/recipeapp/models/Recipe.java +++ b/src/main/java/org/launchcode/recipeapp/models/Recipe.java @@ -24,7 +24,6 @@ public class Recipe extends AbstractEntity { private String img; - //should this have a 1-to-1 with an averageRating field in the Review class? private Double averageRating; @OneToMany(mappedBy = "recipe") @@ -37,22 +36,7 @@ public class Recipe extends AbstractEntity { public Recipe() { } - public void calculateAverageRating(){ - List reviewList = getReviews(); - double numRatings = reviewList.size(); - double sumRatings = 0.0; - - for(int i =0; i < numRatings; i++){ - double reviewRating = reviewList.get(i).getRating(); - sumRatings += reviewRating; - } - // double average = sumRatings / numRatings; - double average = Double.parseDouble(String.format("%.1f",(double)sumRatings / numRatings)) ; - - System.out.println(average); - setAverageRating(average); - } - + // Getters and Setters public String getName() { return name; } @@ -61,7 +45,6 @@ public void setName(String name) { this.name = name; } - public Category getCategory() { return category; } @@ -114,12 +97,38 @@ public Double getAverageRating() { return averageRating; } - public void setAverageRating(Double averageRating) { - this.averageRating = averageRating; + public void setAverageRating() { + List reviewList = getReviews(); + double numRatings = reviewList.size(); + double sumRatings = 0.0; + + for(int i =0; i < numRatings; i++){ + double reviewRating = reviewList.get(i).getRating(); + sumRatings += reviewRating; + } + double average = Double.parseDouble(String.format("%.1f",(double)sumRatings / numRatings)); + averageRating = average; } public List getReviews() { return reviews; } + + @Override + public String toString() { + return "Recipe{" + + "name='" + name + '\'' + + ", ingredients='" + ingredients + '\'' + + ", directions='" + directions + '\'' + + ", category=" + category + + ", tag=" + tag + + ", img='" + img + '\'' + + ", averageRating=" + averageRating + + ", reviews=" + reviews + + ", users=" + users + + '}'; + } + + } diff --git a/src/main/java/org/launchcode/recipeapp/models/Review.java b/src/main/java/org/launchcode/recipeapp/models/Review.java index 5811b96..7b52818 100644 --- a/src/main/java/org/launchcode/recipeapp/models/Review.java +++ b/src/main/java/org/launchcode/recipeapp/models/Review.java @@ -2,6 +2,11 @@ import javax.persistence.Entity; import javax.persistence.ManyToOne; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; @Entity public class Review extends AbstractEntity{ @@ -9,18 +14,28 @@ public class Review extends AbstractEntity{ @ManyToOne private Recipe recipe; - private Integer rating; + @NotBlank(message = "name is required") + @Size(min=2) + private String name; + + @Size(min=5, max=250) private String comment; + private Integer rating; + private String timestamp; + + public Review() { } - public Review(Recipe recipe, Integer rating, String comment) { + public Review(Recipe recipe, Integer rating, String comment, String name) { this.recipe = recipe; this.rating = rating; this.comment = comment; + this.name = name; } + // getters and setters public Recipe getRecipe() { return recipe; } @@ -45,12 +60,25 @@ public void setComment(String comment) { this.comment = comment; } - @Override - public String toString() { - return "Review{" + - "recipe=" + recipe + - ", rating=" + rating + - ", comment='" + comment + '\'' + - '}'; + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; } + + public String getTimestamp() { + return timestamp; + } + + public void setTimestamp() { + LocalDateTime timestampObj = LocalDateTime.now(); + DateTimeFormatter dateObj = DateTimeFormatter.ofPattern("MMMM d, yyyy"); + DateTimeFormatter timeObj = DateTimeFormatter.ofPattern("h:mm a"); + String dateTime = timestampObj.format(dateObj) + " at " + timestampObj.format(timeObj); + timestamp = dateTime; + } + + } diff --git a/src/main/resources/templates/recipes/display.html b/src/main/resources/templates/recipes/display.html index c48c53e..796cdfd 100644 --- a/src/main/resources/templates/recipes/display.html +++ b/src/main/resources/templates/recipes/display.html @@ -37,7 +37,7 @@
-
+

@@ -46,6 +46,7 @@

Leave a Review

+ My Rating:
@@ -56,18 +57,27 @@
-
- +
+
+
+
+
- - + + + + + + + +
Comments
NameRatingCommentDate
From c286ab322d0aadc7877ae2a2c9fcdfd0d1cfbed7 Mon Sep 17 00:00:00 2001 From: paalwilliams Date: Fri, 18 Dec 2020 17:39:16 -0600 Subject: [PATCH 19/39] add /search to whitelist --- .../java/org/launchcode/recipeapp/AuthenticationFilter.java | 2 +- src/main/resources/application.properties | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/launchcode/recipeapp/AuthenticationFilter.java b/src/main/java/org/launchcode/recipeapp/AuthenticationFilter.java index 5d7d2aa..194989c 100644 --- a/src/main/java/org/launchcode/recipeapp/AuthenticationFilter.java +++ b/src/main/java/org/launchcode/recipeapp/AuthenticationFilter.java @@ -23,7 +23,7 @@ public class AuthenticationFilter extends HandlerInterceptorAdapter { @Autowired AuthenticationController authenticationController; - private static final List whitelist = Arrays.asList("/login", "/register", "/logout", "/css"); + private static final List whitelist = Arrays.asList("/login", "/register", "/logout", "/css", "/search"); private static boolean isWhitelisted(String path) { for (String pathRoot : whitelist) { diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 4ac8636..3e0d309 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1,6 +1,6 @@ # Database connection settings -spring.datasource.url=jdbc:mysql://localhost:3306/recipe-app +spring.datasource.url=jdbc:mysql://localhost:3306/recipes spring.datasource.username=recipe-app spring.datasource.password=1Password! From 5601b63fbe2dc2a7ed1fd36a2e0381bbb3c3aa08 Mon Sep 17 00:00:00 2001 From: Oksana999 Date: Mon, 21 Dec 2020 16:01:26 -0600 Subject: [PATCH 20/39] Add header-navigation --- .../recipeapp/AuthenticationFilter.java | 6 +- .../controllers/AuthenticationController.java | 4 +- .../recipeapp/controllers/HomeController.java | 40 +------ .../controllers/RecipeController.java | 13 +- src/main/resources/static/css/rating.css | 4 +- src/main/resources/static/css/style.css | 71 +++++++---- src/main/resources/templates/fragments.html | 111 ++++++++++++------ src/main/resources/templates/index.html | 17 ++- src/main/resources/templates/login.html | 6 +- src/main/resources/templates/recipes/all.html | 29 +++++ .../resources/templates/recipes/create.html | 17 ++- .../resources/templates/recipes/display.html | 2 +- .../resources/templates/recipes/index.html | 4 +- src/main/resources/templates/register.html | 2 +- .../resources/templates/users/profile.html | 2 +- 15 files changed, 202 insertions(+), 126 deletions(-) create mode 100644 src/main/resources/templates/recipes/all.html diff --git a/src/main/java/org/launchcode/recipeapp/AuthenticationFilter.java b/src/main/java/org/launchcode/recipeapp/AuthenticationFilter.java index 194989c..efc5cee 100644 --- a/src/main/java/org/launchcode/recipeapp/AuthenticationFilter.java +++ b/src/main/java/org/launchcode/recipeapp/AuthenticationFilter.java @@ -23,7 +23,7 @@ public class AuthenticationFilter extends HandlerInterceptorAdapter { @Autowired AuthenticationController authenticationController; - private static final List whitelist = Arrays.asList("/login", "/register", "/logout", "/css", "/search"); + private static final List whitelist = Arrays.asList("/home", "/login", "/register", "/logout", "/css", "/recipes/all"); private static boolean isWhitelisted(String path) { for (String pathRoot : whitelist) { @@ -53,7 +53,7 @@ public boolean preHandle(HttpServletRequest request, } // The user is NOT logged in - response.sendRedirect("/login "); + response.sendRedirect("/home"); return false; } -} \ No newline at end of file +} diff --git a/src/main/java/org/launchcode/recipeapp/controllers/AuthenticationController.java b/src/main/java/org/launchcode/recipeapp/controllers/AuthenticationController.java index 08dce97..42c03b8 100644 --- a/src/main/java/org/launchcode/recipeapp/controllers/AuthenticationController.java +++ b/src/main/java/org/launchcode/recipeapp/controllers/AuthenticationController.java @@ -71,7 +71,7 @@ public String processRegistrationForm(@ModelAttribute @Valid RegistrationFormDTO userRepository.save(newUser); setUserInSession(request.getSession(), newUser); - return "redirect:"; + return "redirect:/home"; } @GetMapping("/login") @@ -110,7 +110,7 @@ public String processLoginForm(@ModelAttribute @Valid LoginFormDTO loginFormDTO, setUserInSession(request.getSession(), theUser); - return "redirect:"; + return "redirect:/home"; } diff --git a/src/main/java/org/launchcode/recipeapp/controllers/HomeController.java b/src/main/java/org/launchcode/recipeapp/controllers/HomeController.java index 6fdb797..32f9608 100644 --- a/src/main/java/org/launchcode/recipeapp/controllers/HomeController.java +++ b/src/main/java/org/launchcode/recipeapp/controllers/HomeController.java @@ -1,21 +1,13 @@ package org.launchcode.recipeapp.controllers; -import org.launchcode.recipeapp.models.User; -import org.launchcode.recipeapp.models.UserRecipe; -import org.launchcode.recipeapp.models.data.RecipeRepository; import org.launchcode.recipeapp.models.Recipe; -import org.launchcode.recipeapp.models.data.UserRecipeRepository; -import org.launchcode.recipeapp.models.dto.ActiveRecipeDTO; +import org.launchcode.recipeapp.models.data.RecipeRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; -import javax.servlet.http.HttpServletRequest; -import java.util.ArrayList; -import java.util.List; - /** * @author Oksana */ @@ -24,36 +16,16 @@ public class HomeController { private final RecipeRepository recipeRepository; - private final UserRecipeRepository userRecipeRepository; - @Autowired - public HomeController(RecipeRepository recipeRepository, UserRecipeRepository userRecipeRepository) { + public HomeController(RecipeRepository recipeRepository) { this.recipeRepository = recipeRepository; - this.userRecipeRepository = userRecipeRepository; } - @GetMapping("") - public String home(Model model, HttpServletRequest request) { - User user = (User) request.getSession().getAttribute("user"); - model.addAttribute("title", "Saint Louis Best Recipes"); - - List recipes = new ArrayList<>(); + @GetMapping("/home") + public String home(Model model) { Iterable all = recipeRepository.findAll(); - - List allByUser = userRecipeRepository.getAllByUser(user); - - - for (Recipe recipe : all) { - ActiveRecipeDTO activeRecipeDTO = new ActiveRecipeDTO(); - activeRecipeDTO.setRecipe(recipe); - boolean isActive = allByUser.stream() - .anyMatch(recipeByUser -> recipeByUser.getRecipe().equals(recipe)); - activeRecipeDTO.setActive(isActive); - recipes.add(activeRecipeDTO); - } - - - model.addAttribute("recipes", recipes); + model.addAttribute("recipes", all); + model.addAttribute("title", "Saint Louis Best Recipes"); return "index"; } diff --git a/src/main/java/org/launchcode/recipeapp/controllers/RecipeController.java b/src/main/java/org/launchcode/recipeapp/controllers/RecipeController.java index f13bf3a..25845ae 100644 --- a/src/main/java/org/launchcode/recipeapp/controllers/RecipeController.java +++ b/src/main/java/org/launchcode/recipeapp/controllers/RecipeController.java @@ -1,9 +1,9 @@ package org.launchcode.recipeapp.controllers; -import org.launchcode.recipeapp.models.data.RecipeRepository; import org.launchcode.recipeapp.models.Category; import org.launchcode.recipeapp.models.Recipe; import org.launchcode.recipeapp.models.Tag; +import org.launchcode.recipeapp.models.data.RecipeRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; @@ -17,6 +17,7 @@ import org.springframework.web.servlet.mvc.support.RedirectAttributes; import javax.validation.Valid; +import java.util.List; import java.util.Optional; /** @@ -87,6 +88,16 @@ public String displayRecipe(@RequestParam Integer recipeId, Model model) { return "recipes/display"; } + @GetMapping("all") + public String getAllRecipes (Model model){ + + List all = ((List) recipeRepository.findAll()); + + model.addAttribute("recipes", all); + + return "recipes/all"; + + } @GetMapping("edit/{recipeId}") public String displayEditForm(Model model, @PathVariable int recipeId) { diff --git a/src/main/resources/static/css/rating.css b/src/main/resources/static/css/rating.css index cc7d6bd..8940610 100644 --- a/src/main/resources/static/css/rating.css +++ b/src/main/resources/static/css/rating.css @@ -1,7 +1,7 @@ .rating-area { overflow: hidden; - width: 900px; - margin: 0 auto; + width: 750px; + margin-left: 55px; background-color: #a89a76; } diff --git a/src/main/resources/static/css/style.css b/src/main/resources/static/css/style.css index 844f207..887f68e 100644 --- a/src/main/resources/static/css/style.css +++ b/src/main/resources/static/css/style.css @@ -8,7 +8,7 @@ body { } .container-xxl { - max-width: 1700px; + max-width: 900px; /*background-color: blue;*/ } @@ -29,11 +29,11 @@ section { } .card { margin-left: 190px; - width: 70%; + width: 100%; border: solid 2px; border-radius: 5px; border-color: #91701f; - /*height: 420px;*/ + } .card-body { background-color: #d1cab8; @@ -54,16 +54,16 @@ section { font-weight: bold; } .img-big { - margin-left: 200px; + margin-left: 55px; width: 750px; /*width: 680px;*/ - height: 350px; + height: 400px; border: solid 1px; border-radius: 7px; border-color: #91701f; } .table-striped { - margin-left: 200px; + margin-left: 54px; width: 680px; background-color: bisque; } @@ -89,8 +89,8 @@ section { .carousel-item { - width: 80%; - margin-left: 210px; + width: 100%; + } .carousel-control-prev, .carousel-control-next { width: 50%; @@ -115,7 +115,9 @@ input[type=text], input[type=password], select { button { padding: 5px; - margin: 10px; + /*margin: 10px;*/ + margin-right: 10px; + background-color: #0a67f2; } h1 { font-weight: bold; @@ -136,12 +138,11 @@ input[type="text"], input[type="password"], select { [type="button"]:not(:disabled), [type="reset"]:not(:disabled), [type="submit"]:not(:disabled), button:not(:disabled) { height: 40px; margin-top: 1px; - background-color: #afb3c9; + background-color: #a4893a; } .d-flex { width: 370px; - margin-bottom: 15px; - height: 42px; + margin-bottom: 5px; margin-top: 4px; } .btn btn-light { @@ -185,7 +186,7 @@ input[type="text"], input[type="password"], select { } .form-control { - width: 95%; + width: 250px; } .navbar navbar-expand-lg navbar-light bg-light{ @@ -218,12 +219,13 @@ input[type="text"], input[type="password"], select { } .btn btn-primary { background-color: #3c96ff; - width: 300px !important; -} -[type="button"]:not(:disabled), [type="reset"]:not(:disabled), [type="submit"]:not(:disabled), button:not(:disabled) { - width: 205px; - background-color: #3c96ff; + width: 350px !important; + } +/*[type="button"]:not(:disabled), [type="reset"]:not(:disabled), [type="submit"]:not(:disabled), button:not(:disabled) {*/ +/* width: 205px;*/ +/* background-color: #3c96ff;*/ +/*}*/ th { width: 165px; } @@ -232,9 +234,38 @@ th { margin-right: 1px !important; margin-left: 1px !important; } -.btn-primary { - width: 300px !important; +.navbar-brand { + + color: #f2f2f2 !important; +} +.bg-light { + background-color: #0a67f2 !important; } +.right-header-btn { + display: flex; + + width: 20%; + justify-content: flex-end; +} +.left-header-btn { + display: flex; + width: 50%; + justify-content: flex-end; +} +.left-space-header { + margin-top: 8px; + margin-right: 10px; +} +.navbar-expand-lg .navbar-collapse { + display: contents !important; +} +.btn-light { + width: 105px; + height: 35px; + border-color: blue; +} + + diff --git a/src/main/resources/templates/fragments.html b/src/main/resources/templates/fragments.html index ae80873..2d96158 100644 --- a/src/main/resources/templates/fragments.html +++ b/src/main/resources/templates/fragments.html @@ -7,55 +7,92 @@ Famous Saint Louis Recipes - + - - + +
-
-

Recipes R Us

-
- +

Hello Friends!

-
- - + + + +
diff --git a/src/main/resources/templates/index.html b/src/main/resources/templates/index.html index ead5aac..a21afa9 100644 --- a/src/main/resources/templates/index.html +++ b/src/main/resources/templates/index.html @@ -3,6 +3,9 @@
+
+

To review recipes you need log in. You can do it here.

+
@@ -15,19 +18,13 @@


- ... + ...
-
-

+
+

- Recipe Info - - -
- - -
+ Recipe Info
diff --git a/src/main/resources/templates/login.html b/src/main/resources/templates/login.html index bd1f4e1..e507713 100644 --- a/src/main/resources/templates/login.html +++ b/src/main/resources/templates/login.html @@ -3,7 +3,7 @@
- +

@@ -26,5 +26,7 @@

Don't have an account? Register for one.

+
+
- \ No newline at end of file + diff --git a/src/main/resources/templates/recipes/all.html b/src/main/resources/templates/recipes/all.html new file mode 100644 index 0000000..e374a9d --- /dev/null +++ b/src/main/resources/templates/recipes/all.html @@ -0,0 +1,29 @@ + + + + +
+
+


+
+

To review recipes you need log in. You can do it here.

+
+ + + + + + + + + +
Recipes
+ + + +
+ +
+
+ + diff --git a/src/main/resources/templates/recipes/create.html b/src/main/resources/templates/recipes/create.html index 1ff6ca9..95e692c 100644 --- a/src/main/resources/templates/recipes/create.html +++ b/src/main/resources/templates/recipes/create.html @@ -6,7 +6,8 @@ -
+
+




@@ -20,10 +21,6 @@

Create Recipe



- - - -

+

- -
- + +

+
- +
diff --git a/src/main/resources/templates/recipes/display.html b/src/main/resources/templates/recipes/display.html index 6a22d09..a294178 100644 --- a/src/main/resources/templates/recipes/display.html +++ b/src/main/resources/templates/recipes/display.html @@ -2,7 +2,7 @@ - +
diff --git a/src/main/resources/templates/recipes/index.html b/src/main/resources/templates/recipes/index.html index 7f5c65a..f090ec6 100644 --- a/src/main/resources/templates/recipes/index.html +++ b/src/main/resources/templates/recipes/index.html @@ -2,8 +2,8 @@ - -
+
+

Recipes:

diff --git a/src/main/resources/templates/register.html b/src/main/resources/templates/register.html index 1c71eaa..59e4210 100644 --- a/src/main/resources/templates/register.html +++ b/src/main/resources/templates/register.html @@ -26,6 +26,6 @@ - +
diff --git a/src/main/resources/templates/users/profile.html b/src/main/resources/templates/users/profile.html index f5114d4..13c2940 100644 --- a/src/main/resources/templates/users/profile.html +++ b/src/main/resources/templates/users/profile.html @@ -31,6 +31,6 @@

- +
From 8e48a470a666082b7e14859d4c466deacb02daf7 Mon Sep 17 00:00:00 2001 From: Kelly Dobbs Date: Mon, 21 Dec 2020 19:11:39 -0600 Subject: [PATCH 21/39] uncommited changes --- src/main/java/org/launchcode/recipeapp/models/Recipe.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/org/launchcode/recipeapp/models/Recipe.java b/src/main/java/org/launchcode/recipeapp/models/Recipe.java index 1392e31..d7189e6 100644 --- a/src/main/java/org/launchcode/recipeapp/models/Recipe.java +++ b/src/main/java/org/launchcode/recipeapp/models/Recipe.java @@ -114,7 +114,6 @@ public List getReviews() { return reviews; } - @Override public String toString() { return "Recipe{" + From c800a9f1c1ac83acc5e160824918b3fc8502a5e9 Mon Sep 17 00:00:00 2001 From: reyna biyo Date: Mon, 21 Dec 2020 19:24:14 -0600 Subject: [PATCH 22/39] trying to do search by category --- recipes_table_and_data.sql | 158 ++++++++++++++++++ .../controllers/SearchController.java | 23 ++- src/main/resources/templates/fragments.html | 29 ++-- src/main/resources/templates/search.html | 18 +- 4 files changed, 200 insertions(+), 28 deletions(-) create mode 100644 recipes_table_and_data.sql diff --git a/recipes_table_and_data.sql b/recipes_table_and_data.sql new file mode 100644 index 0000000..9809b63 --- /dev/null +++ b/recipes_table_and_data.sql @@ -0,0 +1,158 @@ +-- MySQL dump 10.13 Distrib 8.0.16, for Win64 (x86_64) +-- +-- Host: localhost Database: recipes +-- ------------------------------------------------------ +-- Server version 8.0.16 + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; +/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; +/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; + SET NAMES utf8 ; +/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; +/*!40103 SET TIME_ZONE='+00:00' */; +/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; +/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; + +-- +-- Table structure for table `hibernate_sequence` +-- + +DROP TABLE IF EXISTS `hibernate_sequence`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `hibernate_sequence` ( + `next_val` bigint(20) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `hibernate_sequence` +-- + +LOCK TABLES `hibernate_sequence` WRITE; +/*!40000 ALTER TABLE `hibernate_sequence` DISABLE KEYS */; +INSERT INTO `hibernate_sequence` VALUES (21); +/*!40000 ALTER TABLE `hibernate_sequence` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `recipe` +-- + +DROP TABLE IF EXISTS `recipe`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `recipe` ( + `id` int(11) NOT NULL, + `category` int(11) NOT NULL, + `directions` varchar(1000) DEFAULT NULL, + `img` varchar(500) DEFAULT NULL, + `ingredients` varchar(1000) NOT NULL, + `name` varchar(255) DEFAULT NULL, + `tag` int(11) DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `recipe` +-- + +LOCK TABLES `recipe` WRITE; +/*!40000 ALTER TABLE `recipe` DISABLE KEYS */; +INSERT INTO `recipe` VALUES (1,3,'\"1. Slice oni1. Slice onions -- 1/8\"\" thick. 2. Melt butter, place onions in it, saute slowly for 1 1/2 hours in a large soup pot. 3. Add all other ingredients except bouillon, saute over low heat 10 minutes more. \"','https://photos.riverfronttimes.com/wp-content/uploads/2020/04/03-FRENCH-ONION.jpg','\"3 pounds3 pounds (1360 grams) Onions, raw 8 tbsp Butter, unsalted 1.50 tsp Pepper, black 1 tsp, crumbled Bay Leaf 2 tbsp Paprika 8 fl oz White Wine 12 cups Beef Broth 0.75 cup spelt flour 2 tsp Sea Salt (1360 grams) Onions, raw\"','Famous Barr\'s French Onion Soup',0),(3,5,'\"1. Preheat oven to 350° F. Line muffin tins with 12 foil cupcake papers. Place a vanilla wafer in the bottom of each cupcake paper. 2. In mixing bowl, beat cream cheese and fat-free cream cheese until smooth. Add sugar and vanilla and mix well. Add eggs and beat until smooth. ','https://sparkpeo.hs.llnwd.net/e1/resize/630m620/e2/guid/Mini-Cheesecakes-RECIPE/fdf44cec-936c-4abd-bc71-675fdb5aac2f.jpg','\"12 low-fat vanilla wafers 3 oz. cream cheese, at room temperature 12 oz. fat-free cream cheese, at room temperature 1/2 cup sugar 1/2 teaspoon vanilla 2 eggs cherry pie filling\"','Mini Cheesecakes',0),(5,0,'Combine the first 3 ingredients in a gallon-size ziploc bag, shake it up, and then add the salmon. Allow to marinate in the refrigerator for an hour, turning after half an hour. Pour the salmon and the marinade into a baking dish and bake in a 350 degree oven, covered with foil, for 15 minutes. The salmon is done when it flakes easily at the thickest part. Enjoy! Makes (4) 3 ounce servings. ','https://sparkpeo.hs.llnwd.net/e2/guid/Worlds-Best-(and-Easiest)-Salmon/d6637946-83d1-4cbb-90c2-a40ab6ea8780.jpg','\"1/4 cup pure maple syrup (NOT pancake syrup!) or honey 1/4 cup soy sauce 2-3 cloves minced garlic 12 ounces fresh or thawed salmon\"','World\'s Best (and Easiest) Salmon',5),(8,2,'Preheat the oven or toaster oven to 425 degrees F. Brush both sides of the eggplant with the oil and season with the salt and pepper. Arrange on a baking sheet and bake until browned and almost tender, 6 to 8 minutes, turning once. Spread 1 tablespoon of pasta sauce on each eggplant slice. Top with the shredded cheese. Bake until the cheese melts, 3 to 5 minutes. Serve hot.','https://sparkpeo.hs.llnwd.net/e2/guid/-Mini-Eggplant-Pizzas/f098cccb-7de1-4738-a18a-ab6774ca6325.jpg','\"1 eggplant - 3 inches in diameter, peeled and cut into 4 half-inch thick slices 4 teaspoons olive oil 1/2 teaspoon salt 1/8 teaspoon ground black pepper 1/4 cup pasta sauce 1/2 cup shredded part-skim mozzarella cheese\"','Mini Eggplant Pizzas',1),(9,4,'1. Wash tomatoes and cilantro.\r\n2. Dice tomatoes, onions, chop cilantro, jalapenos, and the optional ingredients (avocado, cucumber)\r\n3. Put ingredients in a bowl.\r\n4. Add salt, garlic, the juice of half a lemon. Mix it up and serve.','https://sparkpeo.hs.llnwd.net/e2/guid/Pico-de-Gallo---Authentic-Mexican-Salsa/23188500-3d62-4362-a3fe-8885b798241e.jpg','3 large diced tomatoes 1 diced medium sized onion 1/4 bunch of cilantro (use more or less depending on your taste) juice of half a lemon 1/2 teaspoon of minced garlic 1 tsp of salt 2 jalapenos (or more if you prefer it hotter)','Pico de Gallo - Authentic Mexican Salsa',1),(10,2,'1. Preheat oven to 425 degrees F.\r\n2. In a shallow pan, toss potatoes and carrots with oil, salt and pepper.\r\n3. Nestle peeled garlic cloves amongst the vegetables and scatter the rosemary on top.\r\n4. Arrange the chicken among the vegetables and bake uncovered for 30 minutes.\r\n5. Meanwhile, stir the mustard and honey together.\r\n6. Remove the pan from the oven. Carefully take the chicken from the pan to another clean plate. Spread the honey-mustard mixture over the chicken.\r\n7. Stir vegetables in the pan, return coated chicken to the pan, and place pan back into the oven. Bake 10-20 minutes, until chicken is cooked and vegetables are tender.','https://sparkpeo.hs.llnwd.net/e4/nw/2/6/l26327171.jpg','1 lb. potatoes, cut into wedges\r\n2 lbs. chicken, rinsed\r\n6 medium carrots, sliced\r\n2 Tablespoons olive oil\r\n1-1/2 Tablespoons honey\r\n3 Tablespoons mustard\r\n1 teaspoon dried rosemary\r\n2 heads garlic, peeled\r\nsalt and pepper to taste','Honey Mustard Roasted Chicken',4),(11,5,'Place all ingredients in blender and process to desired consistency. Makes 3 servings approx 3/4 cup each.','https://sparkpeo.hs.llnwd.net/e2/guid/5-Minute-Berry-Smoothie/d702b10b-cab7-4bbd-92a6-6cf53d2131b6.jpg','1 cup berries any type (I like Kirkland\'s Frozen Mixed Berry Blend)\r\n1 small banana (6\")\r\n1 cup Low Fat Vanilla Yogurt (I used Mountain High which is made with fructose, if you use an artificially sweetened product the calories will be lower)\r\n1/2 cup skim milk or enough as needed to make to a drinking consistency','5-Minute Berry Smoothie',0),(12,5,'CRUST: Spread the sugar cookie dough over a 14-inch pizza pan. Bake in a 375 degree oven for 12 minutes or until lightly golden brown. Cool in the pan.\r\n\r\nTOPPING: Blend the cream cheese with the sugar and vanilla until completely mixed. Spread in a thin layer over the cooled crust.\r\n\r\nFRUIT LAYER: Creatively arrange the fruit in circles while slightly overlapping the slices around the crust.\r\n\r\nGLAZE: Bring the water and preserves to a boil, stirring constantly. Lightly brush this glaze on top on the fruit to preserve the color. Refrigerate until ready to serve.','https://sparkpeo.hs.llnwd.net/e2/guid/Fruit-Pizza-/824e0313-21dd-4a0c-ba52-e7c88b8cff25.jpg','1/2 package of refrigerated sugar cookie dough\r\n8 ounces reduced-fat cream cheese, whipped\r\n1/3 cup powdered sugar\r\n1/2 teaspoon vanilla\r\n1 tablespoon water\r\n1/4 cup apricot preserves\r\nFruit of your choice (sliced bananas, sliced strawberries, sliced kiwi, seedless grapes cut in half, blueberries, melon balls sliced in half)','Fruit Pizza',0),(13,5,'CRUST: Spread the sugar cookie dough over a 14-inch pizza pan. Bake in a 375 degree oven for 12 minutes or until lightly golden brown. Cool in the pan.\r\n\r\nTOPPING: Blend the cream cheese with the sugar and vanilla until completely mixed. Spread in a thin layer over the cooled crust.\r\n\r\nFRUIT LAYER: Creatively arrange the fruit in circles while slightly overlapping the slices around the crust.\r\n\r\n','https://sparkpeo.hs.llnwd.net/e2/guid/Fruit-Pizza-/824e0313-21dd-4a0c-ba52-e7c88b8cff25.jpg','1/2 package of refrigerated sugar cookie dough\r\n8 ounces reduced-fat cream cheese, whipped\r\n1/3 cup powdered sugar\r\n1/2 teaspoon vanilla\r\n1 tablespoon water\r\n1/4 cup apricot preserves\r\nFruit of your choice (sliced bananas, sliced strawberries, sliced kiwi, seedless grapes cut in half, blueberries, melon balls sliced in half)','Fruit Pizza',0),(14,5,'CRUST: Spread the sugar cookie dough over a 14-inch pizza pan. Bake in a 375 degree oven for 12 minutes or until lightly golden brown. Cool in the pan.\r\n\r\nTOPPING: Blend the cream cheese with the sugar and vanilla until completely mixed. Spread in a thin layer over the cooled crust.\r\n\r\nFRUIT LAYER: Creatively arrange the fruit in circles while slightly overlapping the slices around the crust.\r\n\r\n','https://sparkpeo.hs.llnwd.net/e2/guid/Fruit-Pizza-/824e0313-21dd-4a0c-ba52-e7c88b8cff25.jpg','1/2 package of refrigerated sugar cookie dough\r\n8 ounces reduced-fat cream cheese, whipped\r\n1/3 cup powdered sugar\r\n1/2 teaspoon vanilla\r\n1 tablespoon water\r\n1/4 cup apricot preserves\r\nFruit of your choice (sliced bananas, sliced strawberries, sliced kiwi, seedless grapes cut in half, blueberries, melon balls sliced in half)','Fruit Pizza',0),(15,5,'CRUST: Spread the sugar cookie dough over a 14-inch pizza pan. Bake in a 375 degree oven for 12 minutes or until lightly golden brown. Cool in the pan.\r\n\r\nTOPPING: Blend the cream cheese with the sugar and vanilla until completely mixed. Spread in a thin layer over the cooled crust.\r\n\r\nFRUIT LAYER: Creatively arrange the fruit in circles while slightly overlapping the slices around the crust.\r\n\r\n','https://sparkpeo.hs.llnwd.net/e2/guid/Fruit-Pizza-/824e0313-21dd-4a0c-ba52-e7c88b8cff25.jpg','1/2 package of refrigerated sugar cookie dough\r\n8 ounces reduced-fat cream cheese, whipped\r\n1/3 cup powdered sugar\r\n1/2 teaspoon vanilla\r\n1 tablespoon water\r\n1/4 cup apricot preserves\r\nFruit of your choice (sliced bananas, sliced strawberries, sliced kiwi, seedless grapes cut in half, blueberries, melon balls sliced in half)','Fruit Pizza',0),(16,5,'CRUST: Spread the sugar cookie dough over a 14-inch pizza pan. Bake in a 375 degree oven for 12 minutes or until lightly golden brown. Cool in the pan.\r\n\r\nTOPPING: Blend the cream cheese with the sugar and vanilla until completely mixed. Spread in a thin layer over the cooled crust.\r\n\r\nFRUIT LAYER: Creatively arrange the fruit in circles while slightly overlapping the slices around the crust.\r\n\r\n','https://sparkpeo.hs.llnwd.net/e2/guid/Fruit-Pizza-/824e0313-21dd-4a0c-ba52-e7c88b8cff25.jpg','1/2 package of refrigerated sugar cookie dough\r\n8 ounces reduced-fat cream cheese, whipped\r\n1/3 cup powdered sugar\r\n1/2 teaspoon vanilla\r\n1 tablespoon water\r\n1/4 cup apricot preserves\r\nFruit of your choice (sliced bananas, sliced strawberries, sliced kiwi, seedless grapes cut in half, blueberries, melon balls sliced in half)','Fruit Pizza',0),(17,3,'Crumble sausage into a Dutch oven; add onion. Cook and stir over medium heat until meat is no longer pink.\r\n\r\nAdd garlic; cook and stir 2 minutes longer.\r\n\r\nAdd the broth and tomatoes. Bring to a boil.\r\n\r\nStir in tortellini; return to a boil. Reduce heat; simmer, uncovered, for 5-8 minutes or until pasta is tender, stirring occasionally.\r\n\r\nAdd the spinach, basil, pepper and pepper flakes; cook 2-3 minutes longer or until spinach is wilted. Serve with cheese if desired.\r\n\r\n','https://sparkpeo.hs.llnwd.net/e2/guid/Rustic-Italian-Tortellini-Soup/57d3d1d0-0779-4198-a233-ca08a758e6dd.jpg','3 Italian turkey sausage links (4 ounces each), casings removed (I used the \"hot\" sausage version)\r\n1 medium onion, chopped\r\n6 garlic cloves, minced\r\n4 cups reduced-sodium chicken broth\r\n1 can (14-1/2 ounces) diced tomatoes, undrained\r\n1 package (9 ounces) refrigerated cheese tortellini\r\n1 package (6 ounces) fresh baby spinach, coarsely chopped\r\n2-1/4 teaspoons minced fresh basil or 3/4 teaspoon dried basil (or, you can substitute thyme and oregano)\r\n1/4 teaspoon pepper','Rustic Italian Tortellini Soup',4),(18,2,'1. Place chicken in 13x9x2\" glass baking dish.\r\n\r\n2. Mix lemon juice, vinegar, lemon peel, oregano, and onions. Pour over chicken, cover and marinate in refrigerator several hours or overnight, turning occasionally.\r\n\r\n3. Sprinkle with salt, pepper, and paprika.\r\n\r\n4. Cover and bake at 325º F for 30 minutes. Uncover and bake 30 minutes more or until done.\r\n\r\n','https://sparkpeo.hs.llnwd.net/e2/guid/Easy-Lemon-Chicken-/1217b5a4-46f2-4eb0-8ccc-00eb59111056.jpg','1-1/2 lb. chicken breast, skinned and fat removed\r\n3 lemons, juiced and zested, flesh cut into segments\r\n1 Tablespoon vinegar (or balsamic vinegar)\r\n3 teaspoons chopped fresh oregano or 1 teaspoon dried oregano, crushed\r\n1 medium onion, sliced\r\n1/4 teaspoon salt\r\nBlack pepper to taste\r\n1/2 teaspoon paprika','Easy Lemon Chicken',4),(19,5,'Beat egg whites and dash of salt until soft peaks form. Gradually add in sugar while beating until peaks are stiff and glossy.\r\nFold in coconut.\r\nDrop by rounded teaspoon onto greased baking sheet.\r\nBake at 325*F 18-20 minutes until set and very slightly browned.\r\nCenter will still be soft.','https://sparkpeo.hs.llnwd.net/e2/guid/Coconut-Meringue-Cookies/fe015d9c-5250-4e5f-aa81-d5a337cdaaa6.jpg','1-1/2 cups sweetened shredded coconut\r\n2 egg whites\r\n1/4 tsp vanilla extract\r\nDash of salt\r\n2/3 cup granulated sugar','Coconut Meringue Cookies',2),(20,1,'Add all ingredients to blender or food processor and process to desired consistency. Add salt (about 1/2 tsp) to taste. Serve chilled. Enjoy with your favorite chips or tortillas.','https://sparkpeo.hs.llnwd.net/e2/guid/Coach-Nicoles-Fresh-&-Skinny-Guacamole/2d0c18b7-6bf7-45c9-8858-d45734e9fcfa.jpg','2 ripe avocados, peeled and chopped\r\n1/3 medium organic* cucumber, chopped\r\n1/3 medium onion, chopped (I use red onion)\r\n1 garlic clove, minced\r\n1 tsp cumin powder\r\n1 squeeze lemon (about 1-2 Tbsp juice)\r\nSalt to taste (about 1/2 tsp)','Coach Nicole\'s Fresh & Skinny Guacamole',1); +/*!40000 ALTER TABLE `recipe` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `recipe_ingredient` +-- + +DROP TABLE IF EXISTS `recipe_ingredient`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `recipe_ingredient` ( + `id` int(11) NOT NULL, + `weight` int(11) DEFAULT NULL, + `recipe_id` int(11) DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `FK_RECIPE_INGREDIENT` (`recipe_id`), + CONSTRAINT `FK_RECIPE_INGREDIENT` FOREIGN KEY (`recipe_id`) REFERENCES `recipe` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `recipe_ingredient` +-- + +LOCK TABLES `recipe_ingredient` WRITE; +/*!40000 ALTER TABLE `recipe_ingredient` DISABLE KEYS */; +/*!40000 ALTER TABLE `recipe_ingredient` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `user` +-- + +DROP TABLE IF EXISTS `user`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `user` ( + `id` int(11) NOT NULL, + `email` varchar(255) DEFAULT NULL, + `pw_hash` varchar(255) DEFAULT NULL, + `user_role` int(11) DEFAULT NULL, + `username` varchar(255) DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `user` +-- + +LOCK TABLES `user` WRITE; +/*!40000 ALTER TABLE `user` DISABLE KEYS */; +/*!40000 ALTER TABLE `user` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `user_recipe` +-- + +DROP TABLE IF EXISTS `user_recipe`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `user_recipe` ( + `id` int(11) NOT NULL, + `recipe_id` int(11) NOT NULL, + `user_id` int(11) NOT NULL, + PRIMARY KEY (`id`), + KEY `FK_USER_RECIPE` (`recipe_id`), + KEY `FK_USER` (`user_id`), + CONSTRAINT `FK_USER` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`), + CONSTRAINT `FK_USER_RECIPE` FOREIGN KEY (`recipe_id`) REFERENCES `recipe` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `user_recipe` +-- + +LOCK TABLES `user_recipe` WRITE; +/*!40000 ALTER TABLE `user_recipe` DISABLE KEYS */; +/*!40000 ALTER TABLE `user_recipe` ENABLE KEYS */; +UNLOCK TABLES; +/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; + +/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; +/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; +/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; +/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; +/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; +/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; + +-- Dump completed on 2020-12-04 9:33:57 diff --git a/src/main/java/org/launchcode/recipeapp/controllers/SearchController.java b/src/main/java/org/launchcode/recipeapp/controllers/SearchController.java index 2866f78..91b6861 100644 --- a/src/main/java/org/launchcode/recipeapp/controllers/SearchController.java +++ b/src/main/java/org/launchcode/recipeapp/controllers/SearchController.java @@ -1,14 +1,13 @@ package org.launchcode.recipeapp.controllers; +import org.launchcode.recipeapp.models.Category; import org.launchcode.recipeapp.models.Recipe; import org.launchcode.recipeapp.models.data.RecipeRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.*; import java.util.ArrayList; import java.util.List; @@ -20,7 +19,10 @@ public class SearchController { @Autowired private RecipeRepository recipeRepository; - @PostMapping + + + + @PostMapping(value="/results") public String searchByKeyword(Model model, @RequestParam String keyword) { List recipeList = new ArrayList<>(); @@ -36,4 +38,17 @@ public String searchByKeyword(Model model, @RequestParam String keyword) { return "search"; } + @PostMapping(value= "/selectedCategory") + public String getRecipeByCategory(@ModelAttribute Category category, Model model){ + Iterable recipes = recipeRepository.findAll(); + List recipeByCategory = new ArrayList<>(); + for (Recipe recipe:recipes) { + if(recipe.getCategory().name().equals(category.name())){ + recipeByCategory.add(recipe); + } + model.addAttribute("recipes", recipeByCategory); + } + return "search"; + } + } diff --git a/src/main/resources/templates/fragments.html b/src/main/resources/templates/fragments.html index ae80873..eae6d95 100644 --- a/src/main/resources/templates/fragments.html +++ b/src/main/resources/templates/fragments.html @@ -30,23 +30,22 @@

Recipes R Us

diff --git a/src/main/resources/templates/search.html b/src/main/resources/templates/search.html index 2a8df04..214bc85 100644 --- a/src/main/resources/templates/search.html +++ b/src/main/resources/templates/search.html @@ -4,19 +4,19 @@
+
-

- -

Click on the recipe name to view recipe details

+

-
-
+
-
- -
- +
+ +
+ + +
From 47c1aae2d431ce53d9202484d19e70acc4d16349 Mon Sep 17 00:00:00 2001 From: reyna biyo Date: Mon, 21 Dec 2020 21:47:11 -0600 Subject: [PATCH 23/39] finished search by category --- .../controllers/AuthenticationController.java | 2 ++ .../recipeapp/controllers/HomeController.java | 3 ++- .../recipeapp/controllers/SearchController.java | 13 ++++++++++--- src/main/resources/templates/fragments.html | 4 ++-- 4 files changed, 16 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/launchcode/recipeapp/controllers/AuthenticationController.java b/src/main/java/org/launchcode/recipeapp/controllers/AuthenticationController.java index 08dce97..edf9754 100644 --- a/src/main/java/org/launchcode/recipeapp/controllers/AuthenticationController.java +++ b/src/main/java/org/launchcode/recipeapp/controllers/AuthenticationController.java @@ -1,5 +1,6 @@ package org.launchcode.recipeapp.controllers; +import org.launchcode.recipeapp.models.Category; import org.launchcode.recipeapp.models.data.UserRepository; import org.launchcode.recipeapp.models.dto.LoginFormDTO; import org.launchcode.recipeapp.models.User; @@ -78,6 +79,7 @@ public String processRegistrationForm(@ModelAttribute @Valid RegistrationFormDTO public String displayLoginForm(Model model) { model.addAttribute(new LoginFormDTO()); model.addAttribute("title", "Log In"); + model.addAttribute("categories", Category.values()); return "login"; } diff --git a/src/main/java/org/launchcode/recipeapp/controllers/HomeController.java b/src/main/java/org/launchcode/recipeapp/controllers/HomeController.java index 6fdb797..8ddd0a9 100644 --- a/src/main/java/org/launchcode/recipeapp/controllers/HomeController.java +++ b/src/main/java/org/launchcode/recipeapp/controllers/HomeController.java @@ -1,6 +1,7 @@ package org.launchcode.recipeapp.controllers; +import org.launchcode.recipeapp.models.Category; import org.launchcode.recipeapp.models.User; import org.launchcode.recipeapp.models.UserRecipe; import org.launchcode.recipeapp.models.data.RecipeRepository; @@ -36,7 +37,7 @@ public HomeController(RecipeRepository recipeRepository, UserRecipeRepository us public String home(Model model, HttpServletRequest request) { User user = (User) request.getSession().getAttribute("user"); model.addAttribute("title", "Saint Louis Best Recipes"); - + model.addAttribute("categories", Category.values()); List recipes = new ArrayList<>(); Iterable all = recipeRepository.findAll(); diff --git a/src/main/java/org/launchcode/recipeapp/controllers/SearchController.java b/src/main/java/org/launchcode/recipeapp/controllers/SearchController.java index 91b6861..bbf3692 100644 --- a/src/main/java/org/launchcode/recipeapp/controllers/SearchController.java +++ b/src/main/java/org/launchcode/recipeapp/controllers/SearchController.java @@ -19,7 +19,11 @@ public class SearchController { @Autowired private RecipeRepository recipeRepository; - + @GetMapping("") + public String renderSearch(Model model) { + model.addAttribute("categories", Category.values()); + return "search"; + } @PostMapping(value="/results") @@ -35,18 +39,21 @@ public String searchByKeyword(Model model, @RequestParam String keyword) { } } model.addAttribute("recipes", foundRecipes); + model.addAttribute("categories", Category.values()); return "search"; } @PostMapping(value= "/selectedCategory") - public String getRecipeByCategory(@ModelAttribute Category category, Model model){ + public String getRecipeByCategory(@RequestParam Category category, Model model){ Iterable recipes = recipeRepository.findAll(); List recipeByCategory = new ArrayList<>(); for (Recipe recipe:recipes) { - if(recipe.getCategory().name().equals(category.name())){ + if(recipe.getCategory().name().toLowerCase().equals(category.name().toLowerCase())){ recipeByCategory.add(recipe); } model.addAttribute("recipes", recipeByCategory); + model.addAttribute("categories", Category.values()); + } return "search"; } diff --git a/src/main/resources/templates/fragments.html b/src/main/resources/templates/fragments.html index eae6d95..32179da 100644 --- a/src/main/resources/templates/fragments.html +++ b/src/main/resources/templates/fragments.html @@ -36,7 +36,7 @@

Recipes R Us

-
From 744c9aee573277103c9c10b121e04d92f7057b64 Mon Sep 17 00:00:00 2001 From: Kelly Dobbs Date: Sat, 2 Jan 2021 19:37:32 -0600 Subject: [PATCH 27/39] display only reviews with comments --- .../controllers/RecipeController.java | 56 +++++++++++++------ .../launchcode/recipeapp/models/Recipe.java | 24 +++++++- .../launchcode/recipeapp/models/Review.java | 7 +-- .../resources/templates/recipes/display.html | 15 +++-- 4 files changed, 71 insertions(+), 31 deletions(-) diff --git a/src/main/java/org/launchcode/recipeapp/controllers/RecipeController.java b/src/main/java/org/launchcode/recipeapp/controllers/RecipeController.java index c685e7a..0588e80 100644 --- a/src/main/java/org/launchcode/recipeapp/controllers/RecipeController.java +++ b/src/main/java/org/launchcode/recipeapp/controllers/RecipeController.java @@ -19,6 +19,8 @@ import org.springframework.web.servlet.mvc.support.RedirectAttributes; import javax.validation.Valid; +import java.util.ArrayList; +import java.util.List; import java.util.Optional; @Controller @@ -53,7 +55,7 @@ public String createRecipe(Model model) { model.addAttribute("categories", categories); model.addAttribute("tags", tags); - return "recipes/create"; + return "/recipes/create"; } @PostMapping("create") @@ -78,19 +80,31 @@ public String displayRecipe(@RequestParam Integer recipeId, Model model) { Optional result = recipeRepository.findById(recipeId); - if (result.isEmpty()) { + if (result.isEmpty()) { // invalid id model.addAttribute("title", "Invalid Recipe ID: " + recipeId); - } else { + } else { // valid id Recipe recipe = result.get(); model.addAttribute("title", recipe.getName()); model.addAttribute("recipe", recipe); - if (recipe.getReviews().isEmpty()) { - model.addAttribute("averageRating", "no ratings yet"); - model.addAttribute("numRatings", "no ratings yet"); - } else { + + Integer numComments = recipe.getNumComments(); + List reviews = recipe.getReviews(); + + if (reviews.isEmpty()) { // no reviews + model.addAttribute("numRatings", "0"); + model.addAttribute("averageRating", "No ratings"); + model.addAttribute("comments", "No comments yet"); + } else { // has reviews model.addAttribute("averageRating", recipe.getAverageRating()); model.addAttribute("numRatings", recipe.getReviews().size()); + + if(numComments != 0){ // has comments + model.addAttribute("comments", "Comments"); + } else if (numComments == 0 || numComments == null){ // no comments + model.addAttribute("comments", "No comments yet"); + } } + } return "recipes/display"; @@ -98,34 +112,42 @@ public String displayRecipe(@RequestParam Integer recipeId, Model model) { @PostMapping("display") public String processReviewForm(@RequestParam Integer recipeId, - @Valid @RequestParam String comment, + @RequestParam String comment, @RequestParam Integer rating, - @Valid @RequestParam String name, - Errors errors, Model model) { - // not working - if (errors.hasErrors()) { - return "recipes/display"; - } + @RequestParam String name, + Model model) { - Recipe recipe = recipeRepository.findById(recipeId).get(); +// if (errors.hasErrors()) { +// model.addAttribute("title", "Complete Review"); +// return "display"; +// } - // Ratings and Reviews + Recipe recipe = recipeRepository.findById(recipeId).get(); Review review = new Review(recipe, rating, comment, name); review.setTimestamp(); reviewRepository.save(review); recipe.setAverageRating(); + recipe.setNumComments(review); recipeRepository.save(recipe); model.addAttribute("title", recipe.getName()); model.addAttribute("recipe", recipe); model.addAttribute("review", review); + model.addAttribute("averageRating", recipe.getAverageRating()); model.addAttribute("numRatings", recipe.getReviews().size()); + Integer numComments = recipe.getNumComments(); + if(numComments != 0){ // has comments + model.addAttribute("comments", "Comments"); + } else if (numComments == 0 || numComments == null){ // no comments + model.addAttribute("comments", "No comments yet"); + } return "recipes/display"; } - @GetMapping("edit/{recipeId}") + + @GetMapping("edit/{recipeId}") public String displayEditForm(Model model, @PathVariable int recipeId) { Category[] categories = Category.values(); diff --git a/src/main/java/org/launchcode/recipeapp/models/Recipe.java b/src/main/java/org/launchcode/recipeapp/models/Recipe.java index d7189e6..14d4d42 100644 --- a/src/main/java/org/launchcode/recipeapp/models/Recipe.java +++ b/src/main/java/org/launchcode/recipeapp/models/Recipe.java @@ -25,6 +25,7 @@ public class Recipe extends AbstractEntity { private String img; private Double averageRating; + private Integer numComments = 0; @OneToMany(mappedBy = "recipe") private final List reviews = new ArrayList<>(); @@ -36,6 +37,7 @@ public class Recipe extends AbstractEntity { public Recipe() { } + // Getters and Setters public String getName() { return name; @@ -93,6 +95,11 @@ public void setTag(Tag tag) { this.tag = tag; } + public List getReviews() { + return reviews; + } + + public Double getAverageRating() { return averageRating; } @@ -110,10 +117,23 @@ public void setAverageRating() { averageRating = average; } - public List getReviews() { - return reviews; + public Integer getNumComments() { + return numComments; } + + public Integer setNumComments(Review review){ + if(numComments == null){ + numComments = 0; + } + if (!review.getComment().isEmpty()){ + numComments ++; + } + return numComments; + } + + + @Override public String toString() { return "Recipe{" + diff --git a/src/main/java/org/launchcode/recipeapp/models/Review.java b/src/main/java/org/launchcode/recipeapp/models/Review.java index 7b52818..b5d579d 100644 --- a/src/main/java/org/launchcode/recipeapp/models/Review.java +++ b/src/main/java/org/launchcode/recipeapp/models/Review.java @@ -3,7 +3,6 @@ import javax.persistence.Entity; import javax.persistence.ManyToOne; import javax.validation.constraints.NotBlank; -import javax.validation.constraints.NotNull; import javax.validation.constraints.Size; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; @@ -14,11 +13,11 @@ public class Review extends AbstractEntity{ @ManyToOne private Recipe recipe; - @NotBlank(message = "name is required") - @Size(min=2) + // @NotBlank(message = "name is required") + //@Size(min=2) private String name; - @Size(min=5, max=250) + // @Size(max=250) private String comment; private Integer rating; diff --git a/src/main/resources/templates/recipes/display.html b/src/main/resources/templates/recipes/display.html index 796cdfd..7cc5110 100644 --- a/src/main/resources/templates/recipes/display.html +++ b/src/main/resources/templates/recipes/display.html @@ -37,13 +37,13 @@
-
+

-

Leave a Review

+

Leave a Review

My Rating:
@@ -66,24 +66,23 @@
+

+ - +
- + +
NameRating Comment Date
-
- - -
From 728000c97c80d6e841ff2786adaa2503142a21d7 Mon Sep 17 00:00:00 2001 From: Kelly Dobbs Date: Sat, 2 Jan 2021 21:06:18 -0600 Subject: [PATCH 28/39] added form validation --- .../controllers/RecipeController.java | 33 ++++--- .../launchcode/recipeapp/models/Review.java | 14 ++- src/main/resources/static/css/style.css | 4 +- .../resources/templates/recipes/display.html | 91 +++++++++++-------- 4 files changed, 85 insertions(+), 57 deletions(-) diff --git a/src/main/java/org/launchcode/recipeapp/controllers/RecipeController.java b/src/main/java/org/launchcode/recipeapp/controllers/RecipeController.java index 0588e80..692fa6b 100644 --- a/src/main/java/org/launchcode/recipeapp/controllers/RecipeController.java +++ b/src/main/java/org/launchcode/recipeapp/controllers/RecipeController.java @@ -77,7 +77,7 @@ public String createRecipe(@ModelAttribute @Valid Recipe newRecipe, @GetMapping("display") public String displayRecipe(@RequestParam Integer recipeId, Model model) { - + model.addAttribute("review", new Review()); Optional result = recipeRepository.findById(recipeId); if (result.isEmpty()) { // invalid id @@ -111,19 +111,29 @@ public String displayRecipe(@RequestParam Integer recipeId, Model model) { } @PostMapping("display") - public String processReviewForm(@RequestParam Integer recipeId, - @RequestParam String comment, - @RequestParam Integer rating, - @RequestParam String name, + public String processReviewForm(@ModelAttribute @Valid Review newReview, Errors errors, + @RequestParam Integer recipeId, Model model) { + System.out.println(errors.hasErrors()); + Recipe recipe = recipeRepository.findById(recipeId).get(); -// if (errors.hasErrors()) { -// model.addAttribute("title", "Complete Review"); -// return "display"; -// } + if (errors.hasErrors()) { + model.addAttribute("title", recipe.getName()); + model.addAttribute("recipe", recipe); + model.addAttribute("averageRating", recipe.getAverageRating()); + model.addAttribute("numRatings", recipe.getReviews().size()); + Integer numComments = recipe.getNumComments(); + + if(numComments != 0){ // has comments + model.addAttribute("comments", "Comments"); + } else if (numComments == 0 || numComments == null){ // no comments + model.addAttribute("comments", "No comments yet"); + } + return "recipes/display"; + } + + Review review = new Review(recipe, newReview.getRating(),newReview.getComment(), newReview.getName()); - Recipe recipe = recipeRepository.findById(recipeId).get(); - Review review = new Review(recipe, rating, comment, name); review.setTimestamp(); reviewRepository.save(review); recipe.setAverageRating(); @@ -134,6 +144,7 @@ public String processReviewForm(@RequestParam Integer recipeId, model.addAttribute("recipe", recipe); model.addAttribute("review", review); model.addAttribute("averageRating", recipe.getAverageRating()); + model.addAttribute("numRatings", recipe.getReviews().size()); Integer numComments = recipe.getNumComments(); diff --git a/src/main/java/org/launchcode/recipeapp/models/Review.java b/src/main/java/org/launchcode/recipeapp/models/Review.java index b5d579d..8d92842 100644 --- a/src/main/java/org/launchcode/recipeapp/models/Review.java +++ b/src/main/java/org/launchcode/recipeapp/models/Review.java @@ -3,6 +3,7 @@ import javax.persistence.Entity; import javax.persistence.ManyToOne; import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; import javax.validation.constraints.Size; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; @@ -13,27 +14,30 @@ public class Review extends AbstractEntity{ @ManyToOne private Recipe recipe; - // @NotBlank(message = "name is required") - //@Size(min=2) + @NotBlank(message = "Name is required") private String name; - // @Size(max=250) + @Size(max=250, message = "Comments must be under 250 characters") private String comment; + @NotNull(message = "Rating is required") private Integer rating; + private String timestamp; - public Review() { - } public Review(Recipe recipe, Integer rating, String comment, String name) { + this(); this.recipe = recipe; this.rating = rating; this.comment = comment; this.name = name; } + public Review() { + } + // getters and setters public Recipe getRecipe() { return recipe; diff --git a/src/main/resources/static/css/style.css b/src/main/resources/static/css/style.css index 844f207..f3ec781 100644 --- a/src/main/resources/static/css/style.css +++ b/src/main/resources/static/css/style.css @@ -238,7 +238,9 @@ th { - +.error { + color: red; +} diff --git a/src/main/resources/templates/recipes/display.html b/src/main/resources/templates/recipes/display.html index 7cc5110..6562a63 100644 --- a/src/main/resources/templates/recipes/display.html +++ b/src/main/resources/templates/recipes/display.html @@ -44,46 +44,57 @@

Leave a Review

- - - My Rating:
- - - - - - - - - -
-
-
-
-
- - -
+

+
+ -
-

+
- - - - - - - -
-
- - - - + + + + + + + + + + +

+
+ +
+ +

+ +
+
+
+ +

+ + + + +
+

+ +
NameCommentDate
+ + + + -
NameCommentDate
-
-
- - + +
+ + + + +
+ + +
+
+ + From 4e288ca1f6bf4a2f1a6a5f96d16e38f6bd8c00b7 Mon Sep 17 00:00:00 2001 From: Kelly Dobbs Date: Sat, 2 Jan 2021 22:40:03 -0600 Subject: [PATCH 29/39] added responsive front-end rating --- src/main/resources/static/css/rating.css | 65 +++++++------------ src/main/resources/templates/fragments.html | 5 ++ .../resources/templates/recipes/display.html | 37 ++++++----- 3 files changed, 48 insertions(+), 59 deletions(-) diff --git a/src/main/resources/static/css/rating.css b/src/main/resources/static/css/rating.css index cc7d6bd..7cbf28b 100644 --- a/src/main/resources/static/css/rating.css +++ b/src/main/resources/static/css/rating.css @@ -1,50 +1,29 @@ -.rating-area { - overflow: hidden; - width: 900px; - margin: 0 auto; - background-color: #a89a76; -} -.rating-area:not(:checked) > input { - display: none; -} -.rating-area:not(:checked) > label { - float: none ; - margin-left: 18px; - width: 42px; - padding: 0; - cursor: pointer; - font-size: 32px; - line-height: 32px; - color: lightgrey; - text-shadow: 1px 1px #bbb; -} -.rating-area:not(:checked) > label:before { - content: '★'; +fieldset, label { margin: 0; padding: 0; } +.rating { + border: none; + float: left; } -.rating-area > input:checked ~ label { - color: gold; - text-shadow: 1px 1px #c60; +.rating > input { display: none; } +.rating > label:before { + margin: 5px; + font-size: 1.25em; + font-family: FontAwesome; + display: inline-block; + content: "\f005"; } -.rating-area:not(:checked) > label:hover, -.rating-area:not(:checked) > label:hover ~ label { - color: gold; -} -.rating-area > input:checked + label:hover, -.rating-area > input:checked + label:hover ~ label, -.rating-area > input:checked ~ label:hover, -.rating-area > input:checked ~ label:hover ~ label, -.rating-area > label:hover ~ input:checked ~ label { - color: gold; - text-shadow: 1px 1px goldenrod; -} -.rate-area > label:active { - position: relative; - background-color: #a89a76; -} -.btn-primary { - width: 220px; + +.rating > label { + color: #ddd; + float: right; } +/***** Highlight Stars on Hover *****/ +.rating > input:checked ~ label, /* show gold star when clicked */ +.rating:not(:checked) > label:hover, /* hover current star */ +.rating:not(:checked) > label:hover ~ label { color: #FFD700; } /* hover previous stars in list */ + +.rating > input:checked + label:hover, /* hover current star when changing rating */ +.rating > input:checked ~ label:hover, \ No newline at end of file diff --git a/src/main/resources/templates/fragments.html b/src/main/resources/templates/fragments.html index 17e33e0..afb35da 100644 --- a/src/main/resources/templates/fragments.html +++ b/src/main/resources/templates/fragments.html @@ -11,6 +11,11 @@ --> + + + + + diff --git a/src/main/resources/templates/recipes/display.html b/src/main/resources/templates/recipes/display.html index 6562a63..1e06baa 100644 --- a/src/main/resources/templates/recipes/display.html +++ b/src/main/resources/templates/recipes/display.html @@ -1,6 +1,13 @@ - + + + + + + + +
@@ -42,29 +49,27 @@

+ +

Leave a Review

-

-
- - - - - - - - - - - +
+ + + + + + +


- -
+
+


From 5b6385472005aeadae026309a4f8ef6234a0dceb Mon Sep 17 00:00:00 2001 From: Kelly Dobbs Date: Sat, 2 Jan 2021 22:50:53 -0600 Subject: [PATCH 30/39] front-end responsive rating --- .../java/org/launchcode/recipeapp/models/Review.java | 1 + src/main/resources/templates/fragments.html | 10 ++++------ src/main/resources/templates/recipes/display.html | 2 +- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/main/java/org/launchcode/recipeapp/models/Review.java b/src/main/java/org/launchcode/recipeapp/models/Review.java index 8d92842..d67be34 100644 --- a/src/main/java/org/launchcode/recipeapp/models/Review.java +++ b/src/main/java/org/launchcode/recipeapp/models/Review.java @@ -15,6 +15,7 @@ public class Review extends AbstractEntity{ private Recipe recipe; @NotBlank(message = "Name is required") + @Size(min=2, message = "Name is required") private String name; @Size(max=250, message = "Comments must be under 250 characters") diff --git a/src/main/resources/templates/fragments.html b/src/main/resources/templates/fragments.html index afb35da..84b92ba 100644 --- a/src/main/resources/templates/fragments.html +++ b/src/main/resources/templates/fragments.html @@ -8,14 +8,12 @@ Famous Sent Louis Recipes - - + --> - + + + diff --git a/src/main/resources/templates/recipes/display.html b/src/main/resources/templates/recipes/display.html index 1e06baa..9e44c92 100644 --- a/src/main/resources/templates/recipes/display.html +++ b/src/main/resources/templates/recipes/display.html @@ -1,7 +1,7 @@ - + From 68100609101efc5168d793e8804bbb547940c1e1 Mon Sep 17 00:00:00 2001 From: Kelly Dobbs Date: Sat, 2 Jan 2021 23:29:16 -0600 Subject: [PATCH 31/39] added oksana's changes --- .../controllers/RecipeController.java | 10 +++ src/main/resources/application.properties | 2 +- src/main/resources/templates/fragments.html | 81 +++++++++++++++++-- .../resources/templates/recipes/display.html | 40 +++++---- 4 files changed, 105 insertions(+), 28 deletions(-) diff --git a/src/main/java/org/launchcode/recipeapp/controllers/RecipeController.java b/src/main/java/org/launchcode/recipeapp/controllers/RecipeController.java index 692fa6b..2b7ceec 100644 --- a/src/main/java/org/launchcode/recipeapp/controllers/RecipeController.java +++ b/src/main/java/org/launchcode/recipeapp/controllers/RecipeController.java @@ -157,6 +157,16 @@ public String processReviewForm(@ModelAttribute @Valid Review newReview, Errors } + @GetMapping("all") + public String getAllRecipes (Model model){ + + List all = ((List) recipeRepository.findAll()); + + model.addAttribute("recipes", all); + + return "recipes/all"; + + } @GetMapping("edit/{recipeId}") public String displayEditForm(Model model, @PathVariable int recipeId) { diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 27252ec..c56879d 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1,6 +1,6 @@ # Database connection settings -spring.datasource.url=jdbc:mysql://localhost:3306/recipes +spring.datasource.url=jdbc:mysql://localhost:3306/recipe-app spring.datasource.username=recipe-app spring.datasource.password=1Password diff --git a/src/main/resources/templates/fragments.html b/src/main/resources/templates/fragments.html index 84b92ba..baba8fa 100644 --- a/src/main/resources/templates/fragments.html +++ b/src/main/resources/templates/fragments.html @@ -6,16 +6,55 @@ Famous Sent Louis Recipes - + + --> + +
+ +
@@ -37,8 +76,40 @@

Recipes R Us

Hello Friends!

- - + + + +
diff --git a/src/main/resources/templates/recipes/display.html b/src/main/resources/templates/recipes/display.html index 9e44c92..a654478 100644 --- a/src/main/resources/templates/recipes/display.html +++ b/src/main/resources/templates/recipes/display.html @@ -9,6 +9,7 @@ +
@@ -22,6 +23,11 @@
+
+
+
+
+
@@ -43,47 +49,36 @@

-
-
-
-

- - - +

Leave a Review

-
-
-

-
-
-
-

- -
-
-
+



+
+ +


+
+
-

+

+
+

- +
@@ -99,6 +94,7 @@

Name
+
From 2ab169392193a7ab5e507ecccb4ac27babd58269 Mon Sep 17 00:00:00 2001 From: Kelly Dobbs Date: Sat, 2 Jan 2021 23:45:00 -0600 Subject: [PATCH 32/39] added more of Oksana's edits --- .../resources/templates/recipes/display.html | 41 +++++++++---------- 1 file changed, 19 insertions(+), 22 deletions(-) diff --git a/src/main/resources/templates/recipes/display.html b/src/main/resources/templates/recipes/display.html index a654478..0ab769a 100644 --- a/src/main/resources/templates/recipes/display.html +++ b/src/main/resources/templates/recipes/display.html @@ -12,39 +12,36 @@
- -


- - +



- -
-
-
+
+ +
-
-
+

+ - - - + + + - - - + + + - - - - - - + + + + + + +
Ingredients:
Ingredients:
Directions:
Directions:
Category:
Tags:
Category:
Tags:

From 17fd263e7ab7d1959e435d5736b39097851dfeb0 Mon Sep 17 00:00:00 2001 From: Kelly Dobbs Date: Sun, 3 Jan 2021 00:00:30 -0600 Subject: [PATCH 33/39] added display.html to whitelist --- .../recipeapp/AuthenticationFilter.java | 2 +- .../launchcode/recipeapp/models/UserRecipe.java | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/launchcode/recipeapp/AuthenticationFilter.java b/src/main/java/org/launchcode/recipeapp/AuthenticationFilter.java index efc5cee..5dbeab9 100644 --- a/src/main/java/org/launchcode/recipeapp/AuthenticationFilter.java +++ b/src/main/java/org/launchcode/recipeapp/AuthenticationFilter.java @@ -23,7 +23,7 @@ public class AuthenticationFilter extends HandlerInterceptorAdapter { @Autowired AuthenticationController authenticationController; - private static final List whitelist = Arrays.asList("/home", "/login", "/register", "/logout", "/css", "/recipes/all"); + private static final List whitelist = Arrays.asList("/home", "/login", "/register", "/logout", "/css", "/recipes/all", "/recipes/display"); private static boolean isWhitelisted(String path) { for (String pathRoot : whitelist) { diff --git a/src/main/java/org/launchcode/recipeapp/models/UserRecipe.java b/src/main/java/org/launchcode/recipeapp/models/UserRecipe.java index fb420ca..9322cc7 100644 --- a/src/main/java/org/launchcode/recipeapp/models/UserRecipe.java +++ b/src/main/java/org/launchcode/recipeapp/models/UserRecipe.java @@ -39,4 +39,19 @@ public class UserRecipe extends AbstractEntity { @NotNull(message = "") private Recipe recipe; + public User getUser() { + return user; + } + + public void setUser(User user) { + this.user = user; + } + + public Recipe getRecipe() { + return recipe; + } + + public void setRecipe(Recipe recipe) { + this.recipe = recipe; + } } From 5e8dad8db118ebe0a0e7024317c18d9e361cf4b7 Mon Sep 17 00:00:00 2001 From: Kelly Dobbs Date: Sun, 3 Jan 2021 00:05:12 -0600 Subject: [PATCH 34/39] refactored --- src/main/resources/templates/recipes/display.html | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/main/resources/templates/recipes/display.html b/src/main/resources/templates/recipes/display.html index 0ab769a..62b8ae1 100644 --- a/src/main/resources/templates/recipes/display.html +++ b/src/main/resources/templates/recipes/display.html @@ -1,11 +1,6 @@ - - - - - From 18eb03ba6c13fd5f9793299cbd426aa0b9757400 Mon Sep 17 00:00:00 2001 From: reyna biyo Date: Sun, 3 Jan 2021 01:38:14 -0600 Subject: [PATCH 35/39] continuation of sort feature --- .../controllers/SearchController.java | 48 ++++++++++++++----- .../launchcode/recipeapp/models/Recipe.java | 11 ++++- .../recipeapp/models/SortParameter.java | 14 +++++- src/main/resources/static/css/style.css | 22 --------- src/main/resources/templates/search.html | 22 +++++---- 5 files changed, 69 insertions(+), 48 deletions(-) diff --git a/src/main/java/org/launchcode/recipeapp/controllers/SearchController.java b/src/main/java/org/launchcode/recipeapp/controllers/SearchController.java index f7e4549..250c005 100644 --- a/src/main/java/org/launchcode/recipeapp/controllers/SearchController.java +++ b/src/main/java/org/launchcode/recipeapp/controllers/SearchController.java @@ -37,7 +37,7 @@ public String searchRecipeByKeyword(Model model, @RequestParam String keyword) { List recipeList = new ArrayList<>(); Iterable recipesIter = recipeRepository.findAll(); recipesIter.forEach(recipeList::add); - List foundRecipes = new ArrayList<>(); +// List foundRecipes = new ArrayList<>(); for (Recipe recipe : recipeList) { if (recipe.getName().toLowerCase().contains(lower_val)) { foundRecipes.add(recipe); @@ -85,22 +85,44 @@ public String searchRecipeByCategory(@RequestParam Category category, Model mode return "search"; } - @PostMapping(value = "/sortSearchResults") + @PostMapping(value = "/sortKeyword") public String sortKeywordSearchResults(@RequestParam SortParameter sortParameter, Model model) { - List recipes = foundRecipes; - List sortedRecipes = new ArrayList<>(); + Iterable recipes = foundRecipes; - if (sortParameter.equals(SortParameter.NAME_ASCENDING)) { - for(Recipe recipe : recipes ) { + if (sortParameter == null) { + List unsortedRecipe = new ArrayList<>(); + for (Recipe recipe : recipes) { + unsortedRecipe.add(recipe); + model.addAttribute("recipes", unsortedRecipe); + model.addAttribute("categories", Category.values()); + model.addAttribute("sort", SortParameter.values()); + } + + } else if ((sortParameter.getName().equals("Ascending Recipe Name"))) { + List sortedRecipes = new ArrayList<>(); + for (Recipe recipe : recipes) { sortedRecipes.add(recipe); - Collections.sort(sortedRecipes, new Recipe.SortByName()); + Collections.sort(sortedRecipes, new Recipe.SortByNameAsc()); + } + model.addAttribute("recipes", sortedRecipes); + model.addAttribute("categories", Category.values()); + model.addAttribute("sort", SortParameter.values()); + + } else if ((sortParameter.getName().equals("Descending Recipe Name"))) { + List sortedRecipes = new ArrayList<>(); + for (Recipe recipe : recipes) { + sortedRecipes.add(recipe); + Collections.sort(sortedRecipes, new Recipe.SortByNameDesc()); - } - model.addAttribute("recipes", sortedRecipes); - model.addAttribute("categories", Category.values()); - model.addAttribute("sort", SortParameter.values()); - return "search"; } + model.addAttribute("recipes", sortedRecipes); + model.addAttribute("categories", Category.values()); + model.addAttribute("sort", SortParameter.values()); +// foundRecipes.clear(); + + } + return "search"; + } - } \ No newline at end of file +} \ No newline at end of file diff --git a/src/main/java/org/launchcode/recipeapp/models/Recipe.java b/src/main/java/org/launchcode/recipeapp/models/Recipe.java index d7457ad..607224f 100644 --- a/src/main/java/org/launchcode/recipeapp/models/Recipe.java +++ b/src/main/java/org/launchcode/recipeapp/models/Recipe.java @@ -38,7 +38,7 @@ public Recipe() { } //// Used for sorting in ascending order of name - public static class SortByName implements Comparator { + public static class SortByNameAsc implements Comparator { public int compare(Recipe a, Recipe b) { return a.name.compareTo(b.name); @@ -46,6 +46,15 @@ public int compare(Recipe a, Recipe b) } + //// Used for sorting in descending order of name + public static class SortByNameDesc implements Comparator { + public int compare(Recipe a, Recipe b) + { + return b.name.compareTo(a.name); + } + + } + public String getName() { return name; diff --git a/src/main/java/org/launchcode/recipeapp/models/SortParameter.java b/src/main/java/org/launchcode/recipeapp/models/SortParameter.java index dbc9839..e2ca988 100644 --- a/src/main/java/org/launchcode/recipeapp/models/SortParameter.java +++ b/src/main/java/org/launchcode/recipeapp/models/SortParameter.java @@ -1,7 +1,17 @@ package org.launchcode.recipeapp.models; public enum SortParameter { - NAME_ASCENDING , - NAME_DESCENDING ; + NAME_ASCENDING ("Ascending Recipe Name"), + NAME_DESCENDING ("Descending Recipe Name"); + + private String name; + + SortParameter(String name) { + this.name = name; + } + + public String getName() { + return name; + } } diff --git a/src/main/resources/static/css/style.css b/src/main/resources/static/css/style.css index 4a91ea5..b9ef28a 100644 --- a/src/main/resources/static/css/style.css +++ b/src/main/resources/static/css/style.css @@ -236,30 +236,8 @@ th { width: 300px !important; } -.dropbtn { - color: Black; - font-size: 16px; - border-radius: 5px; -} -.dropdown { - position: fixed; - top: 200px; - left: 1030px; -} -.dropdown-content { - display: none; - position: absolute; - min-width: 100px; - z-index: 1; -} - -.dropdown-content a { - color: black; - padding: 12px 16px; - display: block; -} diff --git a/src/main/resources/templates/search.html b/src/main/resources/templates/search.html index c5b5923..b9294c6 100644 --- a/src/main/resources/templates/search.html +++ b/src/main/resources/templates/search.html @@ -9,16 +9,18 @@

- + +
+ + +
+
From 2243b129faa156c62d8e030bd6f4d1363b2edbff Mon Sep 17 00:00:00 2001 From: reyna biyo Date: Sun, 3 Jan 2021 02:20:43 -0600 Subject: [PATCH 36/39] finished SORT feature --- .../controllers/SearchController.java | 23 ++++++++----------- .../recipeapp/models/SortParameter.java | 9 ++++++-- src/main/resources/templates/fragments.html | 4 ++-- src/main/resources/templates/search.html | 4 ++-- 4 files changed, 21 insertions(+), 19 deletions(-) diff --git a/src/main/java/org/launchcode/recipeapp/controllers/SearchController.java b/src/main/java/org/launchcode/recipeapp/controllers/SearchController.java index 250c005..d2d834d 100644 --- a/src/main/java/org/launchcode/recipeapp/controllers/SearchController.java +++ b/src/main/java/org/launchcode/recipeapp/controllers/SearchController.java @@ -30,14 +30,15 @@ public String renderSearch(Model model) { } - @PostMapping(value = "/results") + @PostMapping(value = "/keywordResults") public String searchRecipeByKeyword(Model model, @RequestParam String keyword) { + foundRecipes.clear(); String lower_val = keyword.toLowerCase(); List recipeList = new ArrayList<>(); Iterable recipesIter = recipeRepository.findAll(); recipesIter.forEach(recipeList::add); -// List foundRecipes = new ArrayList<>(); + for (Recipe recipe : recipeList) { if (recipe.getName().toLowerCase().contains(lower_val)) { foundRecipes.add(recipe); @@ -47,8 +48,6 @@ public String searchRecipeByKeyword(Model model, @RequestParam String keyword) { foundRecipes.add(recipe); } else if (recipe.getCategory().toString().toLowerCase().contains(lower_val)) { foundRecipes.add(recipe); - - } } model.addAttribute("recipes", foundRecipes); @@ -58,26 +57,25 @@ public String searchRecipeByKeyword(Model model, @RequestParam String keyword) { } - @PostMapping(value = "/selectedCategory") + @PostMapping(value = "/categoryResults") public String searchRecipeByCategory(@RequestParam Category category, Model model) { + foundRecipes.clear(); Iterable recipes = recipeRepository.findAll(); if (category == null) { - List allRecipe = new ArrayList<>(); for (Recipe recipe : recipes) { - allRecipe.add(recipe); - model.addAttribute("recipes", allRecipe); + foundRecipes.add(recipe); + model.addAttribute("recipes", foundRecipes); model.addAttribute("categories", Category.values()); model.addAttribute("sort", SortParameter.values()); } } else { - List recipeByCategory = new ArrayList<>(); for (Recipe recipe : recipes) { if (recipe.getCategory().name().toLowerCase().equals(category.name().toLowerCase())) { - recipeByCategory.add(recipe); + foundRecipes.add(recipe); } } - model.addAttribute("recipes", recipeByCategory); + model.addAttribute("recipes", foundRecipes); model.addAttribute("categories", Category.values()); model.addAttribute("sort", SortParameter.values()); @@ -85,7 +83,7 @@ public String searchRecipeByCategory(@RequestParam Category category, Model mode return "search"; } - @PostMapping(value = "/sortKeyword") + @PostMapping(value = "/sort") public String sortKeywordSearchResults(@RequestParam SortParameter sortParameter, Model model) { Iterable recipes = foundRecipes; @@ -119,7 +117,6 @@ public String sortKeywordSearchResults(@RequestParam SortParameter sortParameter model.addAttribute("recipes", sortedRecipes); model.addAttribute("categories", Category.values()); model.addAttribute("sort", SortParameter.values()); -// foundRecipes.clear(); } return "search"; diff --git a/src/main/java/org/launchcode/recipeapp/models/SortParameter.java b/src/main/java/org/launchcode/recipeapp/models/SortParameter.java index e2ca988..1a83529 100644 --- a/src/main/java/org/launchcode/recipeapp/models/SortParameter.java +++ b/src/main/java/org/launchcode/recipeapp/models/SortParameter.java @@ -1,8 +1,13 @@ package org.launchcode.recipeapp.models; public enum SortParameter { - NAME_ASCENDING ("Ascending Recipe Name"), - NAME_DESCENDING ("Descending Recipe Name"); + NAME_ASCENDING ("Ascending Recipe Name"), + NAME_DESCENDING ("Descending Recipe Name"), + TIME_ASCENDING ("Ascending Total Time"), + TIME_DESCENDING ("Descending Total Time"), + RATING_ASCENDING ("Rating: Highest - Lowest"), + RATING_DESCENDING ("Rating: Lowest - Highest"); + private String name; diff --git a/src/main/resources/templates/fragments.html b/src/main/resources/templates/fragments.html index 5af8521..9be9f40 100644 --- a/src/main/resources/templates/fragments.html +++ b/src/main/resources/templates/fragments.html @@ -30,12 +30,12 @@

Recipes R Us

@@ -54,7 +53,7 @@

Recipes R Us

Hello Friends!

- +
diff --git a/src/main/resources/templates/search.html b/src/main/resources/templates/search.html index 06b9e90..ddb839a 100644 --- a/src/main/resources/templates/search.html +++ b/src/main/resources/templates/search.html @@ -10,15 +10,17 @@

-
- - +
From cf1df3b831b3f849c04657d48604fad90f033d68 Mon Sep 17 00:00:00 2001 From: reyna biyo Date: Mon, 4 Jan 2021 20:08:23 -0600 Subject: [PATCH 38/39] started filter search result feature --- .../controllers/SearchController.java | 24 +++++++++++++------ .../launchcode/recipeapp/models/Category.java | 3 --- .../org/launchcode/recipeapp/models/Tag.java | 16 ++++++++++++- src/main/resources/templates/search.html | 8 +++++++ 4 files changed, 40 insertions(+), 11 deletions(-) diff --git a/src/main/java/org/launchcode/recipeapp/controllers/SearchController.java b/src/main/java/org/launchcode/recipeapp/controllers/SearchController.java index 1917cf0..0e8c349 100644 --- a/src/main/java/org/launchcode/recipeapp/controllers/SearchController.java +++ b/src/main/java/org/launchcode/recipeapp/controllers/SearchController.java @@ -4,6 +4,7 @@ import org.launchcode.recipeapp.models.Category; import org.launchcode.recipeapp.models.Recipe; import org.launchcode.recipeapp.models.SortParameter; +import org.launchcode.recipeapp.models.Tag; import org.launchcode.recipeapp.models.data.RecipeRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; @@ -21,10 +22,17 @@ public class SearchController { List foundRecipes = new ArrayList<>(); +// +// @ModelAttribute +// public void initValues(Model model) { +// model.addAttribute("filterTypes", Arrays.asList("Chicken", "Fish")); +// } + @GetMapping("") public String renderSearch(Model model) { model.addAttribute("categories", Category.values()); model.addAttribute("sort", SortParameter.values()); + model.addAttribute("filterTypes", Tag.values()); return "search"; } @@ -89,7 +97,7 @@ public String searchRecipeByCategory(@RequestParam Category category, Model mode //sort search results @PostMapping(value = "/sort") - public String sortKeywordSearchResults(@RequestParam SortParameter sortParameter, Model model) { + public String sortSearchResults(@RequestParam SortParameter sortParameter, Model model) { Iterable recipes = foundRecipes; // sort is black @@ -155,12 +163,14 @@ public String sortKeywordSearchResults(@RequestParam SortParameter sortParameter } -// // filter search results -// @PostMapping(value = "/filter") -// public String filterSearchResults(@RequestParam filterParam filterParam, Model model) { -// Iterable recipes = foundRecipes; -// return "search"; -// } + // filter search results + @RequestMapping(value = "/filter") + public String filterSearchResults(@RequestParam Tag tag, Model model) { + model.addAttribute("filterTypes", Tag.values()); + + Iterable recipes = foundRecipes; + return "search"; + } diff --git a/src/main/java/org/launchcode/recipeapp/models/Category.java b/src/main/java/org/launchcode/recipeapp/models/Category.java index 2d3f84d..92a507f 100644 --- a/src/main/java/org/launchcode/recipeapp/models/Category.java +++ b/src/main/java/org/launchcode/recipeapp/models/Category.java @@ -1,8 +1,5 @@ package org.launchcode.recipeapp.models; -/** - * @author Oksana - */ public enum Category { BEVERAGES ("Beverage"), diff --git a/src/main/java/org/launchcode/recipeapp/models/Tag.java b/src/main/java/org/launchcode/recipeapp/models/Tag.java index d234337..269c475 100644 --- a/src/main/java/org/launchcode/recipeapp/models/Tag.java +++ b/src/main/java/org/launchcode/recipeapp/models/Tag.java @@ -4,6 +4,20 @@ * @author Oksana */ public enum Tag { - GLUTEN_FREE, VEGETARIAN, NUT_FREE, DAIRY_FREE, MEAT, SEAFOOD; + GLUTEN_FREE ("Gluten Free"), + VEGETARIAN("Vegetarian"), + NUT_FREE ("Nut Free"), + DAIRY_FREE ("Dairy Free"), + MEAT ("Meat"), + SEAFOOD ("Seafood"); + private String name; + + Tag(String name) { + this.name = name; + } + + public String getName() { + return name; + } } diff --git a/src/main/resources/templates/search.html b/src/main/resources/templates/search.html index ddb839a..0fb77ed 100644 --- a/src/main/resources/templates/search.html +++ b/src/main/resources/templates/search.html @@ -23,6 +23,14 @@

+
+
    +
  • + + +
  • +
+
From c6a19a642ea95ca1fbd916b24fd9fe3a6aa8e1ee Mon Sep 17 00:00:00 2001 From: reyna biyo Date: Tue, 5 Jan 2021 13:01:00 -0600 Subject: [PATCH 39/39] added sort by category in /home and /recipe/display. Filter feature in progress --- .../recipeapp/controllers/HomeController.java | 2 + .../controllers/RecipeController.java | 7 +- .../controllers/SearchController.java | 52 +++++++------- .../recipeapp/controllers/UserController.java | 3 +- .../recipeapp/models/FilterTypes.java | 21 ++++++ src/main/resources/static/css/style.css | 5 +- src/main/resources/templates/fragments.html | 71 +++++++++++++------ src/main/resources/templates/search.html | 14 ++-- 8 files changed, 114 insertions(+), 61 deletions(-) create mode 100644 src/main/java/org/launchcode/recipeapp/models/FilterTypes.java diff --git a/src/main/java/org/launchcode/recipeapp/controllers/HomeController.java b/src/main/java/org/launchcode/recipeapp/controllers/HomeController.java index 32f9608..b2c7625 100644 --- a/src/main/java/org/launchcode/recipeapp/controllers/HomeController.java +++ b/src/main/java/org/launchcode/recipeapp/controllers/HomeController.java @@ -1,6 +1,7 @@ package org.launchcode.recipeapp.controllers; +import org.launchcode.recipeapp.models.Category; import org.launchcode.recipeapp.models.Recipe; import org.launchcode.recipeapp.models.data.RecipeRepository; import org.springframework.beans.factory.annotation.Autowired; @@ -24,6 +25,7 @@ public HomeController(RecipeRepository recipeRepository) { @GetMapping("/home") public String home(Model model) { Iterable all = recipeRepository.findAll(); + model.addAttribute("categories", Category.values()); model.addAttribute("recipes", all); model.addAttribute("title", "Saint Louis Best Recipes"); diff --git a/src/main/java/org/launchcode/recipeapp/controllers/RecipeController.java b/src/main/java/org/launchcode/recipeapp/controllers/RecipeController.java index 2b7ceec..a61280e 100644 --- a/src/main/java/org/launchcode/recipeapp/controllers/RecipeController.java +++ b/src/main/java/org/launchcode/recipeapp/controllers/RecipeController.java @@ -1,10 +1,7 @@ package org.launchcode.recipeapp.controllers; -import org.launchcode.recipeapp.models.Review; +import org.launchcode.recipeapp.models.*; import org.launchcode.recipeapp.models.data.RecipeRepository; -import org.launchcode.recipeapp.models.Category; -import org.launchcode.recipeapp.models.Recipe; -import org.launchcode.recipeapp.models.Tag; import org.launchcode.recipeapp.models.data.ReviewRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; @@ -78,6 +75,7 @@ public String createRecipe(@ModelAttribute @Valid Recipe newRecipe, @GetMapping("display") public String displayRecipe(@RequestParam Integer recipeId, Model model) { model.addAttribute("review", new Review()); + model.addAttribute("categories", Category.values()); Optional result = recipeRepository.findById(recipeId); if (result.isEmpty()) { // invalid id @@ -163,6 +161,7 @@ public String getAllRecipes (Model model){ List all = ((List) recipeRepository.findAll()); model.addAttribute("recipes", all); + model.addAttribute("categories", Category.values()); return "recipes/all"; diff --git a/src/main/java/org/launchcode/recipeapp/controllers/SearchController.java b/src/main/java/org/launchcode/recipeapp/controllers/SearchController.java index 0e8c349..48b9ee6 100644 --- a/src/main/java/org/launchcode/recipeapp/controllers/SearchController.java +++ b/src/main/java/org/launchcode/recipeapp/controllers/SearchController.java @@ -22,11 +22,11 @@ public class SearchController { List foundRecipes = new ArrayList<>(); -// -// @ModelAttribute -// public void initValues(Model model) { -// model.addAttribute("filterTypes", Arrays.asList("Chicken", "Fish")); -// } + + @ModelAttribute + public void initValues(Model model) { + model.addAttribute("filterTypes", Tag.values()); + } @GetMapping("") public String renderSearch(Model model) { @@ -56,7 +56,7 @@ public String searchRecipeByKeyword(Model model, @RequestParam String keyword) { foundRecipes.add(recipe); } else if (recipe.getCategory().toString().toLowerCase().contains(lower_val)) { foundRecipes.add(recipe); - }else if (recipe.getTag().toString().toLowerCase().contains(lower_val)) { + } else if (recipe.getTag().toString().toLowerCase().contains(lower_val)) { foundRecipes.add(recipe); } } @@ -100,18 +100,7 @@ public String searchRecipeByCategory(@RequestParam Category category, Model mode public String sortSearchResults(@RequestParam SortParameter sortParameter, Model model) { Iterable recipes = foundRecipes; - // sort is black - if (sortParameter == null) { - List unsortedRecipe = new ArrayList<>(); - for (Recipe recipe : recipes) { - unsortedRecipe.add(recipe); - model.addAttribute("recipes", unsortedRecipe); - model.addAttribute("categories", Category.values()); - model.addAttribute("sort", SortParameter.values()); - } - - //sort is ascending name - } else if ((sortParameter.getName().equals("Recipe Name: A-Z"))) { + if ((sortParameter.getName().equals("Recipe Name: A-Z"))) { List sortedRecipes = new ArrayList<>(); for (Recipe recipe : recipes) { sortedRecipes.add(recipe); @@ -122,7 +111,7 @@ public String sortSearchResults(@RequestParam SortParameter sortParameter, Model model.addAttribute("categories", Category.values()); model.addAttribute("sort", SortParameter.values()); - //sort is descending name + //sort is descending name } else if ((sortParameter.getName().equals("Recipe Name: Z-A"))) { List sortedRecipes = new ArrayList<>(); for (Recipe recipe : recipes) { @@ -134,7 +123,7 @@ public String sortSearchResults(@RequestParam SortParameter sortParameter, Model model.addAttribute("categories", Category.values()); model.addAttribute("sort", SortParameter.values()); - //sort is ascending averageRating + //sort is ascending averageRating } else if ((sortParameter.getName().equals("Average Rating: High-Low"))) { List sortedRecipes = new ArrayList<>(); for (Recipe recipe : recipes) { @@ -146,7 +135,7 @@ public String sortSearchResults(@RequestParam SortParameter sortParameter, Model model.addAttribute("categories", Category.values()); model.addAttribute("sort", SortParameter.values()); - //sort is descending averageRating + //sort is descending averageRating } else if ((sortParameter.getName().equals("Average Rating: Low-High"))) { List sortedRecipes = new ArrayList<>(); for (Recipe recipe : recipes) { @@ -164,15 +153,24 @@ public String sortSearchResults(@RequestParam SortParameter sortParameter, Model // filter search results - @RequestMapping(value = "/filter") + @PostMapping(value = "/filter") public String filterSearchResults(@RequestParam Tag tag, Model model) { - model.addAttribute("filterTypes", Tag.values()); - Iterable recipes = foundRecipes; - return "search"; - } + List filteredRecipe = new ArrayList<>(); + for (Recipe recipe : recipes) { + for (Tag tagValue : tag.values()) { + if (recipe.getTag().getName().toLowerCase().equals(tagValue.getName().toLowerCase())) { + filteredRecipe.add(recipe); + model.addAttribute("recipes", filteredRecipe); + model.addAttribute("categories", Category.values()); + model.addAttribute("sort", SortParameter.values()); + } + } + } + return "search"; + } -} \ No newline at end of file + } \ No newline at end of file diff --git a/src/main/java/org/launchcode/recipeapp/controllers/UserController.java b/src/main/java/org/launchcode/recipeapp/controllers/UserController.java index f68bbb7..c31c7aa 100644 --- a/src/main/java/org/launchcode/recipeapp/controllers/UserController.java +++ b/src/main/java/org/launchcode/recipeapp/controllers/UserController.java @@ -1,6 +1,7 @@ package org.launchcode.recipeapp.controllers; import org.launchcode.recipeapp.models.Recipe; +import org.launchcode.recipeapp.models.SortParameter; import org.launchcode.recipeapp.models.User; import org.launchcode.recipeapp.models.UserRecipe; import org.launchcode.recipeapp.models.data.RecipeRepository; @@ -64,7 +65,7 @@ public String getUserProfile(HttpServletRequest request, Model model, RedirectAt Recipe recipe = userRecipe.getRecipe(); recipes.add(recipe); } - + model.addAttribute("sort", SortParameter.values()); model.addAttribute("title", sessionUser.getUsername()); model.addAttribute("user", sessionUser); model.addAttribute("recipes", recipes); diff --git a/src/main/java/org/launchcode/recipeapp/models/FilterTypes.java b/src/main/java/org/launchcode/recipeapp/models/FilterTypes.java new file mode 100644 index 0000000..b7cda8f --- /dev/null +++ b/src/main/java/org/launchcode/recipeapp/models/FilterTypes.java @@ -0,0 +1,21 @@ +package org.launchcode.recipeapp.models; + +public enum FilterTypes { + + BEVERAGES ("Beverage"), + APPETIZER ("Appetizer"), + ENTREE ("Entree"), + SOUP ("Soup"), + SIDES ("Side"), + DESSERT ("Dessert"); + + private String name; + + FilterTypes (String name) { + this.name = name; + } + + public String getName() { + return name; + } + } diff --git a/src/main/resources/static/css/style.css b/src/main/resources/static/css/style.css index dd978a3..3064da8 100644 --- a/src/main/resources/static/css/style.css +++ b/src/main/resources/static/css/style.css @@ -274,9 +274,12 @@ th { background color: blue; position: fixed; right: 10px; - top: 30px; + top: 120px; } +ul { + list-style: outside none none; +} diff --git a/src/main/resources/templates/fragments.html b/src/main/resources/templates/fragments.html index 9ad3b5b..7a0dceb 100644 --- a/src/main/resources/templates/fragments.html +++ b/src/main/resources/templates/fragments.html @@ -16,9 +16,55 @@
-
-

Recipes R Us

-
+ + + - +
diff --git a/src/main/resources/templates/search.html b/src/main/resources/templates/search.html index 0fb77ed..449dbb8 100644 --- a/src/main/resources/templates/search.html +++ b/src/main/resources/templates/search.html @@ -23,26 +23,26 @@

-
+
    -
  • - - + +
  • + +
  • -
+ +
-
-