Working on product detail dialog

This commit is contained in:
2024-09-08 20:35:10 +02:00
parent 3f061f0136
commit ed99709afd
5 changed files with 85 additions and 9 deletions

View File

@@ -26,6 +26,9 @@ export class Product extends Model {
@Column
imageUrl: string
@Column
description: string
// Relations
@BelongsTo(() => Category)

View File

@@ -31,14 +31,24 @@ api.get("/resetdatabase", (req: Request, res: Response, next: NextFunction) => {
Product.bulkCreate(
[
{ id: 0, brand: "Lenovo", name: "Thinkpad T14", price: 799.99, categoryId: 0, discount: 10, rating: 4.6, imageUrl: "https://f.media-amazon.com/images/I/51OHlMuJ5pL._AC_SL1280_.jpg" },
{ id: 1, brand: "Puma", name: "Men's Shirt", price: 14.99, categoryId: 2, discount: 0, rating: 3.8, imageUrl: "https://images.unsplash.com/photo-1496346236646-50e985b31ea4?w=800&auto=format&fit=crop&q=60&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxzZWFyY2h8NHx8dCUyMHNoaXJ0JTIwbWVufGVufDB8fDB8fHww" },
{ id: 2, brand: "Puma", name: "Woman's Shirt", price: 14.99, categoryId: 2, discount: 0, rating: 4.0, imageUrl: "https://images.unsplash.com/photo-1485218126466-34e6392ec754?w=800&auto=format&fit=crop&q=60&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxzZWFyY2h8N3x8dCUyMHNoaXJ0JTIwd29tYW58ZW58MHx8MHx8fDA%3D" },
{ id: 3, brand: "George Orwell", name: "1984", price: 9.99, categoryId: 3, discount: 0, rating: 4.9, imageUrl: "https://f.media-amazon.com/images/I/81BExVLr8sL._SL1500_.jpg" },
{ id: 4, brand: "Johann W. Goethe", name: "Faust", price: 4.99, categoryId: 3, discount: 0, rating: 4.2, imageUrl: "https://f.media-amazon.com/images/I/71p1k4JwDqL._SL1500_.jpg" },
{ id: 5, brand: "Theodor Sturm", name: "Der Schimmelreiter", price: 4.99, categoryId: 3, discount: 0, rating: 3.5, imageUrl: "https://f.media-amazon.com/images/I/81uUWtGmKtL._SL1500_.jpg" },
{ id: 6, brand: "Aldous Huxley", name: "Brave New World", price: 7.99, categoryId: 3, discount: 0, rating: 4.4, imageUrl: "https://f.media-amazon.com/images/I/917t3Joq2WL._SL1500_.jpg" },
{ id: 7, brand: "Ankermann", name: "Gaming Work V3", price: 1299.99, categoryId: 0, discount: 0, rating: 4.7, imageUrl: "https://f.media-amazon.com/images/I/81gpDyNWhzL._AC_SL1500_.jpg" }
{ id: 0, brand: "Lenovo", name: "Thinkpad T14", price: 799.99, categoryId: 0, discount: 10,
rating: 4.6, description: "Die stabile Arbeitsmaschine. Mit AMD Ryzen 7 89029U, 128 GB RAM und 8 TB M.2 SSD!", imageUrl: "https://f.media-amazon.com/images/I/51OHlMuJ5pL._AC_SL1280_.jpg" },
{ id: 1, brand: "Puma", name: "Men's Shirt", price: 14.99, categoryId: 2, discount: 0,
rating: 3.8, description: "", imageUrl: "https://images.unsplash.com/photo-1496346236646-50e985b31ea4?w=800&auto=format&fit=crop&q=60&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxzZWFyY2h8NHx8dCUyMHNoaXJ0JTIwbWVufGVufDB8fDB8fHww" },
{ id: 2, brand: "Puma", name: "Woman's Shirt", price: 14.99, categoryId: 2, discount: 0,
rating: 4.0, description: "", imageUrl: "https://images.unsplash.com/photo-1485218126466-34e6392ec754?w=800&auto=format&fit=crop&q=60&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxzZWFyY2h8N3x8dCUyMHNoaXJ0JTIwd29tYW58ZW58MHx8MHx8fDA%3D" },
{ id: 3, brand: "George Orwell", name: "1984", price: 9.99, categoryId: 3, discount: 0,
rating: 4.9, imageUrl: "https://f.media-amazon.com/images/I/81BExVLr8sL._SL1500_.jpg",
description: "BIG BROTHER IS WATCHING YOU! George Orwells 1984 ist längst zu einer scheinbar nicht mehr erklärungsbedürftigen Metapher für totalitäre Verhältnisse geworden. Mit atemberaubender Unerbittlichkeit zeichnet der Autor das erschreckende Bild einer durch und..." },
{ id: 4, brand: "Johann W. Goethe", name: "Faust", price: 4.99, categoryId: 3, discount: 0,
rating: 4.2, description: "", imageUrl: "https://f.media-amazon.com/images/I/71p1k4JwDqL._SL1500_.jpg" },
{ id: 5, brand: "Theodor Sturm", name: "Der Schimmelreiter", price: 4.99, categoryId: 3, discount: 0,
rating: 3.5, description: "", imageUrl: "https://f.media-amazon.com/images/I/81uUWtGmKtL._SL1500_.jpg" },
{ id: 6, brand: "Aldous Huxley", name: "Brave New World", price: 7.99, categoryId: 3, discount: 0,
rating: 4.4, imageUrl: "https://f.media-amazon.com/images/I/917t3Joq2WL._SL1500_.jpg",
description: "Brave New World beschreibt eine genormte Gesellschaft, in der Föten genetisch manipuliert und Menschen konditioniert werden. Ziel des Staates ist Zufriedenheit und Stabilität, und dies wird durch Gleichheit, Drogen und Propaganda erreicht. Gott und Religion..." },
{ id: 7, brand: "Ankermann", name: "Gaming Work V3", price: 1299.99, categoryId: 0, discount: 0,
rating: 4.7, description: "", imageUrl: "https://f.media-amazon.com/images/I/81gpDyNWhzL._AC_SL1500_.jpg" }
]
)

View File

@@ -2,6 +2,7 @@ export class ProductModel {
id: number = -1
brand: string = ""
name: string = ""
description: string = ""
categoryId: number = 0
price: number = 0
discount: number = 0

View File

@@ -1,5 +1,6 @@
<script setup lang="ts">
import productCard from "./productCard.vue"
import productDetails from "./productDetails.vue"
import filterBar from "./filterBar.vue"
import axios from "axios";
import { Ref, ref, watch } from "vue";
@@ -13,6 +14,8 @@ const categories: Ref<Array<CategoryModel>> = ref<Array<CategoryModel>>([new Cat
const selectedCategory: Ref<CategoryModel> = ref<CategoryModel>(new CategoryModel())
const sortedBy: Ref<FilterModel> = ref<FilterModel>()
const onlyDiscounts: Ref<boolean> = ref(false)
const showProductDetails = ref(false)
const dialogProduct = ref(new ProductModel())
const sortBy: Array<FilterModel> = [
{ icon: "mdi-sort-ascending", name: "Price: Low to high" },
@@ -100,6 +103,11 @@ function filterProducts() {
}
}
function showProductDialog(product: ProductModel) {
dialogProduct.value = product
showProductDetails.value = true
}
watch(() => selectedCategory.value, () => { filterProducts() })
watch(() => sortedBy.value, () => { sortProducts() })
watch(() => onlyDiscounts.value, () => { filterProducts() })
@@ -123,6 +131,7 @@ watch(() => onlyDiscounts.value, () => { filterProducts() })
<product-card
:product="product"
:category="getCategoryById(product.categoryId)"
@click="showProductDialog(product)"
/>
</v-col>
@@ -133,4 +142,6 @@ watch(() => onlyDiscounts.value, () => { filterProducts() })
/>
</v-col>
</v-row>
<product-details v-model="showProductDetails" :product="dialogProduct" :productCategory="getCategoryById(dialogProduct.categoryId)" />
</template>

View File

@@ -1,6 +1,57 @@
<script setup lang="ts">
import { VNumberInput } from 'vuetify/labs/VNumberInput'
import { ProductModel } from '@/data/models/productModel';
import { CategoryModel } from '@/data/models/categoryModel';
import { ref } from 'vue';
const showDialog = defineModel("showDialog", { type: Boolean })
const nrOfArticles = ref(1)
defineProps({
product: ProductModel,
productCategory: CategoryModel
})
</script>
<template>
<v-dialog max-width="800" v-model="showDialog">
<v-card :title="product.name" :subtitle="product.brand" >
<v-img :src="product.imageUrl" max-height="300" />
<v-card-text>
<v-row>
<v-col>
<v-icon :icon="productCategory.icon" />
{{ productCategory.name }}
</v-col>
</v-row>
<v-row>
<v-col>
{{ product.description }}
</v-col>
</v-row>
<v-row>
<v-col>
<v-number-input
:reverse="false"
controlVariant="default"
label="Anzahl"
:hideInput="false"
:inset="false"
v-model="nrOfArticles"
/>
</v-col>
<v-col>
{{ nrOfArticles * product.price }}
</v-col>
</v-row>
</v-card-text>
<v-card-actions>
<v-btn prepend-icon="mdi-cart-plus" >Zum Einkaufswagen hinzufügen</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</template>