Merge pull request #56 from cse110-fa22-group29/sprint-1
Merge with HTMLhint branch
							
								
								
									
										77
									
								
								CreatePage.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,77 @@ | ||||
| <!DOCTYPE html> | ||||
| <html lang="en"> | ||||
|  | ||||
| <head> | ||||
|   <meta charset="UTF-8" /> | ||||
|   <meta http-equiv="X-UA-Compatible" content="IE=edge" /> | ||||
|   <meta name="viewport" content="width=device-width, initial-scale=1.0" /> | ||||
|   <title>Food Journal</title> | ||||
|  | ||||
|   <!-- Recipe Card Custom Element --> | ||||
|   <script src="/source/assets/scripts/ReviewCard.js" type="module"></script> | ||||
|  | ||||
|  | ||||
|   <!-- Main Stylesheets & Scripts --> | ||||
|   <!-- Temporarily commented out reset.css due to furthur discussion needed on the values of the default config--> | ||||
|   <!-- <link rel="stylesheet" href="/static/reset.css" /> --> | ||||
|   <link rel="stylesheet" href="./static/CreatePage.css" /> | ||||
|   <script src="/source/assets/scripts/main.js" type="module"></script> | ||||
|  | ||||
| </head> | ||||
|  | ||||
| <body> | ||||
|   <form id="new-food-entry"> | ||||
|     <fieldset> | ||||
|       <legend>Pic:</legend> | ||||
|       <label for="mealImage"> | ||||
|         Source: | ||||
|         <input type="text" id="mealImg" name="mealImg"> | ||||
|       </label> | ||||
|       <label for="image-alt"> | ||||
|         Alt Text: | ||||
|         <input type="text" id="imgAlt" name="imgAlt"> | ||||
|       </label> | ||||
|     </fieldset> | ||||
|     <fieldset> | ||||
|  | ||||
|       <legend> Meal: </legend> | ||||
|       <label for="Meal: ">Meal: | ||||
|         <input type="text" id="mealName" name="mealName" required> | ||||
|       </label> | ||||
|       <label for="comments">Comments: | ||||
|         <br> | ||||
|         <textarea name="comments" id="comments"></textarea> | ||||
|       </label> | ||||
|     </fieldset> | ||||
|  | ||||
|     <fieldset class="rating"> | ||||
|       <legend> Rating: </legend> | ||||
|       <input type="radio" id="s5" name="rating" value="5"/> <label for="s5"> 5 stars </label> | ||||
|       <input type="radio" id="s4" name="rating" value="4"/> <label for="s4"> 4 stars </label> | ||||
|       <input type="radio" id="s3" name="rating" value="3"/> <label for="s3"> 3 stars </label> | ||||
|       <input type="radio" id="s2" name="rating" value="2"/> <label for="s2"> 2 stars </label> | ||||
|       <input type="radio" id="s1" name="rating" value="1"/> <label for="s1"> 1 star </label> | ||||
|     </fieldset> | ||||
|  | ||||
|     <fieldset> | ||||
|       <legend>Other Info:</legend> | ||||
|       <label for="restaurant"> | ||||
|         Restaurant: | ||||
|         <input type="text" id="restaurant" name="restaurant" required> | ||||
|       </label> | ||||
|       <label for="tag-form"> | ||||
|         Tags: | ||||
|         <input type="text" id="tag-form" name="tag-form"> | ||||
|         <div class='tag-container' id="tag-container-form"> | ||||
|  | ||||
|         </div> | ||||
|         <button type="button" id="tagAdd">Add Tag</button> | ||||
|       </label> | ||||
|  | ||||
|     </fieldset> | ||||
|     <button type="submit" value="Submit">Add Review</button> | ||||
|     <button type="button" class="danger">Clear Review Journal</button> | ||||
|   </form> | ||||
| </body> | ||||
|  | ||||
| </html> | ||||
							
								
								
									
										77
									
								
								ReviewDetails.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,77 @@ | ||||
| <!DOCTYPE html> | ||||
| <html lang="en"> | ||||
| <head> | ||||
|   <meta charset="UTF-8" /> | ||||
|   <meta http-equiv="X-UA-Compatible" content="IE=edge" /> | ||||
|   <meta name="viewport" content="width=device-width, initial-scale=1.0" /> | ||||
|   <title>Food Journal</title> | ||||
|  | ||||
|   <!-- Recipe Card Custom Element --> | ||||
|   <script src="/source/assets/scripts/ReviewCard.js" type="module"></script> | ||||
|  | ||||
|  | ||||
|   <!-- Main Stylesheets & Scripts -->  | ||||
|   <!-- Temporarily commented out reset.css due to furthur discussion needed on the values of the default config--> | ||||
|   <!-- <link rel="stylesheet" href="/static/reset.css" /> --> | ||||
|   <link rel="stylesheet" href="./static/ReviewCard.css" /> | ||||
|   <script src="/source/assets/scripts/ReviewDetails.js" type="module"></script> | ||||
|  | ||||
| </head> | ||||
| <body> | ||||
|   <main> | ||||
|     <button type="button" id="update">Update</button> | ||||
|     <button type="button" id="delete" class="danger">Delete</button> | ||||
|   </main> | ||||
|     <!----> <form id="update-food-entry" class="hidden"> | ||||
|       <fieldset> | ||||
|         <legend>Pic:</legend> | ||||
|         <label for="mealImage"> | ||||
|           Source: | ||||
|           <input type="text" id="mealImg" name="mealImg"> | ||||
|         </label> | ||||
|         <label for="image-alt"> | ||||
|           Alt Text: | ||||
|           <input type="text" id="imgAlt" name="imgAlt"> | ||||
|         </label> | ||||
|       </fieldset> | ||||
|       <fieldset> | ||||
|    | ||||
|         <legend> Meal: </legend> | ||||
|         <label for="Meal: ">Meal: | ||||
|           <input type="text" id="mealName" name="mealName" required> | ||||
|         </label> | ||||
|         <label for="comments">Comments:  | ||||
|           <br> | ||||
|           <textarea name="comments" id="comments"></textarea> | ||||
|         </label> | ||||
|       </fieldset> | ||||
|        | ||||
|       <fieldset class="rating"> | ||||
|         <legend> Rating: </legend> | ||||
|         <input type="radio" id="s5" name="rating" value="5"/> <label for="s5"> 5 stars </label> | ||||
|         <input type="radio" id="s4" name="rating" value="4"/> <label for="s4"> 4 stars </label> | ||||
|         <input type="radio" id="s3" name="rating" value="3"/> <label for="s3"> 3 stars </label> | ||||
|         <input type="radio" id="s2" name="rating" value="2"/> <label for="s2"> 2 stars </label> | ||||
|         <input type="radio" id="s1" name="rating" value="1"/> <label for="s1"> 1 star </label> | ||||
|       </fieldset> | ||||
|  | ||||
|       <fieldset> | ||||
|         <legend>Other Info:</legend> | ||||
|         <label for="restaurant"> | ||||
|           Restaurant: | ||||
|           <input type="text" id="restaurant" name="restaurant" required> | ||||
|         </label> | ||||
|         <label for="tag-form"> | ||||
|           Tags: | ||||
|           <input type="text" id="tag-form" name="tag-form"> | ||||
|           <div class='tag-container' id="tag-container-form"> | ||||
|    | ||||
|           </div> | ||||
|           <button type="button" id="tagAdd">Add Tag</button> | ||||
|         </label> | ||||
|    | ||||
|       </fieldset> | ||||
|       <button type="submit" value="Submit">Add Review</button> | ||||
|       </form> | ||||
| </body> | ||||
| </html> | ||||
							
								
								
									
										79
									
								
								index.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,79 @@ | ||||
|  | ||||
| <!DOCTYPE html> | ||||
| <html lang="en"> | ||||
| <head> | ||||
|   <meta charset="UTF-8" /> | ||||
|   <meta http-equiv="X-UA-Compatible" content="IE=edge" /> | ||||
|   <meta name="viewport" content="width=device-width, initial-scale=1.0" /> | ||||
|   <title>Food Journal</title> | ||||
|  | ||||
|   <!-- Recipe Card Custom Element --> | ||||
|   <script src="/source/assets/scripts/ReviewCard.js" type="module"></script> | ||||
|  | ||||
|  | ||||
|   <!-- Main Stylesheets & Scripts -->  | ||||
|   <!-- Temporarily commented out reset.css due to furthur discussion needed on the values of the default config--> | ||||
|   <!-- <link rel="stylesheet" href="/static/reset.css" /> --> | ||||
|   <link rel="stylesheet" href="./static/ReviewCard.css" /> | ||||
|   <script src="/source/assets/scripts/main.js" type="module"></script> | ||||
|  | ||||
| </head> | ||||
| <body> | ||||
|   <main> | ||||
|     <!-- Add Food Entries Here --> | ||||
|   </main> | ||||
|   <button type="button" id="create">CREATE</button> | ||||
|   <!----> <form id="new-food-entry"> | ||||
|     <fieldset> | ||||
|       <legend>Pic:</legend> | ||||
|       <label for="mealImage"> | ||||
|         Source: | ||||
|         <input type="text" id="mealImg" name="mealImg"> | ||||
|       </label> | ||||
|       <label for="image-alt"> | ||||
|         Alt Text: | ||||
|         <input type="text" id="imgAlt" name="imgAlt"> | ||||
|       </label> | ||||
|     </fieldset> | ||||
|     <fieldset> | ||||
|  | ||||
|       <legend> Meal: </legend> | ||||
|       <label for="Meal: ">Meal: | ||||
|         <input type="text" id="mealName" name="mealName" required> | ||||
|       </label> | ||||
|       <label for="comments">Comments:  | ||||
|         <br> | ||||
|         <textarea name="comments" id="comments"></textarea> | ||||
|       </label> | ||||
|     </fieldset> | ||||
|      | ||||
|     <fieldset class="rating"> | ||||
|       <legend> Rating: </legend> | ||||
|       <input type="radio" id="s5" name="rating" value="5"/> <label for="s5"> 5 stars </label> | ||||
|       <input type="radio" id="s4" name="rating" value="4"/> <label for="s4"> 4 stars </label> | ||||
|       <input type="radio" id="s3" name="rating" value="3"/> <label for="s3"> 3 stars </label> | ||||
|       <input type="radio" id="s2" name="rating" value="2"/> <label for="s2"> 2 stars </label> | ||||
|       <input type="radio" id="s1" name="rating" value="1"/> <label for="s1"> 1 star </label> | ||||
|     </fieldset> | ||||
|  | ||||
|     <fieldset> | ||||
|       <legend>Other Info:</legend> | ||||
|       <label for="restaurant"> | ||||
|         Restaurant: | ||||
|         <input type="text" id="restaurant" name="restaurant" required> | ||||
|       </label> | ||||
|       <label for="tag-form"> | ||||
|         Tags: | ||||
|         <input type="text" id="tag-form" name="tag-form"> | ||||
|         <div class='tag-container' id="tag-container-form"> | ||||
|  | ||||
|         </div> | ||||
|         <button type="button" id="tagAdd">Add Tag</button> | ||||
|       </label> | ||||
|  | ||||
|     </fieldset> | ||||
|     <button type="submit" value="Submit">Add Review</button> | ||||
|     <button type="button" class="danger">Clear Review Journal</button> | ||||
|   </form> <!----> | ||||
| </body> | ||||
| </html> | ||||
							
								
								
									
										16
									
								
								review.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,16 @@ | ||||
| <!DOCTYPE html> | ||||
| <html lang="en"> | ||||
| <head> | ||||
|     <meta charset="UTF-8" /> | ||||
|     <meta http-equiv="X-UA-Compatible" content="IE=edge" /> | ||||
|     <meta name="viewport" content="width=device-width, initial-scale=1.0" /> | ||||
|     <title>Food Journal</title> | ||||
|      | ||||
|     <script src="/source/assets/scripts/reviewpage.js" type="module"></script> | ||||
| </head> | ||||
| <body> | ||||
|     <h1>Current Review:</h1> | ||||
|     <main> | ||||
|     </main> | ||||
| </body> | ||||
| </html> | ||||
							
								
								
									
										
											BIN
										
									
								
								source/assets/images/1_spooky-ghost-cookies.jpeg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 6.6 KiB | 
							
								
								
									
										
											BIN
										
									
								
								source/assets/images/2_frightfully-easy-ghost-cookies.jpeg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 4.9 KiB | 
							
								
								
									
										
											BIN
										
									
								
								source/assets/images/3_ingredient-ghost-halloween-cookies.jpeg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 8.6 KiB | 
							
								
								
									
										1
									
								
								source/assets/images/icons/0-star.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1 @@ | ||||
| <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 157.02 27.59"><defs><style>.cls-1{fill:#dadce0;}</style></defs><g id="Layer_2" data-name="Layer 2"><g id="Layer_1-2" data-name="Layer 1"><path class="cls-1" d="M142.51,0l-3.42,10.53c-3.66,0-7.61,0-11.09,0l9,6.51c-1.12,3.47-2.35,7.24-3.42,10.54,2.87-2.1,5.92-4.3,9-6.51l9,6.51c-1.12-3.41-2.26-6.95-3.42-10.54l9-6.51H145.94"/><path class="cls-1" d="M110.51,0l-3.42,10.53c-3.66,0-7.61,0-11.09,0l9,6.51c-1.12,3.47-2.35,7.24-3.42,10.54,2.87-2.1,5.92-4.3,9-6.51l9,6.51c-1.12-3.41-2.26-6.95-3.42-10.54l9-6.51H113.94"/><path class="cls-1" d="M78.51,0,75.09,10.53c-3.66,0-7.61,0-11.09,0l9,6.51c-1.12,3.47-2.35,7.24-3.42,10.54,2.87-2.1,5.92-4.3,9-6.51l9,6.51c-1.12-3.41-2.26-6.95-3.42-10.54l9-6.51H81.94"/><path class="cls-1" d="M46.51,0,43.09,10.53c-3.66,0-7.61,0-11.09,0l9,6.51c-1.12,3.47-2.35,7.24-3.42,10.54,2.87-2.1,5.92-4.3,9-6.51l9,6.51c-1.12-3.41-2.26-6.95-3.42-10.54l9-6.51H49.94"/><path class="cls-1" d="M14.51,0,11.09,10.53c-3.66,0-7.61,0-11.09,0l9,6.51c-1.12,3.47-2.35,7.24-3.42,10.54,2.87-2.1,5.92-4.3,9-6.51l9,6.51c-1.12-3.41-2.26-6.95-3.42-10.54l9-6.51H17.94"/></g></g></svg> | ||||
| After Width: | Height: | Size: 1.1 KiB | 
							
								
								
									
										1
									
								
								source/assets/images/icons/1-star.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1 @@ | ||||
| <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 157.02 27.59"><defs><style>.cls-1{fill:#febc17;}.cls-2{fill:#dadce0;}</style></defs><g id="Layer_2" data-name="Layer 2"><g id="Layer_1-2" data-name="Layer 1"><path class="cls-1" d="M14.51,0,11.09,10.53c-3.66,0-7.61,0-11.09,0l9,6.51c-1.12,3.47-2.35,7.24-3.42,10.54,2.87-2.1,5.92-4.3,9-6.51l9,6.51c-1.12-3.41-2.26-6.95-3.42-10.54l9-6.51H17.94"/><path class="cls-2" d="M142.51,0l-3.42,10.53c-3.66,0-7.61,0-11.09,0l9,6.51c-1.12,3.47-2.35,7.24-3.42,10.54,2.87-2.1,5.92-4.3,9-6.51l9,6.51c-1.12-3.41-2.26-6.95-3.42-10.54l9-6.51H145.94"/><path class="cls-2" d="M110.51,0l-3.42,10.53c-3.66,0-7.61,0-11.09,0l9,6.51c-1.12,3.47-2.35,7.24-3.42,10.54,2.87-2.1,5.92-4.3,9-6.51l9,6.51c-1.12-3.41-2.26-6.95-3.42-10.54l9-6.51H113.94"/><path class="cls-2" d="M78.51,0,75.09,10.53c-3.66,0-7.61,0-11.09,0l9,6.51c-1.12,3.47-2.35,7.24-3.42,10.54,2.87-2.1,5.92-4.3,9-6.51l9,6.51c-1.12-3.41-2.26-6.95-3.42-10.54l9-6.51H81.94"/><path class="cls-2" d="M46.51,0,43.09,10.53c-3.66,0-7.61,0-11.09,0l9,6.51c-1.12,3.47-2.35,7.24-3.42,10.54,2.87-2.1,5.92-4.3,9-6.51l9,6.51c-1.12-3.41-2.26-6.95-3.42-10.54l9-6.51H49.94"/></g></g></svg> | ||||
| After Width: | Height: | Size: 1.1 KiB | 
							
								
								
									
										1
									
								
								source/assets/images/icons/2-star.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1 @@ | ||||
| <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 157.02 27.59"><defs><style>.cls-1{fill:#febc17;}.cls-2{fill:#dadce0;}</style></defs><g id="Layer_2" data-name="Layer 2"><g id="Layer_1-2" data-name="Layer 1"><path class="cls-1" d="M14.51,0,11.09,10.53c-3.66,0-7.61,0-11.09,0l9,6.51c-1.12,3.47-2.35,7.24-3.42,10.54,2.87-2.1,5.92-4.3,9-6.51l9,6.51c-1.12-3.41-2.26-6.95-3.42-10.54l9-6.51H17.94"/><path class="cls-1" d="M46.51,0,43.09,10.53c-3.66,0-7.61,0-11.09,0l9,6.51c-1.12,3.47-2.35,7.24-3.42,10.54,2.87-2.1,5.92-4.3,9-6.51l9,6.51c-1.12-3.41-2.26-6.95-3.42-10.54l9-6.51H49.94"/><path class="cls-2" d="M142.51,0l-3.42,10.53c-3.66,0-7.61,0-11.09,0l9,6.51c-1.12,3.47-2.35,7.24-3.42,10.54,2.87-2.1,5.92-4.3,9-6.51l9,6.51c-1.12-3.41-2.26-6.95-3.42-10.54l9-6.51H145.94"/><path class="cls-2" d="M110.51,0l-3.42,10.53c-3.66,0-7.61,0-11.09,0l9,6.51c-1.12,3.47-2.35,7.24-3.42,10.54,2.87-2.1,5.92-4.3,9-6.51l9,6.51c-1.12-3.41-2.26-6.95-3.42-10.54l9-6.51H113.94"/><path class="cls-2" d="M78.51,0,75.09,10.53c-3.66,0-7.61,0-11.09,0l9,6.51c-1.12,3.47-2.35,7.24-3.42,10.54,2.87-2.1,5.92-4.3,9-6.51l9,6.51c-1.12-3.41-2.26-6.95-3.42-10.54l9-6.51H81.94"/></g></g></svg> | ||||
| After Width: | Height: | Size: 1.1 KiB | 
							
								
								
									
										1
									
								
								source/assets/images/icons/3-star.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1 @@ | ||||
| <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 157.02 27.59"><defs><style>.cls-1{fill:#febc17;}.cls-2{fill:#dadce0;}</style></defs><g id="Layer_2" data-name="Layer 2"><g id="Layer_1-2" data-name="Layer 1"><path class="cls-1" d="M14.51,0,11.09,10.53c-3.66,0-7.61,0-11.09,0l9,6.51c-1.12,3.47-2.35,7.24-3.42,10.54,2.87-2.1,5.92-4.3,9-6.51l9,6.51c-1.12-3.41-2.26-6.95-3.42-10.54l9-6.51H17.94"/><path class="cls-1" d="M46.51,0,43.09,10.53c-3.66,0-7.61,0-11.09,0l9,6.51c-1.12,3.47-2.35,7.24-3.42,10.54,2.87-2.1,5.92-4.3,9-6.51l9,6.51c-1.12-3.41-2.26-6.95-3.42-10.54l9-6.51H49.94"/><path class="cls-1" d="M78.51,0,75.09,10.53c-3.66,0-7.61,0-11.09,0l9,6.51c-1.12,3.47-2.35,7.24-3.42,10.54,2.87-2.1,5.92-4.3,9-6.51l9,6.51c-1.12-3.41-2.26-6.95-3.42-10.54l9-6.51H81.94"/><path class="cls-2" d="M142.51,0l-3.42,10.53c-3.66,0-7.61,0-11.09,0l9,6.51c-1.12,3.47-2.35,7.24-3.42,10.54,2.87-2.1,5.92-4.3,9-6.51l9,6.51c-1.12-3.41-2.26-6.95-3.42-10.54l9-6.51H145.94"/><path class="cls-2" d="M110.51,0l-3.42,10.53c-3.66,0-7.61,0-11.09,0l9,6.51c-1.12,3.47-2.35,7.24-3.42,10.54,2.87-2.1,5.92-4.3,9-6.51l9,6.51c-1.12-3.41-2.26-6.95-3.42-10.54l9-6.51H113.94"/></g></g></svg> | ||||
| After Width: | Height: | Size: 1.1 KiB | 
							
								
								
									
										1
									
								
								source/assets/images/icons/4-star.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1 @@ | ||||
| <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 157.02 27.59"><defs><style>.cls-1{fill:#febc17;}.cls-2{fill:#dadce0;}</style></defs><g id="Layer_2" data-name="Layer 2"><g id="Layer_1-2" data-name="Layer 1"><path class="cls-1" d="M14.51,0,11.09,10.53c-3.66,0-7.61,0-11.09,0l9,6.51c-1.12,3.47-2.35,7.24-3.42,10.54,2.87-2.1,5.92-4.3,9-6.51l9,6.51c-1.12-3.41-2.26-6.95-3.42-10.54l9-6.51H17.94"/><path class="cls-1" d="M46.51,0,43.09,10.53c-3.66,0-7.61,0-11.09,0l9,6.51c-1.12,3.47-2.35,7.24-3.42,10.54,2.87-2.1,5.92-4.3,9-6.51l9,6.51c-1.12-3.41-2.26-6.95-3.42-10.54l9-6.51H49.94"/><path class="cls-1" d="M78.51,0,75.09,10.53c-3.66,0-7.61,0-11.09,0l9,6.51c-1.12,3.47-2.35,7.24-3.42,10.54,2.87-2.1,5.92-4.3,9-6.51l9,6.51c-1.12-3.41-2.26-6.95-3.42-10.54l9-6.51H81.94"/><path class="cls-1" d="M110.51,0l-3.42,10.53c-3.66,0-7.61,0-11.09,0l9,6.51c-1.12,3.47-2.35,7.24-3.42,10.54,2.87-2.1,5.92-4.3,9-6.51l9,6.51c-1.12-3.41-2.26-6.95-3.42-10.54l9-6.51H113.94"/><path class="cls-2" d="M142.51,0l-3.42,10.53c-3.66,0-7.61,0-11.09,0l9,6.51c-1.12,3.47-2.35,7.24-3.42,10.54,2.87-2.1,5.92-4.3,9-6.51l9,6.51c-1.12-3.41-2.26-6.95-3.42-10.54l9-6.51H145.94"/></g></g></svg> | ||||
| After Width: | Height: | Size: 1.1 KiB | 
							
								
								
									
										1
									
								
								source/assets/images/icons/5-star.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1 @@ | ||||
| <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 157.02 27.59"><defs><style>.cls-1{fill:#febc17;}</style></defs><g id="Layer_2" data-name="Layer 2"><g id="Layer_1-2" data-name="Layer 1"><path class="cls-1" d="M14.51,0,11.09,10.53c-3.66,0-7.61,0-11.09,0l9,6.51c-1.12,3.47-2.35,7.24-3.42,10.54,2.87-2.1,5.92-4.3,9-6.51l9,6.51c-1.12-3.41-2.26-6.95-3.42-10.54l9-6.51H17.94"/><path class="cls-1" d="M46.51,0,43.09,10.53c-3.66,0-7.61,0-11.09,0l9,6.51c-1.12,3.47-2.35,7.24-3.42,10.54,2.87-2.1,5.92-4.3,9-6.51l9,6.51c-1.12-3.41-2.26-6.95-3.42-10.54l9-6.51H49.94"/><path class="cls-1" d="M78.51,0,75.09,10.53c-3.66,0-7.61,0-11.09,0l9,6.51c-1.12,3.47-2.35,7.24-3.42,10.54,2.87-2.1,5.92-4.3,9-6.51l9,6.51c-1.12-3.41-2.26-6.95-3.42-10.54l9-6.51H81.94"/><path class="cls-1" d="M110.51,0l-3.42,10.53c-3.66,0-7.61,0-11.09,0l9,6.51c-1.12,3.47-2.35,7.24-3.42,10.54,2.87-2.1,5.92-4.3,9-6.51l9,6.51c-1.12-3.41-2.26-6.95-3.42-10.54l9-6.51H113.94"/><path class="cls-1" d="M142.51,0l-3.42,10.53c-3.66,0-7.61,0-11.09,0l9,6.51c-1.12,3.47-2.35,7.24-3.42,10.54,2.87-2.1,5.92-4.3,9-6.51l9,6.51c-1.12-3.41-2.26-6.95-3.42-10.54l9-6.51H145.94"/></g></g></svg> | ||||
| After Width: | Height: | Size: 1.1 KiB | 
							
								
								
									
										
											BIN
										
									
								
								source/assets/images/icons/default_plate.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 311 KiB | 
							
								
								
									
										
											BIN
										
									
								
								source/assets/images/icons/plate_with_chopsticks.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 129 KiB | 
							
								
								
									
										
											BIN
										
									
								
								source/assets/images/icons/plate_with_cutlery.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 253 KiB | 
							
								
								
									
										270
									
								
								source/assets/scripts/ReviewCard.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,270 @@ | ||||
| // ReviewCard.js | ||||
|  | ||||
| class ReviewCard extends HTMLElement { | ||||
|   // Called once when document.createElement('review-card') is called, or | ||||
|   // the element is written into the DOM directly as <review-card> | ||||
|   constructor() { | ||||
|     super();  | ||||
|  | ||||
|  | ||||
|     let shadowEl = this.attachShadow({mode:'open'}); | ||||
|  | ||||
|     let articleEl = document.createElement('article'); | ||||
|  | ||||
|     let styleEl = document.createElement('style'); | ||||
|     styleEl.textContent = ` | ||||
|       * { | ||||
|         font-family: sans-serif; | ||||
|         margin: 0; | ||||
|         padding: 0; | ||||
|       } | ||||
|      | ||||
|       a { | ||||
|         text-decoration: none; | ||||
|       } | ||||
|      | ||||
|       a:hover { | ||||
|         text-decoration: underline; | ||||
|       } | ||||
|      | ||||
|       article { | ||||
|         align-items: center; | ||||
|         border: 1px solid rgb(223, 225, 229); | ||||
|         border-radius: 8px; | ||||
|         display: grid; | ||||
|         grid-template-rows: 118px 56px 14px 18px 15px 36px; | ||||
|         height: auto; | ||||
|         row-gap: 5px; | ||||
|         padding: 0 16px 16px 16px; | ||||
|         width: 178px; | ||||
|       } | ||||
|      | ||||
|       div.rating { | ||||
|         align-items: center; | ||||
|         column-gap: 5px; | ||||
|         display: flex; | ||||
|       } | ||||
|      | ||||
|       div.rating>img { | ||||
|         height: auto; | ||||
|         display: inline-block; | ||||
|         object-fit: scale-down; | ||||
|         width: 78px; | ||||
|       } | ||||
|      | ||||
|       article>img { | ||||
|         border-top-left-radius: 8px; | ||||
|         border-top-right-radius: 8px; | ||||
|         height: 118px; | ||||
|         object-fit: cover; | ||||
|         margin-left: -16px; | ||||
|         width: calc(100% + 32px); | ||||
|       } | ||||
|      | ||||
|       label.restaurant-name { | ||||
|         color: black !important; | ||||
|       } | ||||
|      | ||||
|       label.meal-name { | ||||
|         display: -webkit-box; | ||||
|         font-size: 16px; | ||||
|         height: 36px; | ||||
|         line-height: 18px; | ||||
|         overflow: hidden; | ||||
|         -webkit-line-clamp: 2; | ||||
|         -webkit-box-orient: vertical; | ||||
|       } | ||||
|      | ||||
|       label:not(.meal-name), | ||||
|       span, | ||||
|       time { | ||||
|         color: #70757A; | ||||
|         font-size: 12px; | ||||
|       } | ||||
|     `; | ||||
|     articleEl.append(styleEl); | ||||
|     shadowEl.append(articleEl); | ||||
|     this.shadowEl = shadowEl; | ||||
|     //attach event listener to each recipe-card | ||||
|     this.addEventListener('click', (event) => { | ||||
|       console.log(event.target); | ||||
|       console.log(event.target.data); | ||||
|       //Option 1: sending current data to second html page using localStorage (could also just store index) | ||||
|       sessionStorage.setItem('current', JSON.stringify(event.target.data)); | ||||
|       window.location.assign("./ReviewDetails.html"); | ||||
|       /* | ||||
|       //Option 2: sending current data to second html page using string query w/ url (currently not storing value) | ||||
|       let reviewFields = window.location.search.slice(1).split("&"); | ||||
|       for(let i = 0; i < reviewFields.length; i++) { | ||||
|         let kv = reviewFields[i].split("="); | ||||
|         let key = kv[0];  | ||||
|         let value = kv[1]; | ||||
|         console.log(key); | ||||
|         console.log(value); | ||||
|         // What you want to do with name and value... | ||||
|       }*/ | ||||
|     }); | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * Called when the .data property is set on this element. | ||||
|    * | ||||
|    * For Example: | ||||
|    * let reviewCard = document.createElement('review-card');  | ||||
|    * reviewCard.data = { foo: 'bar' }  | ||||
|    * | ||||
|    * @param {Object} data - The data to pass into the <review-card>, must be of the | ||||
|    *                        following format: | ||||
|    *                        { | ||||
|    *                          "mealImg": "string", | ||||
|    *                          "imgAlt": "string", | ||||
|    *                          "mealName": "string", | ||||
|    *                          "comments": "string", | ||||
|    *                          "rating": number, | ||||
|    *                          "restaurant": "string", | ||||
|    *                          "tags": string array | ||||
|    *                        } | ||||
|    */ | ||||
|   set data(data) { | ||||
|     // If nothing was passed in, return | ||||
|     if (!data) return; | ||||
|  | ||||
|     // Select the <article> we added to the Shadow DOM in the constructor | ||||
|     let articleEl = this.shadowEl.querySelector('article'); | ||||
|      | ||||
|     // setting the article elements for the review card | ||||
|  | ||||
|     //image setup | ||||
|     let mealImg = document.createElement('img'); | ||||
|     mealImg.setAttribute('id', 'a-mealImg'); | ||||
|     mealImg.setAttribute('src',data['mealImg']); | ||||
|     mealImg.setAttribute('alt',data['imgAlt']); | ||||
|  | ||||
|     //meal name setup | ||||
|     let mealLabel = document.createElement('label'); | ||||
|     mealLabel.setAttribute('id', 'a-mealName'); | ||||
|     mealLabel.setAttribute('class','meal-name'); | ||||
|     mealLabel.innerHTML = data['mealName']; | ||||
|  | ||||
|     //restaurant name setup | ||||
| /* | ||||
|     //review page link | ||||
|     //giving it functionality to save the review card's info to session storage for loading the review page | ||||
|     let reviewLink = document.createElement('a'); | ||||
|     reviewLink.setAttribute('href','./review.html') | ||||
|     reviewLink.innerHTML = 'review page' | ||||
|     reviewLink.addEventListener('click', () => { | ||||
|       sessionStorage.clear(); | ||||
|       let currReview = { | ||||
|         "imgSrc": data['imgSrc'], | ||||
|         "imgAlt": data['imgAlt'], | ||||
|         "mealName": data['mealName'], | ||||
|         "restaurant": data['restaurant'], | ||||
|         "comments": data['comments'], | ||||
|         "rating": data['rating'], | ||||
|         "tags": data['tags']                 | ||||
|       } | ||||
|       sessionStorage.setItem('currReview', JSON.stringify(currReview)); | ||||
|     }); | ||||
| */ | ||||
|     let restaurantLabel = document.createElement('label'); | ||||
|     restaurantLabel.setAttribute('id', 'a-restaurant'); | ||||
|     restaurantLabel.setAttribute('class','restaurant-name'); | ||||
|     restaurantLabel.innerHTML = data['restaurant']; | ||||
|  | ||||
|     //comment section setup (display set to none) | ||||
|     let comments = document.createElement('p'); | ||||
|     comments.setAttribute('id', 'a-comments'); | ||||
|     comments.style.display = 'none'; | ||||
|     comments.innerText = data['comments']; | ||||
|  | ||||
|     //other info: rating | ||||
|     let ratingDiv = document.createElement('div'); | ||||
|     ratingDiv.setAttribute('class', 'rating'); | ||||
|     let starsImg = document.createElement('img'); | ||||
|     starsImg.setAttribute('id', 'a-rating'); | ||||
|     starsImg.setAttribute('src', './source/assets/images/icons/'+data['rating']+'-star.svg'); | ||||
|     starsImg.setAttribute('alt', data['rating'] +' stars'); | ||||
|     starsImg.setAttribute('num', data['rating']); | ||||
|     ratingDiv.append(starsImg); | ||||
|  | ||||
|     //added tags | ||||
|     let tagContainer = document.createElement('div'); | ||||
|     tagContainer.setAttribute('class', 'tag-container'); | ||||
|     tagContainer.setAttribute('id', 'a-tags'); | ||||
|     tagContainer.setAttribute('list', data['tags']); | ||||
|     if(data['tags']){ | ||||
|       for (let i = 0; i < data['tags'].length; i++) { | ||||
|         let newTag = document.createElement('label'); | ||||
|         newTag.setAttribute('class','tag'); | ||||
|         newTag.innerHTML = data['tags'][i] + "   "; | ||||
|         tagContainer.append(newTag); | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     articleEl.append(mealImg); | ||||
|     articleEl.append(mealLabel); | ||||
|     //articleEl.append(reviewLink) | ||||
|     articleEl.append(restaurantLabel); | ||||
|     articleEl.append(ratingDiv); | ||||
|     articleEl.append(tagContainer); | ||||
|     articleEl.append(comments); | ||||
|  | ||||
|  | ||||
|   } | ||||
|  | ||||
|     /** | ||||
|    * Called when getting the .data property of this element. | ||||
|    * | ||||
|    * For Example: | ||||
|    * let reviewCard = document.createElement('review-card');  | ||||
|    * reviewCard.data = { foo: 'bar' }  | ||||
|    * | ||||
|    * @return {Object} data - The data from the <review-card>, of the | ||||
|    *                        following format: | ||||
|    *                        { | ||||
|    *                          "mealImg": "string", | ||||
|    *                          "imgAlt": "string", | ||||
|    *                          "mealName": "string", | ||||
|    *                          "comments": "string", | ||||
|    *                          "rating": number, | ||||
|    *                          "restaurant": "string", | ||||
|    *                          "tags": string array | ||||
|    *                        } | ||||
|    */ | ||||
|   get data() { | ||||
|  | ||||
|     let dataContainer = {}; | ||||
|      | ||||
|     // getting the article elements for the review card | ||||
|  | ||||
|     //get image | ||||
|     let mealImg = this.shadowEl.getElementById('a-mealImg'); | ||||
|     dataContainer['mealImg'] = mealImg.getAttribute('src'); | ||||
|     dataContainer['imgAlt'] = mealImg.getAttribute('alt'); | ||||
|  | ||||
|     //get meal name | ||||
|     let mealLabel = this.shadowEl.getElementById('a-mealName'); | ||||
|     dataContainer['mealName'] = mealLabel.innerHTML; | ||||
|  | ||||
|     //get comment section | ||||
|     let comments = this.shadowEl.getElementById('a-comments'); | ||||
|     console.log(comments); | ||||
|     dataContainer['comments'] = comments.innerText; | ||||
|  | ||||
|     //get other info: rating | ||||
|     let starsImg = this.shadowEl.getElementById('a-rating'); | ||||
|     dataContainer['rating'] = starsImg.getAttribute('num'); | ||||
|  | ||||
|     //get restaurant name | ||||
|     let restaurantLabel = this.shadowEl.getElementById('a-restaurant'); | ||||
|     dataContainer['restaurant'] = restaurantLabel.innerHTML; | ||||
|  | ||||
|     //get tags | ||||
|     let tagContainer = this.shadowEl.getElementById('a-tags'); | ||||
|     dataContainer['tags'] = tagContainer.getAttribute('list').split(","); | ||||
|  | ||||
|     return dataContainer; | ||||
|   } | ||||
| } | ||||
| customElements.define('review-card', ReviewCard); | ||||
							
								
								
									
										127
									
								
								source/assets/scripts/ReviewDetails.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,127 @@ | ||||
| //reviewDetails.js | ||||
| import {getReviewsFromStorage, saveReviewsToStorage} from './localStorage.js'; | ||||
|  | ||||
| // Run the init() function when the page has loaded | ||||
| window.addEventListener('DOMContentLoaded', init); | ||||
|  | ||||
| function init(){ | ||||
|     let main = document.querySelector('main'); | ||||
|     let reviews = getReviewsFromStorage(); | ||||
|     setupDelete(); | ||||
|     setupUpdate(); | ||||
| } | ||||
|  | ||||
| function setupDelete(){ | ||||
|     let deleteBtn = document.getElementById('delete'); | ||||
|     let reviews = getReviewsFromStorage(); | ||||
|     let current = JSON.parse(sessionStorage.getItem('current')); | ||||
|     deleteBtn.addEventListener('click', function(){ | ||||
|         if(window.confirm("Are you sure you want to delete this entry?")){ | ||||
|             //delete function | ||||
|             if(current){ | ||||
|                 console.log(current); | ||||
|                 for(let i = 0; i < reviews.length; i++){ | ||||
|                     console.log(reviews[i]); | ||||
|                     if(reviews[i]['mealName'] == current['mealName'] && reviews[i]['restaurant'] == current['restaurant']){ | ||||
|                         console.log("match found"); | ||||
|                         reviews.splice(i,1); | ||||
|                         saveReviewsToStorage(reviews); | ||||
|                         sessionStorage.removeItem('current'); | ||||
|                         window.location.assign("./index.html"); | ||||
|                         break; | ||||
|                     } | ||||
|                 }; | ||||
|             } | ||||
|         } | ||||
|     }); | ||||
| } | ||||
|  | ||||
| function setupUpdate(){ | ||||
|     let updateBtn = document.getElementById('update'); | ||||
|     let reviews = getReviewsFromStorage(); | ||||
|     let current = JSON.parse(sessionStorage.getItem('current')); | ||||
|     let form = document.getElementById('update-food-entry'); | ||||
|     updateBtn.addEventListener('click', function(){ | ||||
|         //update function | ||||
|         if(current){ | ||||
|             console.log(current); | ||||
|             form.style.display = 'block'; | ||||
|             let tagContainer = document.getElementById('tag-container-form'); | ||||
|             console.log(document.querySelectorAll('#update-food-entry input')); | ||||
|  | ||||
|             //Set value of each input element to current's values | ||||
|             document.getElementById('mealImg').defaultValue = current['mealImg']; | ||||
|             document.getElementById('imgAlt').defaultValue = current['imgAlt']; | ||||
|             document.getElementById('mealName').defaultValue = current['mealName']; | ||||
|             document.getElementById('comments').textContent = current['comments']; | ||||
|             document.getElementById('rating-' + `${current['rating']}`).checked = true; | ||||
|             document.getElementById('restaurant').defaultValue = current['restaurant']; | ||||
|  | ||||
|             if(current['tags']){ | ||||
|                 for (let i = 0; i < current['tags'].length; i++) { | ||||
|                   let newTag = document.createElement('label'); | ||||
|                   newTag.setAttribute('class','tag'); | ||||
|                   newTag.innerHTML = current['tags'][i] + "   "; | ||||
|                   newTag.addEventListener('click',()=> { | ||||
|                     tagContainer.removeChild(newTag); | ||||
|                   }); | ||||
|                   tagContainer.append(newTag); | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             //Take formdata values as newData when submit | ||||
|             form.addEventListener('submit', function(){ | ||||
|                 /* | ||||
|                 *  User submits the form for their review. | ||||
|                 *  We create reviewCard and put in storage | ||||
|                 */ | ||||
|                 let formData = new FormData(form); | ||||
|                 let newData = {}; | ||||
|                 for (let [key, value] of formData) { | ||||
|                   console.log(`${key}`); | ||||
|                   console.log(`${value}`); | ||||
|                   if (`${key}` !== "tag-form") { | ||||
|                     newData[`${key}`] = `${value}`; | ||||
|                   } | ||||
|                 } | ||||
|                 newData['tags'] = []; | ||||
|              | ||||
|                 let tags = document.querySelectorAll('.tag'); | ||||
|                 for(let i = 0; i < tags.length; i ++) { | ||||
|                   newData['tags'].push(tags[i].innerHTML); | ||||
|                   tagContainer.removeChild(tags[i]); | ||||
|                 } | ||||
|  | ||||
|                 for(let i = 0; i < reviews.length; i++){ | ||||
|                     console.log(reviews[i]); | ||||
|                     if(reviews[i]['mealName'] == current['mealName'] && reviews[i]['restaurant'] == current['restaurant']){ | ||||
|                         console.log("match found"); | ||||
|                         reviews.splice(i,1,newData); | ||||
|                         saveReviewsToStorage(reviews); | ||||
|                         sessionStorage.setItem('current', JSON.stringify(newData)); | ||||
|                         break; | ||||
|                     } | ||||
|                 }; | ||||
|  | ||||
|                 form.style.display = 'none'; | ||||
|  | ||||
|             }); | ||||
|  | ||||
|             let tagAddBtn = document.getElementById('tagAdd'); | ||||
|             tagAddBtn.addEventListener('click', ()=> { | ||||
|               let tagField = document.getElementById('tag-form'); | ||||
|               if (tagField.value.length > 0) { | ||||
|                 let tagLabel = document.createElement('label'); | ||||
|                 tagLabel.innerHTML = tagField.value; | ||||
|                 tagLabel.setAttribute('class','tag'); | ||||
|                 tagLabel.addEventListener('click',()=> { | ||||
|                   tagContainer.removeChild(tagLabel); | ||||
|                 }); | ||||
|                  | ||||
|                 tagContainer.append(tagLabel); | ||||
|                 tagField.value = ''; | ||||
|               } | ||||
|             }); | ||||
|         } | ||||
|     }); | ||||
| } | ||||
							
								
								
									
										13
									
								
								source/assets/scripts/ReviewPage.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,13 @@ | ||||
| // Run the init() function when the page has loaded | ||||
| window.addEventListener('DOMContentLoaded', init); | ||||
|  | ||||
| function init() { | ||||
|     let result = sessionStorage.getItem('currReview') | ||||
|  | ||||
|     let main = document.querySelector('main'); | ||||
|      | ||||
|     main.innerHTML = result | ||||
|     let p = document.createElement('p') | ||||
|     p.innerHTML = JSON.parse(result)['comments'] | ||||
|     main.append(p) | ||||
| } | ||||
							
								
								
									
										19
									
								
								source/assets/scripts/localStorage.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,19 @@ | ||||
| /** | ||||
|  * @returns {Array<Object>} An array of reviews found in localStorage | ||||
|  */ | ||||
| export function getReviewsFromStorage() { | ||||
| 	let result = JSON.parse(localStorage.getItem('reviews')) | ||||
| 	if (result) { | ||||
| 		return result; | ||||
| 	} | ||||
| 	return new Array(0); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Takes in an array of reviews, converts it to a string, and then | ||||
|  * saves that string to 'reviews' in localStorage | ||||
|  * @param {Array<Object>} reviews An array of reviews | ||||
|  */ | ||||
| export function saveReviewsToStorage(reviews) { | ||||
| 	localStorage.setItem('reviews', JSON.stringify(reviews)); | ||||
| } | ||||
							
								
								
									
										48
									
								
								source/assets/scripts/localStorage.test.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,48 @@ | ||||
| import {strict as assert} from "node:assert" | ||||
| import {describe, it, beforeEach} from "mocha"; | ||||
| import {saveReviewsToStorage, getReviewsFromStorage} from "./localStorage.js"; | ||||
|  | ||||
| beforeEach(() => { | ||||
| 	localStorage.clear(); | ||||
| }); | ||||
|  | ||||
| describe("test app localStorage interaction", () => { | ||||
| 	it("get after init", () => { | ||||
| 		assert.deepEqual(getReviewsFromStorage(), []); | ||||
| 	}); | ||||
| 	it("store one then get", () => { | ||||
| 		let reviews = [{ | ||||
| 			"imgSrc": "sample src", | ||||
| 			"imgAlt": "sample alt", | ||||
| 			"mealName": "sample name", | ||||
| 			"restaurant": "sample restaurant", | ||||
| 			"rating": 5, | ||||
| 			"tags": ["tag 1", "tag  2", "tag 3"] | ||||
| 		}]; | ||||
|  | ||||
| 		saveReviewsToStorage(reviews); | ||||
| 		assert.deepEqual(getReviewsFromStorage(), reviews); | ||||
| 	}); | ||||
| 	it("repeated store one more and get", () => { | ||||
| 		let reviews = []; | ||||
|  | ||||
| 		assert.deepEqual(getReviewsFromStorage(), reviews); | ||||
|  | ||||
| 		for(let i = 0; i < 1000; i++){ | ||||
| 			reviews = getReviewsFromStorage(); | ||||
| 			 | ||||
| 			reviews.push( | ||||
| 				{ | ||||
| 					"imgSrc": `sample src ${i}`, | ||||
| 					"imgAlt": `sample alt ${i}`, | ||||
| 					"mealName": `sample name ${i}`, | ||||
| 					"restaurant": `sample restaurant ${i}`, | ||||
| 					"rating": i, | ||||
| 					"tags": [`tag ${3*i}`, `tag ${3*i + 1}`, `tag ${3*i + 2}`] | ||||
| 				} | ||||
| 			) | ||||
| 			saveReviewsToStorage(reviews); | ||||
| 			assert.deepEqual(getReviewsFromStorage(), reviews); | ||||
| 		} | ||||
| 	}); | ||||
| }); | ||||
							
								
								
									
										118
									
								
								source/assets/scripts/main.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,118 @@ | ||||
| // main.js | ||||
| import {getReviewsFromStorage, saveReviewsToStorage} from './localStorage.js'; | ||||
|  | ||||
| // Run the init() function when the page has loaded | ||||
| window.addEventListener('DOMContentLoaded', init); | ||||
|  | ||||
| function init() { | ||||
|   // Get the reviews from localStorage | ||||
|   let reviews = getReviewsFromStorage(); | ||||
|   // Add each reviews to the <main> element | ||||
|   addReviewsToDocument(reviews); | ||||
|   // Add the event listeners to the form elements | ||||
|   initFormHandler(); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * @param {Array<Object>} reviews An array of reviews | ||||
|  */ | ||||
| function addReviewsToDocument(reviews) { | ||||
|   let mainEl = document.querySelector('main'); | ||||
|   reviews.forEach(review => { | ||||
|     let newReview = document.createElement('review-card'); | ||||
|     newReview.data = review; | ||||
|     //TODO: want to append it to whatever the box is in layout  | ||||
|     mainEl.append(newReview); | ||||
|   }); | ||||
|  | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Adds the necessary event handlers to <form> and the clear storage | ||||
|  * <button>. | ||||
|  */ | ||||
| function initFormHandler() { | ||||
|  | ||||
|   //btn to create form (could be its own function?) | ||||
|   let createBtn = document.getElementById('create'); | ||||
|   createBtn.addEventListener('click', function(){ | ||||
|     window.location.assign('./CreatePage.html'); | ||||
|   }); | ||||
|  | ||||
|   //accessing form components | ||||
|   let tagContainer = document.getElementById('tag-container-form'); | ||||
|   let form = document.querySelector('form'); | ||||
|    | ||||
|   form.addEventListener('submit', function(){ | ||||
|     /* | ||||
|     *  User submits the form for their review. | ||||
|     *  We create reviewCard and put in storage | ||||
|     */ | ||||
|     let formData = new FormData(form); | ||||
|     let reviewObject = {}; | ||||
|     for (let [key, value] of formData) { | ||||
|       console.log(`${key}`); | ||||
|       console.log(`${value}`); | ||||
|       if (`${key}` !== "tag-form") { | ||||
|         reviewObject[`${key}`] = `${value}`; | ||||
|       } | ||||
|     } | ||||
|     reviewObject['tags'] = []; | ||||
|  | ||||
|     let tags = document.querySelectorAll('.tag'); | ||||
|     for(let i = 0; i < tags.length; i ++) { | ||||
|       reviewObject['tags'].push(tags[i].innerHTML); | ||||
|       tagContainer.removeChild(tags[i]); | ||||
|     } | ||||
|      | ||||
|  | ||||
|     let newReview = document.createElement('review-card'); | ||||
|     newReview.data = reviewObject; | ||||
|  | ||||
|     //TODO: want to append it to whatever the box is in layout  | ||||
|     let mainEl = document.querySelector('main'); | ||||
|     mainEl.append(newReview); | ||||
|  | ||||
|     let storedReviews = getReviewsFromStorage(); | ||||
|     storedReviews.push(reviewObject); | ||||
|     saveReviewsToStorage(storedReviews); | ||||
|     document.getElementById("new-food-entry").reset(); | ||||
|   }); | ||||
|  | ||||
|   // DEV-MODE: for testing purposes  | ||||
|   let clearBtn = document.querySelector('.danger'); | ||||
|   clearBtn.addEventListener('click', function() { | ||||
|     localStorage.clear(); | ||||
|     let mainEl = document.querySelector('main'); | ||||
|     while (mainEl.firstChild) { | ||||
|       mainEl.removeChild(mainEl.firstChild); | ||||
|     } | ||||
|     let deleteTags = document.querySelectorAll('.tag'); | ||||
|     for(let i = 0; i < deleteTags.length; i ++) { | ||||
|       tagContainer.removeChild(deleteTags[i]); | ||||
|     } | ||||
|      | ||||
|     //clears reviews AS WELL as resets form | ||||
|     document.getElementById("new-food-entry").reset(); | ||||
|       | ||||
|       | ||||
|   }); | ||||
|  | ||||
|   let tagAddBtn = document.getElementById('tagAdd'); | ||||
|   tagAddBtn.addEventListener('click', ()=> { | ||||
|     let tagField = document.getElementById('tag-form'); | ||||
|     if (tagField.value.length > 0) { | ||||
|       let tagLabel = document.createElement('label'); | ||||
|       tagLabel.innerHTML = tagField.value; | ||||
|       tagLabel.setAttribute('class','tag'); | ||||
|       tagLabel.addEventListener('click',()=> { | ||||
|         tagContainer.removeChild(tagLabel); | ||||
|       }); | ||||
|        | ||||
|       tagContainer.append(tagLabel); | ||||
|       tagField.value = ''; | ||||
|  | ||||
|     } | ||||
|   }); | ||||
|  | ||||
| } | ||||
							
								
								
									
										19
									
								
								source/reviews.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,19 @@ | ||||
| [ | ||||
|    { | ||||
|       "imgSrc": "https://cdn.vox-cdn.com/thumbor/Cj5J-5WqSCjlC2tWCOXEB536CJY=/0x0:1810x1182/1200x800/filters:focal(761x447:1049x735)/cdn.vox-cdn.com/uploads/chorus_image/image/69422966/Tacos_Lined_Up.0.png", | ||||
|       "imgAlt": "tacos pic", | ||||
|       "mealName": "Birria Tacos", | ||||
|       "restaurant": "Mike's Red Tacos", | ||||
|       "rating": 5, | ||||
|       "tags": ["delicious", "#worthit","omg"] | ||||
|    }, | ||||
|    { | ||||
|       "imgSrc": "https://www.redwormcomposting.com/images/worm-burrito.JPG", | ||||
|       "imgAlt": "wolftown pic", | ||||
|       "mealName": "Carnitas Burrito", | ||||
|       "restaurant": "Wolftown UCSD", | ||||
|       "rating": 0, | ||||
|       "tags": ["gross", "why","no"] | ||||
|  | ||||
|    } | ||||
| ] | ||||
							
								
								
									
										128
									
								
								static/CreatePage.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,128 @@ | ||||
| /* CreatePage.css */ | ||||
|  | ||||
| * { | ||||
|   font-family: sans-serif; | ||||
| } | ||||
|  | ||||
| body { | ||||
|   height: 100%; | ||||
|   width: 100%; | ||||
| } | ||||
|  | ||||
| fieldset { | ||||
|   border: 2px solid rgb(214, 214, 214); | ||||
|   box-sizing: border-box; | ||||
|   display: block; | ||||
|   width: max-content; | ||||
| } | ||||
|  | ||||
| form button { | ||||
|   display: block; | ||||
|   margin-top: 5px; | ||||
| } | ||||
|  | ||||
| label[for="ingredients"] p { | ||||
|   margin: 0; | ||||
| } | ||||
|  | ||||
| label[for="numRatings"] { | ||||
|   margin: 10px 0 0 0; | ||||
| } | ||||
|  | ||||
| label[for^="rating"] { | ||||
|   padding-right: 10px; | ||||
| } | ||||
|  | ||||
| label:not([for^="rating"]) { | ||||
|   display: block; | ||||
|   margin-bottom: 5px; | ||||
| } | ||||
|  | ||||
| main { | ||||
|   column-gap: 10px; | ||||
|   display: flex; | ||||
|   flex-wrap: wrap; | ||||
|   height: auto; | ||||
|   max-width: 660px; | ||||
|   row-gap: 10px; | ||||
|   width: 100%; | ||||
| } | ||||
|  | ||||
| .tag-container { | ||||
|   display: flex; | ||||
|   flex-flow: row wrap; | ||||
| } | ||||
| .tag { | ||||
| background-color: grey; | ||||
| border-radius: 7px; | ||||
| color: white; | ||||
| padding-right: 7px; | ||||
| padding-left: 7px; | ||||
| margin: 3px; | ||||
| } | ||||
|  | ||||
| .tag::before { | ||||
| display: inline-block; | ||||
| content: 'x'; | ||||
| height: 15px; | ||||
| width: 15px; | ||||
| margin-right: 4px; | ||||
| text-align: center; | ||||
| color: white; | ||||
| cursor: pointer; | ||||
| } | ||||
|  | ||||
| .tag:hover::before { | ||||
| color: red; | ||||
| } | ||||
| .danger { | ||||
| background-color: rgb(254, 171, 171); | ||||
| border-color: red; | ||||
| } | ||||
|  | ||||
|  | ||||
| .hidden,  | ||||
| .rating:not(:checked) > input { /* Hide radio circles while star rating */ | ||||
| display: none; | ||||
| } | ||||
|  | ||||
| /* Unchecked stars */ | ||||
| .rating:not(:checked) > label { | ||||
|   /* Make stars line up sideways and not vertically */ | ||||
|   float:right;  | ||||
|  | ||||
|   /* Hide label text */ | ||||
|   width:1em; | ||||
|   overflow:hidden; | ||||
|   white-space:nowrap; | ||||
|  | ||||
|   font-size:200%; | ||||
|   line-height:1.2; | ||||
|   color:#b3b3cc;  | ||||
| } | ||||
|  | ||||
| .rating:not(:checked) > label:before { | ||||
|   content:'★'; | ||||
| } | ||||
|  | ||||
| /* Checked star color */ | ||||
| .rating > input:checked ~ label { | ||||
|   color: #FFBF00; | ||||
| } | ||||
|  | ||||
| .rating:not(:checked) > label:hover, | ||||
| .rating:not(:checked) > label:hover ~ label { | ||||
|   color: orangered; | ||||
| } | ||||
|  | ||||
| .rating > input:checked + label:hover, | ||||
| .rating > input:checked + label:hover ~ label, | ||||
| .rating > input:checked ~ label:hover, | ||||
| .rating > input:checked ~ label:hover ~ label, | ||||
| .rating > label:hover ~ input:checked ~ label { | ||||
|   color: orangered; | ||||
| } | ||||
|  | ||||
| .rating > label:active { | ||||
|   position:relative; | ||||
| } | ||||
							
								
								
									
										126
									
								
								static/ReviewCard.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,126 @@ | ||||
| /* main.css */ | ||||
|  | ||||
| * { | ||||
|     font-family: sans-serif; | ||||
|   } | ||||
|    | ||||
|   body { | ||||
|     height: 100%; | ||||
|     width: 100%; | ||||
|   } | ||||
|    | ||||
|   fieldset { | ||||
|     border: 2px solid rgb(214, 214, 214); | ||||
|     box-sizing: border-box; | ||||
|     display: block; | ||||
|     width: max-content; | ||||
|   } | ||||
|    | ||||
|   form button { | ||||
|     display: block; | ||||
|     margin-top: 5px; | ||||
|   } | ||||
|    | ||||
|   label[for="ingredients"] p { | ||||
|     margin: 0; | ||||
|   } | ||||
|    | ||||
|   label[for="numRatings"] { | ||||
|     margin: 10px 0 0 0; | ||||
|   } | ||||
|    | ||||
|   label[for^="rating"] { | ||||
|     padding-right: 10px; | ||||
|   } | ||||
|    | ||||
|   label:not([for^="rating"]) { | ||||
|     display: block; | ||||
|     margin-bottom: 5px; | ||||
|   } | ||||
|    | ||||
|   main { | ||||
|     column-gap: 10px; | ||||
|     display: flex; | ||||
|     flex-wrap: wrap; | ||||
|     height: auto; | ||||
|     max-width: 660px; | ||||
|     row-gap: 10px; | ||||
|     width: 100%; | ||||
|   } | ||||
|  | ||||
|   .tag-container { | ||||
|     display: flex; | ||||
|     flex-flow: row wrap; | ||||
|   } | ||||
|   .tag { | ||||
|   background-color: grey; | ||||
|   border-radius: 7px; | ||||
|   color: white; | ||||
|   padding-right: 7px; | ||||
|   padding-left: 7px; | ||||
|   margin: 3px; | ||||
| } | ||||
|  | ||||
| .tag::before { | ||||
|   display: inline-block; | ||||
|   content: 'x'; | ||||
|   height: 15px; | ||||
|   width: 15px; | ||||
|   margin-right: 4px; | ||||
|   text-align: center; | ||||
|   color: white; | ||||
|   cursor: pointer; | ||||
| } | ||||
| .tag:hover::before { | ||||
|   color: red; | ||||
| } | ||||
| .danger { | ||||
|   background-color: rgb(254, 171, 171); | ||||
|   border-color: red; | ||||
| } | ||||
|  | ||||
| .hidden,  | ||||
| .rating:not(:checked) > input { /* Hide radio circles while star rating */ | ||||
| display: none; | ||||
| } | ||||
|  | ||||
| /* Unchecked stars */ | ||||
| .rating:not(:checked) > label { | ||||
|   /* Make stars line up sideways and not vertically */ | ||||
|   float:right;  | ||||
|  | ||||
|   /* Hide label text */ | ||||
|   width:1em; | ||||
|   overflow:hidden; | ||||
|   white-space:nowrap; | ||||
|  | ||||
|   font-size:200%; | ||||
|   line-height:1.2; | ||||
|   color:#b3b3cc;  | ||||
| } | ||||
|  | ||||
| .rating:not(:checked) > label:before { | ||||
|   content:'★'; | ||||
| } | ||||
|  | ||||
| /* Checked star color */ | ||||
| .rating > input:checked ~ label { | ||||
|   color: #FFBF00; | ||||
| } | ||||
|  | ||||
| .rating:not(:checked) > label:hover, | ||||
| .rating:not(:checked) > label:hover ~ label { | ||||
|   color: orangered; | ||||
| } | ||||
|  | ||||
| .rating > input:checked + label:hover, | ||||
| .rating > input:checked + label:hover ~ label, | ||||
| .rating > input:checked ~ label:hover, | ||||
| .rating > input:checked ~ label:hover ~ label, | ||||
| .rating > label:hover ~ input:checked ~ label { | ||||
|   color: orangered; | ||||
| } | ||||
|  | ||||
| .rating > label:active { | ||||
|   position:relative; | ||||
| } | ||||