From c33384eafe43583b205761bbbcbb1a5ce7b0a927 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Aaron=20D=C3=B6tsch?= <aaron@fsmpi.rwth-aachen.de>
Date: Thu, 25 May 2023 19:26:43 +0200
Subject: [PATCH] Add item visibility column

Until now you could only distinguish between available and non-available items. The non-available
items do not even get sent to the client, it doesn't know about their existance. However it might
be nice to have items that are not shown on the front end but are still known to the front end.
With this new boolean it is possible to do that.
---
 .../20230525163656_add_item_visibility/migration.sql      | 2 ++
 prisma/schema.prisma                                      | 1 +
 src/routes/+page.svelte                                   | 2 +-
 src/routes/admin/api/articles.js                          | 8 ++++----
 src/routes/admin/product/+page.server.js                  | 6 ++++--
 src/routes/admin/product/ProductItem.svelte               | 4 +++-
 src/routes/admin/product/ProductList.svelte               | 2 ++
 7 files changed, 17 insertions(+), 8 deletions(-)
 create mode 100644 prisma/migrations/20230525163656_add_item_visibility/migration.sql

diff --git a/prisma/migrations/20230525163656_add_item_visibility/migration.sql b/prisma/migrations/20230525163656_add_item_visibility/migration.sql
new file mode 100644
index 0000000..ad7b613
--- /dev/null
+++ b/prisma/migrations/20230525163656_add_item_visibility/migration.sql
@@ -0,0 +1,2 @@
+-- AlterTable
+ALTER TABLE "Item" ADD COLUMN     "show" BOOLEAN NOT NULL DEFAULT true;
diff --git a/prisma/schema.prisma b/prisma/schema.prisma
index 2c4e5ff..00f3dfb 100644
--- a/prisma/schema.prisma
+++ b/prisma/schema.prisma
@@ -65,6 +65,7 @@ model Item {
 	stock        Int               @default(0)
 	bought       Int               @default(0)
 	available    Boolean           @default(true)
+	show         Boolean           @default(true)
 	restocks     Restock[]
 	transactions ItemTransaction[]
 }
diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte
index 629f83c..65e1304 100644
--- a/src/routes/+page.svelte
+++ b/src/routes/+page.svelte
@@ -313,7 +313,7 @@
 				{#each categories as category, i}
 					<h2 bind:this={categoryElements[i].element}>{category.name}</h2>
 					<div class="item-list">
-						<ItemList items={items.filter(item=>item.categoryId===category.id)} onClick={item=>addToCart({type: "article", code: item.code})} priceModifier={x=>x} bind:inView={elementsInView[i]} />
+						<ItemList items={items.filter(item=>item.categoryId===category.id&&item.show)} onClick={item=>addToCart({type: "article", code: item.code})} priceModifier={x=>x} bind:inView={elementsInView[i]} />
 					</div>
 				{/each}
 			</div>
diff --git a/src/routes/admin/api/articles.js b/src/routes/admin/api/articles.js
index 7944467..10b35fb 100644
--- a/src/routes/admin/api/articles.js
+++ b/src/routes/admin/api/articles.js
@@ -47,12 +47,12 @@ export async function restockArticles(restocks){
 	return db.$transaction(restocks.map(({code, amount, cost})=>restockArticle(code, amount, cost)));
 }
 
-export async function createArticle(code, name, price, categoryId, image, available=true){
-	return db.item.create({data: {code, name, price, categoryId, image, available}});
+export async function createArticle(code, name, price, categoryId, image, available=true, show=true){
+	return db.item.create({data: {code, name, price, categoryId, image, available, show}});
 }
 
-export async function updateArticle(code, name, price, categoryId, image, available){
-	return db.item.update({where: {code}, data: {name, price, categoryId, image, available}});
+export async function updateArticle(code, name, price, categoryId, image, available, show){
+	return db.item.update({where: {code}, data: {name, price, categoryId, image, available, show}});
 }
 
 export async function createCategory(name, position){
diff --git a/src/routes/admin/product/+page.server.js b/src/routes/admin/product/+page.server.js
index 1ac8c7d..bc83a67 100644
--- a/src/routes/admin/product/+page.server.js
+++ b/src/routes/admin/product/+page.server.js
@@ -18,6 +18,7 @@ export const actions = {
 		const image = data.get('image');
 		const oldImage = data.get('oldImage');
 		const available = !!data.get('available');
+		const show = !!data.get('show');
 		const deleteImage = data.get("deleteImage") === "true";
 		if(!code || !name || Number.isNaN(price) || price < 0 || !categoryId) return { errors: { failed: "Invalid form data" } };
 		let imagePath = oldImage;
@@ -35,7 +36,7 @@ export const actions = {
 			// TODO decide whether to await this or not
 			/*await */fs.writeFile(`/app/article-images/${imageName}`, buffer);
 		}
-		const product = await updateArticle(code, name, price, categoryId, imagePath, available);
+		const product = await updateArticle(code, name, price, categoryId, imagePath, available, show);
 		delete product.createdAt;
 		return {success: true, product};
 	},
@@ -47,6 +48,7 @@ export const actions = {
 		const categoryId = parseInt(data.get('categoryId'));
 		const image = data.get('image');
 		const available = !!data.get('available');
+		const show = !!data.get('show');
 		if(!code || !name || Number.isNaN(price) || price < 0 || !categoryId) return { error: "Invalid form data" };
 		if(image.size > 0 && !image.type.startsWith("image/")) return { error: "Invalid image" };
 		let imageUrl;
@@ -57,7 +59,7 @@ export const actions = {
 			// TODO decide whether to await this or not
 			/*await */fs.writeFile(`/app/article-images/${imageName}`, buffer);
 		}
-		const product = await createArticle(code, name, price, categoryId, imageUrl, available);
+		const product = await createArticle(code, name, price, categoryId, imageUrl, available, show);
 		delete product.createdAt;
 		return {success: true, article: product};
 	},
diff --git a/src/routes/admin/product/ProductItem.svelte b/src/routes/admin/product/ProductItem.svelte
index c7e5068..4bc7057 100644
--- a/src/routes/admin/product/ProductItem.svelte
+++ b/src/routes/admin/product/ProductItem.svelte
@@ -1,7 +1,7 @@
 <script>
 	import ItemIcon from "../../../components/ItemIcon.svelte";
 	
-	export let name, price, image, code, categoryId, available, categories, stock;
+	export let name, price, image, code, categoryId, available, show, categories, stock;
 	export let edit, deleteImage;
 	let newImage = image;
 </script>
@@ -28,6 +28,7 @@
 			{/each}
 		</select></td>
 		<td><input form={"form" + code} type="checkbox" name="available" id="available" checked={available} /></td>
+		<td><input form={"form" + code} type="checkbox" name="show" id="show" checked={show} /></td>
 		<td>
 			<button type="submit" form={"form" + code}>Speichern</button>
 			<button type="button" on:click={() => {edit = false; deleteImage = false; newImage = image;}}>Abbrechen</button>
@@ -40,6 +41,7 @@
 		<td><ItemIcon icon={image} size="40px" name={name} /></td>
 		<td>{categories[categoryId].name}</td>
 		<td>{available ? "Ja" : "Nein"} ({stock})</td>
+		<td>{show ? "Ja" : "Nein"}</td>
 		<td><button on:click={() => edit = true}>Bearbeiten</button></td>
 	</tr>
 {/if}
diff --git a/src/routes/admin/product/ProductList.svelte b/src/routes/admin/product/ProductList.svelte
index 3b480b5..df20711 100644
--- a/src/routes/admin/product/ProductList.svelte
+++ b/src/routes/admin/product/ProductList.svelte
@@ -19,6 +19,7 @@
 		<th>Bild</th>
 		<th>Kategorie</th>
 		<th>verfügbar</th>
+		<th>Sichtbar</th>
 		<th></th>
 	</tr>
 	{#each products as product, i}
@@ -40,6 +41,7 @@
 			{/each}
 		</select></td>
 		<td><input form="form-new" type="checkbox" name="available" id="available" checked /></td>
+		<td><input form="form-new" type="checkbox" name="show" id="show" checked /></td>
 		<td><button type="submit" form="form-new">Erstellen</button></td>
 	</tr>
 </table>
-- 
GitLab