mirror of
https://github.com/cse110-fa22-group29/cse110-fa22-group29.git
synced 2024-12-27 09:29:10 +00:00
Merge remote-tracking branch 'origin/sprint-3' into 49-image-feature
This commit is contained in:
commit
20cdc4ce76
29
.github/workflows/prettier-linting.yml
vendored
Normal file
29
.github/workflows/prettier-linting.yml
vendored
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
name: Prettier
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
|
||||||
|
# Allows you to run this workflow manually from the Actions tab
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
# Single deploy job since we're just deploying
|
||||||
|
test:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Install apt updates
|
||||||
|
run: sudo apt -y update; sudo apt -y upgrade;
|
||||||
|
- name: Install prerequisites
|
||||||
|
uses: actions/setup-node@v3
|
||||||
|
with:
|
||||||
|
node-version: 18
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
- name: Install dependencies
|
||||||
|
run: sudo npm install
|
||||||
|
- name: Start local http server
|
||||||
|
run: sudo npm run http-server &
|
||||||
|
- name: Run tests
|
||||||
|
run: sudo npm lint-prettier
|
5
.prettierrc.json
Normal file
5
.prettierrc.json
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"printWidth": 160,
|
||||||
|
"tabWidth": 4,
|
||||||
|
"useTabs": true
|
||||||
|
}
|
@ -10,7 +10,6 @@
|
|||||||
"lint-css": "stylelint **/*.css",
|
"lint-css": "stylelint **/*.css",
|
||||||
"fix-css": "stylelint --fix **/*.css",
|
"fix-css": "stylelint --fix **/*.css",
|
||||||
"http-server": "http-server source",
|
"http-server": "http-server source",
|
||||||
"js-doc": "jsdoc -d source/docs/ -r source/",
|
|
||||||
"lint-prettier": "prettier --check .",
|
"lint-prettier": "prettier --check .",
|
||||||
"fix-prettier": "prettier --write ."
|
"fix-prettier": "prettier --write ."
|
||||||
},
|
},
|
||||||
@ -18,12 +17,11 @@
|
|||||||
"eslint": "^8.27.0",
|
"eslint": "^8.27.0",
|
||||||
"htmlhint": "1.1.4",
|
"htmlhint": "1.1.4",
|
||||||
"http-server": "",
|
"http-server": "",
|
||||||
"jsdoc": "^4.0.0",
|
|
||||||
"mocha": "10",
|
"mocha": "10",
|
||||||
"mock-local-storage": "^1.1.23",
|
"mock-local-storage": "^1.1.23",
|
||||||
|
"prettier": "2.8.0",
|
||||||
"puppeteer": "^18.2.1",
|
"puppeteer": "^18.2.1",
|
||||||
"stylelint": "14.14.1",
|
"stylelint": "14.14.1",
|
||||||
"stylelint-config-standard": "^29.0.0",
|
"stylelint-config-standard": "^29.0.0"
|
||||||
"prettier": "2.8.0"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,13 +32,13 @@
|
|||||||
<div class="journal-form" id="review-details">
|
<div class="journal-form" id="review-details">
|
||||||
<form>
|
<form>
|
||||||
<fieldset class = "meal-name">
|
<fieldset class = "meal-name">
|
||||||
<h1 id="d-mealName" style="font-family: Century Gothic;"></h1>
|
<h1 id="d-meal-name" style="font-family: Century Gothic;"></h1>
|
||||||
<h1 id="d-restaurant" style="font-family: Century Gothic; font-size: 30px;"></h1>
|
<h1 id="d-restaurant" style="font-family: Century Gothic; font-size: 30px;"></h1>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
|
||||||
<fieldset class = "meal-pics">
|
<fieldset class = "meal-pics">
|
||||||
<!-- image source -->
|
<!-- image source -->
|
||||||
<img width=40% height=40% id="d-mealImg" style="margin-left: auto; margin-right: auto; display: block;"/>
|
<img width=40% height=40% id="d-meal-img" style="margin-left: auto; margin-right: auto; display: block;"/>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
|
||||||
<fieldset class = "stars-and-comments" style="text-align: center;">
|
<fieldset class = "stars-and-comments" style="text-align: center;">
|
||||||
@ -55,9 +55,9 @@
|
|||||||
|
|
||||||
<!---Navigation Buttons-->
|
<!---Navigation Buttons-->
|
||||||
<div style="display: flex; justify-content: center;">
|
<div style="display: flex; justify-content: center;">
|
||||||
<img src="./assets/images/home_button_for_interface.png" style="margin: 20px 10px 20px 10px;" id="home-btn" onclick="window.location.assign('./index.html')" height="50" width="50"/>
|
<img src="./assets/images/home_button_for_interface.png" style="margin: 20px 10px 20px 10px;" id="home-btn" title="Home Page" onclick="window.location.assign('./index.html')" height="50" width="50"/>
|
||||||
<img src ="./assets/images/edit_button_for_interface.png" style="margin: 20px 10px 20px 10px;" id="update-btn" height="50" width="50"/>
|
<img src ="./assets/images/edit_button_for_interface.png" style="margin: 20px 10px 20px 10px;" id="update-btn" title="Edit Review" height="50" width="50"/>
|
||||||
<img src ="./assets/images/delete_icon_for_interface.png" style="margin: 20px 10px 20px 10px;" id="delete-btn" class="danger" height="50" width="50"/>
|
<img src ="./assets/images/delete_icon_for_interface.png" style="margin: 20px 10px 20px 10px;" id="delete-btn" title="Delete Review" class="danger" height="50" width="50"/>
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
|
Binary file not shown.
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 16 KiB |
Binary file not shown.
Before Width: | Height: | Size: 311 KiB After Width: | Height: | Size: 2.7 MiB |
Binary file not shown.
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 14 KiB |
@ -6,9 +6,7 @@ window.addEventListener("DOMContentLoaded", init);
|
|||||||
* Delegates the functionality for creating review cards.
|
* Delegates the functionality for creating review cards.
|
||||||
*/
|
*/
|
||||||
function init() {
|
function init() {
|
||||||
|
|
||||||
initFormHandler();
|
initFormHandler();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -104,24 +102,29 @@ function initFormHandler() {
|
|||||||
|
|
||||||
// Event listener for tag functionality
|
// Event listener for tag functionality
|
||||||
let tagAddBtn = document.getElementById("tag-add-btn");
|
let tagAddBtn = document.getElementById("tag-add-btn");
|
||||||
|
//Set used to track tags and ensure no duplicates
|
||||||
|
let tagSet = new Set();
|
||||||
tagAddBtn.addEventListener("click", ()=> {
|
tagAddBtn.addEventListener("click", ()=> {
|
||||||
let tagField = document.getElementById("tag-form");
|
let tagField = document.getElementById("tag-form");
|
||||||
|
|
||||||
// If there is a tag, it'll display the tag
|
// If there is a tag, it'll display the tag
|
||||||
if (tagField.value.length > 0) {
|
if (tagField.value.length > 0) {
|
||||||
|
let tagSetVal = tagField.value.toLowerCase();
|
||||||
|
if (!tagSet.has(tagSetVal)){
|
||||||
let tagLabel = document.createElement("label");
|
let tagLabel = document.createElement("label");
|
||||||
tagLabel.innerHTML = tagField.value;
|
tagLabel.innerHTML = tagField.value;
|
||||||
tagLabel.setAttribute("class","tag");
|
tagLabel.setAttribute("class","tag");
|
||||||
|
tagSet.add(tagField.value.toLowerCase());
|
||||||
// Allows for user to delete the tag
|
|
||||||
tagLabel.addEventListener("click",()=> {
|
tagLabel.addEventListener("click",()=> {
|
||||||
tagContainer.removeChild(tagLabel);
|
tagContainer.removeChild(tagLabel);
|
||||||
|
tagSet.delete(tagField.value.toLowerCase());
|
||||||
});
|
});
|
||||||
|
|
||||||
// Adds the tag
|
|
||||||
tagContainer.append(tagLabel);
|
tagContainer.append(tagLabel);
|
||||||
|
} else {
|
||||||
|
window.alert("No duplicate tags allowed");
|
||||||
|
}
|
||||||
tagField.value = "";
|
tagField.value = "";
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -31,18 +31,15 @@ class ReviewCard extends HTMLElement {
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
border: 2px solid rgb(31, 41, 32);
|
border: 2px solid rgb(31, 41, 32);
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
display: grid;
|
|
||||||
grid-template-rows: 118px 56px 14px 18px 15px 36px;
|
|
||||||
height: auto;
|
height: auto;
|
||||||
row-gap: 5px;
|
row-gap: 5px;
|
||||||
padding: 0 16px 16px 16px;
|
padding: 0 16px 16px 16px;
|
||||||
width: 178px;
|
width: 200px;
|
||||||
margin: 8px 8px 8px 8px;
|
margin: 8px 8px 8px 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
div.rating {
|
div.rating {
|
||||||
align-items: center;
|
align-items: center;
|
||||||
column-gap: 5px;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -50,30 +47,30 @@ class ReviewCard extends HTMLElement {
|
|||||||
height: auto;
|
height: auto;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
object-fit: scale-down;
|
object-fit: scale-down;
|
||||||
width: 78px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
article>img {
|
article>img {
|
||||||
border-top-left-radius: 6px;
|
border-top-left-radius: 6px;
|
||||||
border-top-right-radius: 6px;
|
border-top-right-radius: 6px;
|
||||||
height: 119px;
|
height: 120px;
|
||||||
object-fit: cover;
|
object-fit: cover;
|
||||||
margin-left: -16px;
|
margin-left: -16px;
|
||||||
|
margin-right: -16px;
|
||||||
width: calc(100% + 32px);
|
width: calc(100% + 32px);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.meal-name-div {
|
||||||
|
height: 54px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
label.restaurant-name {
|
label.restaurant-name {
|
||||||
color: black !important;
|
color: black !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
label.meal-name {
|
label.meal-name {
|
||||||
display: -webkit-box;
|
font-size: 24px;
|
||||||
font-size: 16px;
|
|
||||||
height: 36px;
|
height: 36px;
|
||||||
line-height: 18px;
|
|
||||||
overflow: hidden;
|
|
||||||
-webkit-line-clamp: 2;
|
|
||||||
-webkit-box-orient: vertical;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
label:not(.meal-name),
|
label:not(.meal-name),
|
||||||
@ -83,20 +80,27 @@ class ReviewCard extends HTMLElement {
|
|||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tag-container {
|
.tag-container-div {
|
||||||
margin-top: 20px;
|
margin-top: 20px;
|
||||||
|
height: 100px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tag-container {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-flow: row wrap;
|
flex-flow: row wrap;
|
||||||
|
height: fit-content;
|
||||||
}
|
}
|
||||||
|
|
||||||
.a-tag {
|
.a-tag {
|
||||||
background-color:#94da97;
|
background-color:#94da97;
|
||||||
border-radius: 7px;
|
border-radius: 6px;
|
||||||
color: #94da97;
|
color: #94da97;
|
||||||
padding-right: 7px;
|
padding: 0px 6px 2px 6px;
|
||||||
padding-left: 7px;
|
margin: 2px 2px 2px 2px;
|
||||||
margin: 3px;
|
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
|
overflow: hidden;
|
||||||
|
height: 14px;
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
articleEl.append(styleEl);
|
articleEl.append(styleEl);
|
||||||
@ -149,15 +153,18 @@ class ReviewCard extends HTMLElement {
|
|||||||
mealImg.setAttribute("alt","Meal Photo Corrupted");
|
mealImg.setAttribute("alt","Meal Photo Corrupted");
|
||||||
mealImg.setAttribute("src",data["mealImg"]);
|
mealImg.setAttribute("src",data["mealImg"]);
|
||||||
mealImg.addEventListener("error", function(e) {
|
mealImg.addEventListener("error", function(e) {
|
||||||
mealImg.setAttribute("src", "./assets/images/plate_with_cutlery.png");
|
mealImg.setAttribute("src", "./assets/images/default_plate.png");
|
||||||
e.onerror = null;
|
e.onerror = null;
|
||||||
});
|
});
|
||||||
|
|
||||||
// Meal name setup
|
//meal name setup
|
||||||
|
let meallabelDiv = document.createElement("div");
|
||||||
|
meallabelDiv.setAttribute("class", "meal-name-div");
|
||||||
let mealLabel = document.createElement("label");
|
let mealLabel = document.createElement("label");
|
||||||
mealLabel.setAttribute("id", "a-mealName");
|
mealLabel.setAttribute("id", "a-mealName");
|
||||||
mealLabel.setAttribute("class","meal-name");
|
mealLabel.setAttribute("class","meal-name");
|
||||||
mealLabel.innerHTML = data["mealName"];
|
mealLabel.innerHTML = data["mealName"];
|
||||||
|
meallabelDiv.append(mealLabel);
|
||||||
|
|
||||||
// Restaurant name setup
|
// Restaurant name setup
|
||||||
let restaurantLabel = document.createElement("label");
|
let restaurantLabel = document.createElement("label");
|
||||||
@ -181,7 +188,9 @@ class ReviewCard extends HTMLElement {
|
|||||||
starsImg.setAttribute("num", data["rating"]);
|
starsImg.setAttribute("num", data["rating"]);
|
||||||
ratingDiv.append(starsImg);
|
ratingDiv.append(starsImg);
|
||||||
|
|
||||||
// Tags setup
|
//added tags
|
||||||
|
let tagContainerDiv = document.createElement("div");
|
||||||
|
tagContainerDiv.setAttribute("class", "tag-container-div");
|
||||||
let tagContainer = document.createElement("div");
|
let tagContainer = document.createElement("div");
|
||||||
tagContainer.setAttribute("class", "tag-container");
|
tagContainer.setAttribute("class", "tag-container");
|
||||||
tagContainer.setAttribute("id", "a-tags");
|
tagContainer.setAttribute("id", "a-tags");
|
||||||
@ -196,13 +205,14 @@ class ReviewCard extends HTMLElement {
|
|||||||
tagContainer.append(newTag);
|
tagContainer.append(newTag);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
tagContainerDiv.append(tagContainer);
|
||||||
|
|
||||||
// Setting all the data to the review card
|
// Setting all the data to the review card
|
||||||
articleEl.append(mealImg);
|
articleEl.append(mealImg);
|
||||||
articleEl.append(mealLabel);
|
articleEl.append(meallabelDiv);
|
||||||
articleEl.append(restaurantLabel);
|
articleEl.append(restaurantLabel);
|
||||||
articleEl.append(ratingDiv);
|
articleEl.append(ratingDiv);
|
||||||
articleEl.append(tagContainer);
|
articleEl.append(tagContainerDiv);
|
||||||
articleEl.append(comments);
|
articleEl.append(comments);
|
||||||
|
|
||||||
|
|
||||||
|
@ -13,20 +13,23 @@ function init(){
|
|||||||
setupUpdate();
|
setupUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Populates the relevant data to the details from local storage review
|
||||||
|
*/
|
||||||
function setupInfo(){
|
function setupInfo(){
|
||||||
let currID = JSON.parse(sessionStorage.getItem("currID"));
|
let currID = JSON.parse(sessionStorage.getItem("currID"));
|
||||||
let currReview = getReviewFromStorage(currID);
|
let currReview = getReviewFromStorage(currID);
|
||||||
|
|
||||||
//meal image
|
//meal image
|
||||||
let mealImg = document.getElementById("d-mealImg");
|
let mealImg = document.getElementById("d-meal-img");
|
||||||
mealImg.setAttribute("src",currReview["mealImg"]);
|
mealImg.setAttribute("src",currReview["mealImg"]);
|
||||||
mealImg.addEventListener("error", function(e) {
|
mealImg.addEventListener("error", function(e) {
|
||||||
mealImg.setAttribute("src", "./assets/images/plate_with_cutlery.png");
|
mealImg.setAttribute("src", "./assets/images/default_plate.png");
|
||||||
e.onerror = null;
|
e.onerror = null;
|
||||||
});
|
});
|
||||||
|
|
||||||
//meal name
|
//meal name
|
||||||
let mealLabel = document.getElementById("d-mealName");
|
let mealLabel = document.getElementById("d-meal-name");
|
||||||
mealLabel.innerHTML = currReview["mealName"];
|
mealLabel.innerHTML = currReview["mealName"];
|
||||||
|
|
||||||
//restaurant name
|
//restaurant name
|
||||||
@ -55,7 +58,7 @@ function setupInfo(){
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets up delete button to delete reveiw from storage and switch to homepage.
|
* Sets up delete button to delete review from storage and switch to homepage
|
||||||
*/
|
*/
|
||||||
function setupDelete(){
|
function setupDelete(){
|
||||||
let deleteBtn = document.getElementById("delete-btn");
|
let deleteBtn = document.getElementById("delete-btn");
|
||||||
@ -70,7 +73,7 @@ function setupDelete(){
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets up update button to reveal form and update info in storage and the current page.
|
* Sets up update button to reveal form and update info in storage and the current page
|
||||||
*/
|
*/
|
||||||
function setupUpdate(){
|
function setupUpdate(){
|
||||||
let updateBtn = document.getElementById("update-btn");
|
let updateBtn = document.getElementById("update-btn");
|
||||||
@ -92,16 +95,22 @@ function setupUpdate(){
|
|||||||
document.getElementById("s" + `${currReview["rating"]}`).checked = true;
|
document.getElementById("s" + `${currReview["rating"]}`).checked = true;
|
||||||
document.getElementById("restaurant").defaultValue = currReview["restaurant"];
|
document.getElementById("restaurant").defaultValue = currReview["restaurant"];
|
||||||
|
|
||||||
|
//Set used to track tags and ensure no duplicates
|
||||||
|
let tagSet = new Set();
|
||||||
|
|
||||||
if(currReview["tags"]){
|
if(currReview["tags"]){
|
||||||
while (tagContainer.firstChild) {
|
while (tagContainer.firstChild) {
|
||||||
tagContainer.removeChild(tagContainer.firstChild);
|
tagContainer.removeChild(tagContainer.firstChild);
|
||||||
}
|
}
|
||||||
|
let tagSetVal = currReview["tags"][i].toLowerCase()
|
||||||
for (let i = 0; i < currReview["tags"].length; i++) {
|
for (let i = 0; i < currReview["tags"].length; i++) {
|
||||||
|
tagSet.add(tagSetVal);
|
||||||
let newTag = document.createElement("label");
|
let newTag = document.createElement("label");
|
||||||
newTag.setAttribute("class","tag");
|
newTag.setAttribute("class","tag");
|
||||||
newTag.innerHTML = currReview["tags"][i];
|
newTag.innerHTML = currReview["tags"][i];
|
||||||
newTag.addEventListener("click",()=> {
|
newTag.addEventListener("click",()=> {
|
||||||
tagContainer.removeChild(newTag);
|
tagContainer.removeChild(newTag);
|
||||||
|
tagSet.delete(tagSetVal);
|
||||||
});
|
});
|
||||||
tagContainer.append(newTag);
|
tagContainer.append(newTag);
|
||||||
}
|
}
|
||||||
@ -148,11 +157,13 @@ function setupUpdate(){
|
|||||||
|
|
||||||
//Take formdata values as newData when submit
|
//Take formdata values as newData when submit
|
||||||
form.addEventListener("submit", function(){
|
form.addEventListener("submit", function(){
|
||||||
//We create reviewCard datea, replace it in in storage, and update tags
|
/*
|
||||||
|
* User submits the form for their review.
|
||||||
|
* We create reviewCard data, replace in storage, and update tags
|
||||||
|
*/
|
||||||
let formData = new FormData(form);
|
let formData = new FormData(form);
|
||||||
let newData = {};
|
let newData = {};
|
||||||
|
//iterate through formData and add to newData
|
||||||
// Iterate through formData an add to newData
|
|
||||||
for (let [key, value] of formData) {
|
for (let [key, value] of formData) {
|
||||||
console.log(`${key}`);
|
console.log(`${key}`);
|
||||||
console.log(`${value}`);
|
console.log(`${value}`);
|
||||||
@ -183,19 +194,26 @@ function setupUpdate(){
|
|||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Adding tag to form functionality
|
//adding tag to form functionality
|
||||||
let tagAddBtn = document.getElementById("tag-add-btn");
|
let tagAddBtn = document.getElementById("tag-add-btn");
|
||||||
tagAddBtn.addEventListener("click", ()=> {
|
tagAddBtn.addEventListener("click", ()=> {
|
||||||
let tagField = document.getElementById("tag-form");
|
let tagField = document.getElementById("tag-form");
|
||||||
if (tagField.value.length > 0) {
|
if (tagField.value.length > 0) {
|
||||||
|
let tagSetVal = tagField.value.toLowerCase();
|
||||||
|
if (!tagSet.has(tagSetVal)){
|
||||||
let tagLabel = document.createElement("label");
|
let tagLabel = document.createElement("label");
|
||||||
tagLabel.innerHTML = tagField.value;
|
tagLabel.innerHTML = tagField.value;
|
||||||
tagLabel.setAttribute("class","tag");
|
tagLabel.setAttribute("class","tag");
|
||||||
|
tagSet.add(tagSetVal);
|
||||||
tagLabel.addEventListener("click",()=> {
|
tagLabel.addEventListener("click",()=> {
|
||||||
tagContainer.removeChild(tagLabel);
|
tagContainer.removeChild(tagLabel);
|
||||||
|
tagSet.delete(tagSetVal);
|
||||||
});
|
});
|
||||||
|
|
||||||
tagContainer.append(tagLabel);
|
tagContainer.append(tagLabel);
|
||||||
|
} else {
|
||||||
|
window.alert("No duplicate tags allowed");
|
||||||
|
}
|
||||||
tagField.value = "";
|
tagField.value = "";
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -11,6 +11,9 @@ export function newReviewToStorage(review){
|
|||||||
// set the review entry to the review object
|
// set the review entry to the review object
|
||||||
localStorage.setItem(`review${nextReviewId}`, JSON.stringify(review));
|
localStorage.setItem(`review${nextReviewId}`, JSON.stringify(review));
|
||||||
|
|
||||||
|
// adding to the tag keys
|
||||||
|
addTagsToStorage(nextReviewId, review["tags"]);
|
||||||
|
|
||||||
//updating our activeIDS list
|
//updating our activeIDS list
|
||||||
let tempIdArr = JSON.parse(localStorage.getItem("activeIDS"));
|
let tempIdArr = JSON.parse(localStorage.getItem("activeIDS"));
|
||||||
tempIdArr.push(nextReviewId);
|
tempIdArr.push(nextReviewId);
|
||||||
@ -37,6 +40,14 @@ export function getReviewFromStorage(ID){
|
|||||||
* @param {Object} review to store
|
* @param {Object} review to store
|
||||||
*/
|
*/
|
||||||
export function updateReviewToStorage(ID, review){
|
export function updateReviewToStorage(ID, review){
|
||||||
|
let oldReview = JSON.parse(localStorage.getItem(`review${ID}`));
|
||||||
|
|
||||||
|
//Get diff of tags and update storage
|
||||||
|
let deletedTags = oldReview["tags"].filter(x => !review["tags"].includes(x));
|
||||||
|
let addedTags = review["tags"].filter(x => !oldReview["tags"].includes(x));
|
||||||
|
deleteTagsFromStorage(ID, deletedTags);
|
||||||
|
addTagsToStorage(ID, addedTags);
|
||||||
|
|
||||||
// set the review entry with ID to the review object
|
// set the review entry with ID to the review object
|
||||||
localStorage.setItem(`review${ID}`, JSON.stringify(review));
|
localStorage.setItem(`review${ID}`, JSON.stringify(review));
|
||||||
}
|
}
|
||||||
@ -52,6 +63,8 @@ export function deleteReviewFromStorage(ID){
|
|||||||
if (activeIDS[i] == ID) {
|
if (activeIDS[i] == ID) {
|
||||||
activeIDS.splice(i,1);
|
activeIDS.splice(i,1);
|
||||||
localStorage.setItem("activeIDS", JSON.stringify(activeIDS));
|
localStorage.setItem("activeIDS", JSON.stringify(activeIDS));
|
||||||
|
let currReview = JSON.parse(localStorage.getItem(`review${ID}`));
|
||||||
|
deleteTagsFromStorage(ID, currReview["tags"]);
|
||||||
localStorage.removeItem(`review${ID}`);
|
localStorage.removeItem(`review${ID}`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -60,6 +73,65 @@ export function deleteReviewFromStorage(ID){
|
|||||||
console.error(`could not find review${ID} in localStorage`);
|
console.error(`could not find review${ID} in localStorage`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete ID from the specified tags' storage
|
||||||
|
* @param {string} ID to delete from lists
|
||||||
|
* @param {string[]} deletedTags to modify storage of
|
||||||
|
*/
|
||||||
|
function deleteTagsFromStorage(ID, deletedTags) {
|
||||||
|
for(let i in deletedTags){
|
||||||
|
//get local storage of each tag and remove id from tag list
|
||||||
|
let tagName = "!"+ deletedTags[i].toLowerCase();
|
||||||
|
let tagArr = JSON.parse(localStorage.getItem(tagName));
|
||||||
|
for(let j in tagArr){
|
||||||
|
if(tagArr[j] == ID){
|
||||||
|
tagArr.splice(j,1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(tagArr.length != 0){
|
||||||
|
localStorage.setItem(tagName, JSON.stringify(tagArr));
|
||||||
|
} else {
|
||||||
|
localStorage.removeItem(tagName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add ID from the specified tags' storage
|
||||||
|
* @param {string} ID to add to lists
|
||||||
|
* @param {string[]} addedTags to modify storage of
|
||||||
|
*/
|
||||||
|
function addTagsToStorage(ID, addedTags) {
|
||||||
|
for(let i in addedTags){
|
||||||
|
let tagName = "!" + addedTags[i].toLowerCase();
|
||||||
|
let tagArr = JSON.parse(localStorage.getItem(tagName));
|
||||||
|
if(!tagArr){
|
||||||
|
tagArr = [];
|
||||||
|
}
|
||||||
|
tagArr.push(ID);
|
||||||
|
localStorage.setItem(tagName, JSON.stringify(tagArr));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the top n reviews by ID. If there are less than n reviews, returns the most possible.
|
||||||
|
* @param {number} n number of reviews to return
|
||||||
|
* @returns {Object} list of n reviews that are the top rated
|
||||||
|
*/
|
||||||
|
export function getTopReviewsFromStorage(n) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns all reviews which contain the same tag specified.
|
||||||
|
* @param {string} tag to filter by
|
||||||
|
* @returns {Object} list of reviews that all contain the specified tag
|
||||||
|
*/
|
||||||
|
export function getReviewsByTag(tag) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// legacy function
|
// legacy function
|
||||||
export function getAllReviewsFromStorage() {
|
export function getAllReviewsFromStorage() {
|
||||||
if (!(localStorage.getItem("activeIDS"))) {
|
if (!(localStorage.getItem("activeIDS"))) {
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import {strict as assert} from "node:assert";
|
import {strict as assert} from "node:assert";
|
||||||
import {describe, it, before, after} from "mocha";
|
import {describe, it, before, after} from "mocha";
|
||||||
import {newReviewToStorage, getReviewFromStorage, updateReviewToStorage, deleteReviewFromStorage, getAllReviewsFromStorage} from "./localStorage.js";
|
import {newReviewToStorage, getReviewFromStorage, updateReviewToStorage, deleteReviewFromStorage, getAllReviewsFromStorage, getTopReviewsFromStorage, getReviewsByTag} from "./localStorage.js";
|
||||||
|
|
||||||
describe("test app localStorage interaction", () => {
|
describe("test CRUD localStorage interaction", () => {
|
||||||
|
|
||||||
before(() => {
|
before(() => {
|
||||||
localStorage.clear();
|
localStorage.clear();
|
||||||
@ -47,9 +47,7 @@ describe("test app localStorage interaction", () => {
|
|||||||
"tags": [`tag ${3*i}`, `tag ${3*i + 1}`, `tag ${3*i + 2}`]
|
"tags": [`tag ${3*i}`, `tag ${3*i + 1}`, `tag ${3*i + 2}`]
|
||||||
};
|
};
|
||||||
|
|
||||||
newReviewToStorage(new_review);
|
new_review.reviewID = newReviewToStorage(new_review);
|
||||||
|
|
||||||
new_review.reviewID = i;
|
|
||||||
reviews.push(new_review);
|
reviews.push(new_review);
|
||||||
|
|
||||||
assert.deepEqual(getAllReviewsFromStorage(), reviews);
|
assert.deepEqual(getAllReviewsFromStorage(), reviews);
|
||||||
@ -99,5 +97,204 @@ describe("test app localStorage interaction", () => {
|
|||||||
}
|
}
|
||||||
}).timeout(5000);
|
}).timeout(5000);
|
||||||
|
|
||||||
|
it("test localStorage state after all deletes", () => {
|
||||||
|
assert.deepEqual(getAllReviewsFromStorage(), []);
|
||||||
|
});
|
||||||
|
|
||||||
|
after(() => {});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("test sort/filter localStorage interaction", () => {
|
||||||
|
|
||||||
|
before(() => {
|
||||||
|
localStorage.clear();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("add sample data for sort and filter", () => {
|
||||||
|
for(let i = 0; i < 100; i++){
|
||||||
|
let review = {
|
||||||
|
"imgSrc": `sample src ${i}`,
|
||||||
|
"mealName": `sample name ${i}`,
|
||||||
|
"restaurant": `sample restaurant ${i}`,
|
||||||
|
"rating": i,
|
||||||
|
"tags": [`tag ${i%3}`, `tag ${i < 50}`, "tag x"]
|
||||||
|
};
|
||||||
|
|
||||||
|
newReviewToStorage(review);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
it("test getTopReviewsFromStorage end behavior after create", () =>{
|
||||||
|
for(let i = 0; i <= 100; i++){
|
||||||
|
let top_reviews = getTopReviewsFromStorage(i);
|
||||||
|
for(let j = 0; j < i; j++){
|
||||||
|
assert.strictEqual(top_reviews[j].rating, 99 - j);
|
||||||
|
assert.strictEqual(top_reviews[j].reviewID, 99 - j);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
it("test getReviewsByTag end behavior after create", () => {
|
||||||
|
let specific_tagged_reviews = [];
|
||||||
|
|
||||||
|
specific_tagged_reviews = getReviewsByTag("tag 0");
|
||||||
|
assert.strictEqual(specific_tagged_reviews.length, 34);
|
||||||
|
for(let i = 0; i < specific_tagged_reviews.length; i++){
|
||||||
|
assert.strictEqual(specific_tagged_reviews[i].tags.includes("tag 0"), true);
|
||||||
|
assert.strictEqual(specific_tagged_reviews[i].reviewID % 3, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
specific_tagged_reviews = getReviewsByTag("tag 1");
|
||||||
|
assert.strictEqual(specific_tagged_reviews.length, 33);
|
||||||
|
for(let i = 0; i < specific_tagged_reviews.length; i++){
|
||||||
|
assert.strictEqual(specific_tagged_reviews[i].tags.includes("tag 1"), true);
|
||||||
|
assert.strictEqual(specific_tagged_reviews[i].reviewID % 3, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
specific_tagged_reviews = getReviewsByTag("tag 2");
|
||||||
|
assert.strictEqual(specific_tagged_reviews.length, 33);
|
||||||
|
for(let i = 0; i < specific_tagged_reviews.length; i++){
|
||||||
|
assert.strictEqual(specific_tagged_reviews[i].tags.includes("tag 2"), true);
|
||||||
|
assert.strictEqual(specific_tagged_reviews[i].reviewID % 3, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
specific_tagged_reviews = getReviewsByTag("tag true");
|
||||||
|
assert.strictEqual(specific_tagged_reviews.length, 50);
|
||||||
|
for(let i = 0; i < specific_tagged_reviews.length; i++){
|
||||||
|
assert.strictEqual(specific_tagged_reviews[i].tags.includes("tag true"), true);
|
||||||
|
assert.strictEqual(specific_tagged_reviews[i].reviewID < 50, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
specific_tagged_reviews = getReviewsByTag("tag false");
|
||||||
|
assert.strictEqual(specific_tagged_reviews.length, 50);
|
||||||
|
for(let i = 0; i < specific_tagged_reviews.length; i++){
|
||||||
|
assert.strictEqual(specific_tagged_reviews[i].tags.includes("tag false"), true);
|
||||||
|
assert.strictEqual(specific_tagged_reviews[i].reviewID >= 50, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
specific_tagged_reviews = getReviewsByTag("tag x");
|
||||||
|
assert.strictEqual(specific_tagged_reviews.length, 100);
|
||||||
|
|
||||||
|
specific_tagged_reviews = getReviewsByTag("tag y");
|
||||||
|
assert.deepEqual(specific_tagged_reviews, []);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("update sample data for sort and filter", () => {
|
||||||
|
for(let i = 0; i < 100; i++){
|
||||||
|
let new_review = {
|
||||||
|
"imgSrc": `sample src ${i}`,
|
||||||
|
"mealName": `sample name ${i}`,
|
||||||
|
"restaurant": `sample restaurant ${i}`,
|
||||||
|
"rating": 99-i,
|
||||||
|
"tags": [`tag ${i%4}`, `tag ${i < 37}`, "tag y"]
|
||||||
|
};
|
||||||
|
|
||||||
|
updateReviewToStorage(i, new_review);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
it("test getTopReviewsFromStorage end behavior after create", () =>{
|
||||||
|
for(let i = 0; i <= 100; i++){
|
||||||
|
let top_reviews = getTopReviewsFromStorage(i);
|
||||||
|
for(let j = 0; j < i; j++){
|
||||||
|
assert.strictEqual(top_reviews[j].rating, 99 - j);
|
||||||
|
assert.strictEqual(top_reviews[j].reviewID, j);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
it("test getReviewsByTag end behavior after update", () => {
|
||||||
|
let specific_tagged_reviews = [];
|
||||||
|
|
||||||
|
specific_tagged_reviews = getReviewsByTag("tag 0");
|
||||||
|
assert.strictEqual(specific_tagged_reviews.length, 25);
|
||||||
|
for(let i = 0; i < specific_tagged_reviews.length; i++){
|
||||||
|
assert.strictEqual(specific_tagged_reviews[i].tags.includes("tag 0"), true);
|
||||||
|
assert.strictEqual(specific_tagged_reviews[i].reviewID % 4, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
specific_tagged_reviews = getReviewsByTag("tag 1");
|
||||||
|
assert.strictEqual(specific_tagged_reviews.length, 25);
|
||||||
|
for(let i = 0; i < specific_tagged_reviews.length; i++){
|
||||||
|
assert.strictEqual(specific_tagged_reviews[i].tags.includes("tag 1"), true);
|
||||||
|
assert.strictEqual(specific_tagged_reviews[i].reviewID % 4, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
specific_tagged_reviews = getReviewsByTag("tag 2");
|
||||||
|
assert.strictEqual(specific_tagged_reviews.length, 25);
|
||||||
|
for(let i = 0; i < specific_tagged_reviews.length; i++){
|
||||||
|
assert.strictEqual(specific_tagged_reviews[i].tags.includes("tag 2"), true);
|
||||||
|
assert.strictEqual(specific_tagged_reviews[i].reviewID % 4, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
specific_tagged_reviews = getReviewsByTag("tag 3");
|
||||||
|
assert.strictEqual(specific_tagged_reviews.length, 25);
|
||||||
|
for(let i = 0; i < specific_tagged_reviews.length; i++){
|
||||||
|
assert.strictEqual(specific_tagged_reviews[i].tags.includes("tag 3"), true);
|
||||||
|
assert.strictEqual(specific_tagged_reviews[i].reviewID % 4, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
specific_tagged_reviews = getReviewsByTag("tag true");
|
||||||
|
assert.strictEqual(specific_tagged_reviews.length, 37);
|
||||||
|
for(let i = 0; i < specific_tagged_reviews.length; i++){
|
||||||
|
assert.strictEqual(specific_tagged_reviews[i].tags.includes("tag true"), true);
|
||||||
|
assert.strictEqual(specific_tagged_reviews[i].reviewID < 37, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
specific_tagged_reviews = getReviewsByTag("tag false");
|
||||||
|
assert.strictEqual(specific_tagged_reviews.length, 63);
|
||||||
|
for(let i = 0; i < specific_tagged_reviews.length; i++){
|
||||||
|
assert.strictEqual(specific_tagged_reviews[i].tags.includes("tag false"), true);
|
||||||
|
assert.strictEqual(specific_tagged_reviews[i].reviewID >= 37, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
specific_tagged_reviews = getReviewsByTag("tag x");
|
||||||
|
assert.deepEqual(specific_tagged_reviews, []);
|
||||||
|
|
||||||
|
specific_tagged_reviews = getReviewsByTag("tag y");
|
||||||
|
assert.strictEqual(specific_tagged_reviews.length, 100);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("delete all sample data for sort and filter", () => {
|
||||||
|
for(let i = 0; i < 100; i++){
|
||||||
|
deleteReviewFromStorage(i);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
it("test getTopReviewsFromStorage end behavior after delete", () =>{
|
||||||
|
for(let i = 0; i <= 100; i++){
|
||||||
|
let top_reviews = getTopReviewsFromStorage(i);
|
||||||
|
assert.deepEqual(top_reviews, []);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
it("test getReviewsByTag end behavior after delete", () => {
|
||||||
|
let specific_tagged_reviews = [];
|
||||||
|
|
||||||
|
specific_tagged_reviews = getReviewsByTag("tag 0");
|
||||||
|
assert.deepEqual(specific_tagged_reviews, []);
|
||||||
|
|
||||||
|
specific_tagged_reviews = getReviewsByTag("tag 1");
|
||||||
|
assert.deepEqual(specific_tagged_reviews, []);
|
||||||
|
|
||||||
|
specific_tagged_reviews = getReviewsByTag("tag 2");
|
||||||
|
assert.deepEqual(specific_tagged_reviews, []);
|
||||||
|
|
||||||
|
specific_tagged_reviews = getReviewsByTag("tag 3");
|
||||||
|
assert.deepEqual(specific_tagged_reviews, []);
|
||||||
|
|
||||||
|
specific_tagged_reviews = getReviewsByTag("tag true");
|
||||||
|
assert.deepEqual(specific_tagged_reviews, []);
|
||||||
|
|
||||||
|
specific_tagged_reviews = getReviewsByTag("tag false");
|
||||||
|
assert.deepEqual(specific_tagged_reviews, []);
|
||||||
|
|
||||||
|
specific_tagged_reviews = getReviewsByTag("tag x");
|
||||||
|
assert.deepEqual(specific_tagged_reviews, []);
|
||||||
|
|
||||||
|
specific_tagged_reviews = getReviewsByTag("tag y");
|
||||||
|
assert.deepEqual(specific_tagged_reviews, []);
|
||||||
|
});
|
||||||
|
|
||||||
after(() => {});
|
after(() => {});
|
||||||
});
|
});
|
@ -1,7 +1,6 @@
|
|||||||
import {strict as assert} from "node:assert";
|
import {strict as assert} from "node:assert";
|
||||||
import {describe, it, before, after} from "mocha";
|
import {describe, it, before, after} from "mocha";
|
||||||
import puppeteer from "puppeteer-core";
|
import puppeteer from "puppeteer-core";
|
||||||
import {exit} from "node:process";
|
|
||||||
import {setReviewForm, checkCorrectness} from "./appTestHelpers.js";
|
import {setReviewForm, checkCorrectness} from "./appTestHelpers.js";
|
||||||
|
|
||||||
describe("test App end to end", async () => {
|
describe("test App end to end", async () => {
|
||||||
@ -27,7 +26,6 @@ describe("test App end to end", async () => {
|
|||||||
}
|
}
|
||||||
catch (error) {
|
catch (error) {
|
||||||
await console.log("❌ failed to connect to localhost webserver on port 8080");
|
await console.log("❌ failed to connect to localhost webserver on port 8080");
|
||||||
await exit(1);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -65,7 +63,7 @@ describe("test App end to end", async () => {
|
|||||||
it("check details page", async () => {
|
it("check details page", async () => {
|
||||||
// check the details page for correctness
|
// check the details page for correctness
|
||||||
let expected = {
|
let expected = {
|
||||||
imgSrc: "http://localhost:8080/assets/images/plate_with_cutlery.png",
|
imgSrc: "http://localhost:8080/assets/images/default_plate.png",
|
||||||
mealName: "sample name",
|
mealName: "sample name",
|
||||||
comments: "sample comment",
|
comments: "sample comment",
|
||||||
restaurant: "sample restaurant",
|
restaurant: "sample restaurant",
|
||||||
@ -86,7 +84,7 @@ describe("test App end to end", async () => {
|
|||||||
let shadowRoot = await review_card.getProperty("shadowRoot");
|
let shadowRoot = await review_card.getProperty("shadowRoot");
|
||||||
|
|
||||||
let expected = {
|
let expected = {
|
||||||
imgSrc: "http://localhost:8080/assets/images/plate_with_cutlery.png",
|
imgSrc: "http://localhost:8080/assets/images/default_plate.png",
|
||||||
mealName: "sample name",
|
mealName: "sample name",
|
||||||
comments: "sample comment",
|
comments: "sample comment",
|
||||||
restaurant: "sample restaurant",
|
restaurant: "sample restaurant",
|
||||||
@ -111,7 +109,7 @@ describe("test App end to end", async () => {
|
|||||||
|
|
||||||
// check the details page for correctness
|
// check the details page for correctness
|
||||||
let expected = {
|
let expected = {
|
||||||
imgSrc: "http://localhost:8080/assets/images/plate_with_cutlery.png",
|
imgSrc: "http://localhost:8080/assets/images/default_plate.png",
|
||||||
mealName: "sample name",
|
mealName: "sample name",
|
||||||
comments: "sample comment",
|
comments: "sample comment",
|
||||||
restaurant: "sample restaurant",
|
restaurant: "sample restaurant",
|
||||||
@ -133,7 +131,7 @@ describe("test App end to end", async () => {
|
|||||||
|
|
||||||
// check the details page for correctness
|
// check the details page for correctness
|
||||||
let expected = {
|
let expected = {
|
||||||
imgSrc: "http://localhost:8080/assets/images/plate_with_cutlery.png",
|
imgSrc: "http://localhost:8080/assets/images/default_plate.png",
|
||||||
mealName: "sample name",
|
mealName: "sample name",
|
||||||
comments: "sample comment",
|
comments: "sample comment",
|
||||||
restaurant: "sample restaurant",
|
restaurant: "sample restaurant",
|
||||||
@ -176,7 +174,7 @@ describe("test App end to end", async () => {
|
|||||||
it("check details page", async () => {
|
it("check details page", async () => {
|
||||||
// check the details page for correctness
|
// check the details page for correctness
|
||||||
let expected = {
|
let expected = {
|
||||||
imgSrc: "http://localhost:8080/assets/images/plate_with_cutlery.png",
|
imgSrc: "http://localhost:8080/assets/images/default_plate.png",
|
||||||
mealName: "updated name",
|
mealName: "updated name",
|
||||||
comments: "updated comment",
|
comments: "updated comment",
|
||||||
restaurant: "updated restaurant",
|
restaurant: "updated restaurant",
|
||||||
@ -198,7 +196,7 @@ describe("test App end to end", async () => {
|
|||||||
|
|
||||||
// check the details page for correctness
|
// check the details page for correctness
|
||||||
let expected = {
|
let expected = {
|
||||||
imgSrc: "http://localhost:8080/assets/images/plate_with_cutlery.png",
|
imgSrc: "http://localhost:8080/assets/images/default_plate.png",
|
||||||
mealName: "updated name",
|
mealName: "updated name",
|
||||||
comments: "updated comment",
|
comments: "updated comment",
|
||||||
restaurant: "updated restaurant",
|
restaurant: "updated restaurant",
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
@ -39,7 +38,7 @@
|
|||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<div class="center-display">
|
<div class="center-display">
|
||||||
<img src ="./assets/images/Grouppink.png" alt="CREATE" style="opacity: 100%;" id="create-btn" onclick="window.location.assign('./CreatePage.html')"/>
|
<img src ="./assets/images/Grouppink.png" alt="CREATE" style="opacity: 100%;" id="create-btn" title="Add an entry!" onclick="window.location.assign('./CreatePage.html')"/>
|
||||||
<h2 id="recent-reviews-text"> Recent Reviews </h2>
|
<h2 id="recent-reviews-text"> Recent Reviews </h2>
|
||||||
<img src ="./assets/images/Grouppink.png" style="opacity:0;"/>
|
<img src ="./assets/images/Grouppink.png" style="opacity:0;"/>
|
||||||
|
|
||||||
|
@ -19,6 +19,11 @@
|
|||||||
background-color: #f7dfd5;
|
background-color: #f7dfd5;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#d-meal-img {
|
||||||
|
border: 2px solid rgb(31 41 32);
|
||||||
|
border-radius: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
fieldset {
|
fieldset {
|
||||||
border: none;
|
border: none;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user