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; | ||||||
|  | } | ||||||