Matching UI with improved API

This commit is contained in:
2024-09-24 13:12:44 +02:00
parent 8395b4427d
commit 0b34174ce9
34 changed files with 194 additions and 545 deletions

View File

@@ -1,27 +1,27 @@
<script setup lang="ts">
import { useTheme } from 'vuetify/lib/framework.mjs';
import { useUserStore } from './data/stores/userStore';
import { i18n } from './plugins/i18n';
import { ref, watch } from 'vue';
import vuetify from './plugins/vuetify';
import navigationItems from './components/navigationItems.vue';
import { useProductStore } from './data/stores/productStore';
import { useCategoryStore } from './data/stores/categoryStore';
import { usePreferencesStore } from './data/stores/preferencesStore';
const userStore = useUserStore()
const preferencesStore = usePreferencesStore()
const productStore = useProductStore()
const categoryStore = useCategoryStore()
const theme = useTheme()
const navRail = ref(vuetify.display.mobile)
theme.global.name.value = userStore.theme
theme.global.name.value = preferencesStore.theme
productStore.fetchAllProducts()
categoryStore.fetchAllCategories()
// Global watcher
watch(() => userStore.language, () => {
i18n.global.locale = userStore.language
watch(() => preferencesStore.language, () => {
i18n.global.locale = preferencesStore.language
}, { immediate: true })
</script>

View File

@@ -1,8 +1,8 @@
<script setup lang="ts">
import { useUserStore } from '@/data/stores/userStore';
import { useBasketStore } from '@/data/stores/basketStore';
import { useAccountStore } from '@/data/stores/accountStore';
const userStore = useUserStore()
const accountStore = useAccountStore()
const basketStore = useBasketStore()
const navRail = defineModel("navRail", { type: Boolean })
</script>
@@ -36,16 +36,16 @@ const navRail = defineModel("navRail", { type: Boolean })
</v-list-subheader>
<v-expand-transition>
<div v-if="!userStore.loggedIn">
<v-list-item v-if="!userStore.loggedIn" :title="$t('menu.login')" prepend-icon="mdi-login" to="/login" link />
<div v-if="accountStore.userAccount.id == null">
<v-list-item v-if="accountStore.userAccount.id == null" :title="$t('menu.login')" prepend-icon="mdi-login" to="/login" link />
</div>
</v-expand-transition>
<v-expand-transition>
<div v-if="userStore.loggedIn">
<div v-if="accountStore.userAccount.id != null">
<v-list-item :title="$t('menu.account')" prepend-icon="mdi-account" to="/account" link />
<v-list-item :title="$t('menu.orders')" prepend-icon="mdi-cart-check" to="/orders" link />
<v-list-item :title="$t('menu.logout')" prepend-icon="mdi-logout" @click="userStore.logout" link />
<v-list-item :title="$t('menu.logout')" prepend-icon="mdi-logout" @click="accountStore.logout" link />
</div>
</v-expand-transition>

View File

@@ -1,15 +1,14 @@
import { AccountRole } from "./accountRole"
import { AddressModel } from "./addressModel"
import { PaymentModel } from "./paymentModel"
export class AccountModel {
id: number
username: string = ""
password: string = ""
street: string = ""
houseNumber: number = 0
postalCode: number = 0
city: string = ""
firstName: string = ""
lastName: string = ""
createdAt: string = ""
updatedAt: string = ""
bankName: string = ""
iban: string = ""
addresses: Array<AddressModel> = [ new AddressModel() ]
payments: Array<PaymentModel> = [ new PaymentModel() ]
accountRole: AccountRole = new AccountRole()
}

View File

@@ -0,0 +1,5 @@
export class AccountRole {
name: string = ""
privilegeBuy: boolean = false
privilegeAdminPanel: boolean = false
}

View File

@@ -0,0 +1,6 @@
export class AddressModel {
street: string = ""
houseNumber: number = 0
postalCode: number = 0
city: string = ""
}

View File

@@ -1,10 +1,7 @@
import { ProductModel } from "./productModel"
export class BasketItemModel {
id: number = -1
brand: string = ""
name: string = ""
categoryName: string = ""
categoryIcon: string = ""
price: number = 0
discount: number = 0
quantity: number = 1
product: ProductModel = new ProductModel()
}

View File

@@ -0,0 +1,4 @@
export class BrandModel {
id: number = 0
name: string = ""
}

View File

@@ -2,6 +2,4 @@ export class CategoryModel {
id: number = -1
name: string
icon: string
createdAt: string = ""
updatedAt: string = ""
}

View File

@@ -2,8 +2,7 @@ import { OrderedItemModel } from "./orderedItemModel"
export class OrderModel {
accountId: number
totalPrice: number
shippingProgress: number
orderItem: Array<OrderedItemModel>
createdAt: string
orderItems: Array<OrderedItemModel>
orderedAt: string
}

View File

@@ -0,0 +1,4 @@
export class PaymentModel {
bankName: string = ""
iban: string = ""
}

View File

@@ -1,13 +1,16 @@
import { BrandModel } from "./brandModel"
import { CategoryModel } from "./categoryModel"
export class ProductModel {
id: number = -1
brand: string
name: string
id: number = 0
category: CategoryModel = new CategoryModel()
brand: BrandModel = new BrandModel()
name: string = ""
description: string = ""
specs: Array<string> = []
categoryId: number
price: number = 0
discount: number = 0
rating: number = 1
inStock: number
specs: Array<string> = []
images: Array<string> = [""]
storedItems: number
}

View File

@@ -1,15 +0,0 @@
import { CategoryModel } from "./categoryModel"
export class ProductWithCategoryModel {
id: number = -1
brand: string
name: string
description: string = ""
specs: Array<string> = []
category: CategoryModel = new CategoryModel()
price: number = 0
discount: number = 0
rating: number = 1
images: Array<string> = [""]
storedItems: number
}

View File

@@ -1,21 +1,16 @@
import { defineStore } from "pinia";
import { useLocalStorage } from "@vueuse/core";
import { ThemeEnum } from "../enums/themeEnums";
import { LanguageEnum } from "../enums/languageEnum";
import { defineStore } from "pinia";
import { AccountModel } from "../models/accountModel";
import { loginAccount, registerAccount, updateAccount } from "../api/accountApi";
import { useFeedbackStore } from "./feedbackStore";
import { BannerStateEnum } from "../enums/bannerStateEnum";
import { OrderModel } from "../models/orderModel";
import { useFeedbackStore } from "./feedbackStore";
import { loginAccount, registerAccount, updateAccount } from "../api/accountApi";
import { getUserOrders } from "../api/orderApi";
import { BannerStateEnum } from "../enums/bannerStateEnum";
export const useUserStore = defineStore('userStore', {
export const useAccountStore = defineStore("accountStore", {
state: () => ({
theme: useLocalStorage<ThemeEnum>("hackmycart/userStore/theme", ThemeEnum.DARKRED),
language: useLocalStorage<LanguageEnum>("hackmycart/userStore/language", LanguageEnum.GERMAN),
userAccount: useLocalStorage<AccountModel>("hackmycart/userStore/userAccount", new AccountModel()),
loggedIn: useLocalStorage<Boolean>("hackmycart/userStore/loggedIn", false),
orders: useLocalStorage<Array<OrderModel>>("hackmycart/userStore/orders", [])
userAccount: useLocalStorage("hackmycart/accountStore/userAccount", new AccountModel()),
orders: useLocalStorage<Array<OrderModel>>("hackmycart/accountStore/orders", [ new OrderModel() ])
}),
actions: {

View File

@@ -4,11 +4,10 @@ import { calcProductPrice } from "@/scripts/productScripts";
import { BasketItemModel } from "../models/basketItemModel";
import { useFeedbackStore } from "./feedbackStore";
import { BannerStateEnum } from "../enums/bannerStateEnum";
import { OrderModel } from "../models/orderModel";
import { useUserStore } from "./userStore";
import { addOrder } from "../api/orderApi";
import { useAccountStore } from "./accountStore";
export const useBasketStore = defineStore('basket', {
export const useBasketStore = defineStore('basketStore', {
state: () => ({
itemsInBasket: useLocalStorage<Array<BasketItemModel>>("hackmycart/basketStore/productsInBasket", [])
}),
@@ -31,7 +30,7 @@ export const useBasketStore = defineStore('basket', {
feedbackStore.changeBanner(BannerStateEnum.BASKETPRODUCTREMOVED)
this.itemsInBasket = this.itemsInBasket.filter((basketItemModel: BasketItemModel) =>
basketItemModel.productId != item.productId
basketItemModel.product.id != item.product.id
)
},
@@ -40,15 +39,16 @@ export const useBasketStore = defineStore('basket', {
feedbackStore.changeBanner(BannerStateEnum.BASKETPRODUCTADDED)
// Product is already in the basket, increase number of items
if (this.itemsInBasket.find((basketItem) => basketItem.productId == item.productId)) {
this.itemsInBasket.find((basketItem) => basketItem.productId == item.productId).quantity += item.quantity
if (this.itemsInBasket.find((basketItem) => basketItem.productId == item.product.id)) {
this.itemsInBasket.find((basketItem) =>
basketItem.productId == item.product.id).quantity += item.quantity
} else {
this.itemsInBasket.push(item)
}
},
takeOrder() {
const userStore = useUserStore()
const accountStore = useAccountStore()
//
// const order = new OrderModel()
// order.accountId = userStore.userAccount.id
@@ -56,7 +56,7 @@ export const useBasketStore = defineStore('basket', {
//
// console.log(order)
addOrder(userStore.userAccount.id, this.itemsInBasket)
addOrder(accountStore.userAccount.id, this.itemsInBasket)
}
}
})

View File

@@ -0,0 +1,11 @@
import { defineStore } from "pinia";
import { useLocalStorage } from "@vueuse/core";
import { ThemeEnum } from "../enums/themeEnums";
import { LanguageEnum } from "../enums/languageEnum";
export const usePreferencesStore = defineStore('preferencesStore', {
state: () => ({
theme: useLocalStorage<ThemeEnum>("hackmycart/preferencesStore/theme", ThemeEnum.DARKRED),
language: useLocalStorage<LanguageEnum>("hackmycart/preferencesStore/language", LanguageEnum.GERMAN)
}),
})

View File

@@ -3,13 +3,13 @@ import { defineStore } from "pinia";
import { getAllProducts } from "../api/productApi";
import { SortOrder } from "../enums/sortOrderEnum";
import { CategoryModel } from "../models/categoryModel";
import { ProductWithCategoryModel } from "../models/productWithCategoryModel";
import { ProductModel } from "../models/productModel";
export const useProductStore = defineStore("productStore", {
state: () => ({
products: useLocalStorage<Array<ProductWithCategoryModel>>("hackmycart/productStore/products", []),
filteredProducts: useLocalStorage<Array<ProductWithCategoryModel>>("hackmycart/productStore/filteredProducts", []),
products: useLocalStorage<Array<ProductModel>>("hackmycart/productStore/products", []),
filteredProducts: useLocalStorage<Array<ProductModel>>("hackmycart/productStore/filteredProducts", []),
sortOrder: useLocalStorage<SortOrder>("hackmycart/productStore/sortOrder", SortOrder.NAMEATOZ),
filteredCategory: useLocalStorage<CategoryModel>("hackmycart/productStore/filteredCategory", new CategoryModel()),
onlyDiscounts: useLocalStorage<Boolean>("hackmycart/productStore/onlyDiscounts", false)
@@ -28,20 +28,20 @@ export const useProductStore = defineStore("productStore", {
if (this.filteredCategory.id == -1 || this.filteredCategory.id == 0) {
this.filteredProducts = this.products
} else {
this.filteredProducts = this.products.filter((product: ProductWithCategoryModel) =>
this.filteredProducts = this.products.filter((product: ProductModel) =>
product.category.id == this.filteredCategory.id
)
}
if (this.onlyDiscounts) {
this.filteredProducts = this.filteredProducts.filter((product: ProductWithCategoryModel) =>
this.filteredProducts = this.filteredProducts.filter((product: ProductModel) =>
product.discount > 0
)
}
},
sortProducts() {
this.filteredProducts.sort((a: ProductWithCategoryModel, b: ProductWithCategoryModel) => {
this.filteredProducts.sort((a: ProductModel, b: ProductModel) => {
switch (this.sortOrder)
{
case SortOrder.PRICELOWTOHIGH: {

View File

@@ -1,9 +1,9 @@
<script setup lang="ts">
import { useUserStore } from '@/data/stores/userStore';
import cardView from '@/components/cardView.vue';
import outlinedButton from '@/components/outlinedButton.vue';
import { useAccountStore } from '@/data/stores/accountStore';
const userStore = useUserStore()
const accountStore = useAccountStore()
</script>
<template>
@@ -13,14 +13,14 @@ const userStore = useUserStore()
<v-col>
<v-text-field
:label="$t('account.username')"
v-model="userStore.userAccount.username"
v-model="accountStore.userAccount.username"
disabled
/>
</v-col>
<v-col>
<v-text-field
:label="$t('account.password')"
v-model="userStore.userAccount.password"
v-model="accountStore.userAccount.password"
type="password"
/>
</v-col>
@@ -30,13 +30,13 @@ const userStore = useUserStore()
<v-col>
<v-text-field
:label="$t('userInfo.firstName')"
v-model="userStore.userAccount.firstName"
v-model="accountStore.userAccount.firstName"
/>
</v-col>
<v-col>
<v-text-field
:label="$t('userInfo.lastName')"
v-model="userStore.userAccount.lastName"
v-model="accountStore.userAccount.lastName"
/>
</v-col>
</v-row>
@@ -45,13 +45,13 @@ const userStore = useUserStore()
<v-col>
<v-text-field
:label="$t('userInfo.street')"
v-model="userStore.userAccount.street"
v-model="accountStore.userAccount.addresses[0].street"
/>
</v-col>
<v-col>
<v-text-field
:label="$t('userInfo.houseNumber')"
v-model="userStore.userAccount.houseNumber"
v-model="accountStore.userAccount.addresses[0].houseNumber"
/>
</v-col>
</v-row>
@@ -60,13 +60,13 @@ const userStore = useUserStore()
<v-col>
<v-text-field
:label="$t('userInfo.postalCode')"
v-model="userStore.userAccount.postalCode"
v-model="accountStore.userAccount.addresses[0].postalCode"
/>
</v-col>
<v-col>
<v-text-field
:label="$t('userInfo.city')"
v-model="userStore.userAccount.city"
v-model="accountStore.userAccount.addresses[0].city"
/>
</v-col>
</v-row>
@@ -75,13 +75,13 @@ const userStore = useUserStore()
<v-col>
<v-text-field
:label="$t('userInfo.bankName')"
v-model="userStore.userAccount.bankName"
v-model="accountStore.userAccount.payments[0].bankName"
/>
</v-col>
<v-col>
<v-text-field
:label="$t('userInfo.iban')"
v-model="userStore.userAccount.iban"
v-model="accountStore.userAccount.payments[0].iban"
/>
</v-col>
</v-row>
@@ -89,7 +89,7 @@ const userStore = useUserStore()
<template #actions>
<outlined-button
@click="userStore.updateAccount()"
@click="accountStore.updateAccount()"
prepend-icon="mdi-content-save"
color="green"
>

View File

@@ -3,13 +3,13 @@ import { useBasketStore } from '@/data/stores/basketStore';
import productsTable from './productsTable.vue';
import alertBanner from '@/components/alertBanner.vue';
import cardView from '@/components/cardView.vue';
import { useUserStore } from '@/data/stores/userStore';
import orderingDialog from './orderingDialog.vue';
import outlinedButton from '@/components/outlinedButton.vue';
import { ref } from 'vue';
import { useAccountStore } from '@/data/stores/accountStore';
const basketStore = useBasketStore()
const userStore = useUserStore()
const accountStore = useAccountStore()
const showOrderingDialog = ref()
</script>
@@ -47,7 +47,7 @@ const showOrderingDialog = ref()
<template #actions>
<outlined-button
prepend-icon="mdi-basket-check"
:disabled="basketStore.itemsInBasket.length == 0 || userStore.userAccount.id == null"
:disabled="basketStore.itemsInBasket.length == 0 || accountStore.userAccount.id == null"
variant="outlined"
color="green"
@click="showOrderingDialog = true"

View File

@@ -1,16 +1,16 @@
<script setup lang="ts">
import { useUserStore } from '@/data/stores/userStore';
import { ref } from 'vue';
import cardView from '@/components/cardView.vue';
import outlinedButton from '@/components/outlinedButton.vue';
import { useAccountStore } from '@/data/stores/accountStore';
const userStore = useUserStore()
const accountStore = useAccountStore()
const showRegisterCard = defineModel("showRegisterCard", { type: Boolean, default: false })
const username = ref("duranduran")
const password = ref("H4nn0ver")
function startLogin() {
userStore.login(username.value, password.value)
accountStore.login(username.value, password.value)
}
</script>

View File

@@ -1,13 +1,13 @@
<script setup lang="ts">
import { AccountModel } from '@/data/models/accountModel';
import { useUserStore } from '@/data/stores/userStore';
import { ref } from 'vue';
import cardView from '@/components/cardView.vue';
import outlinedButton from '@/components/outlinedButton.vue';
import { useAccountStore } from '@/data/stores/accountStore';
const newUser = ref(new AccountModel())
const showRegisterCard = defineModel("showRegisterCard", { type: Boolean, default: false })
const userStore = useUserStore()
const accountStore = useAccountStore()
</script>
<template>
@@ -54,12 +54,12 @@ const userStore = useUserStore()
<v-text-field
:label="$t('userInfo.street')"
prepend-icon="mdi-numeric"
v-model="newUser.street"
v-model="newUser.addresses[0].street"
clearable
/>
</v-col>
<v-col cols="4">
<v-text-field :label="$t('userInfo.houseNumber')" v-model="newUser.houseNumber" clearable />
<v-text-field :label="$t('userInfo.houseNumber')" v-model="newUser.addresses[0].houseNumber" clearable />
</v-col>
</v-row>
@@ -68,12 +68,12 @@ const userStore = useUserStore()
<v-text-field
:label="$t('userInfo.postalCode')"
prepend-icon="mdi-city"
v-model="newUser.postalCode"
v-model="newUser.addresses[0].postalCode"
clearable
/>
</v-col>
<v-col>
<v-text-field :label="$t('userInfo.city')" v-model="newUser.city" clearable />
<v-text-field :label="$t('userInfo.city')" v-model="newUser.addresses[0].city" clearable />
</v-col>
</v-row>
</v-container>
@@ -88,7 +88,7 @@ const userStore = useUserStore()
<outlined-button
prepend-icon="mdi-account-plus"
@click="userStore.registerAccount(newUser)"
@click="accountStore.registerAccount(newUser)"
>
{{ $t('account.register') }}
</outlined-button>

View File

@@ -1,8 +1,8 @@
<script setup lang="ts">
import { useUserStore } from '@/data/stores/userStore';
import { useAccountStore } from '@/data/stores/accountStore';
import ordersCard from './ordersCard.vue';
const userStore = useUserStore()
const accountStore = useAccountStore()
function getDotColor(order, step: number) {
if (order.shippingProgress == step)
@@ -27,7 +27,7 @@ function formatDateTimeString(string: string) {
<template>
<v-container max-width="1000">
<v-row v-for="order in userStore.orders">
<v-row v-for="order in accountStore.orders">
<v-col>
<orders-card :order="order" />
</v-col>

View File

@@ -29,8 +29,8 @@ function formatDateTimeString(string: string) {
<template>
<card-view
:title="$t('orders.orderFrom') + ' ' + formatDateTimeString(order.createdAt) + ' ' + $t('oclock')"
:subtitle="$t('totalPrice') + ': ' + order.totalPrice + ' €'"
:title="$t('orders.orderFrom') + ' ' + formatDateTimeString(order.orderedAt) + ' ' + $t('oclock')"
:subtitle="$t('totalPrice') + ': ' + 0 + ' €'"
>
<v-timeline direction="horizontal" side="start" size="x-large">
<v-timeline-item :dot-color="getDotColor(order, 1)" icon="mdi-basket-check">
@@ -64,9 +64,9 @@ function formatDateTimeString(string: string) {
</tr>
</thead>
<tbody>
<tr v-for="orderItem in order.orderItem">
<tr v-for="orderItem in order.orderItems">
<td>{{ orderItem.quantity }}x</td>
<td>{{ orderItem.product.brand }}</td>
<td>{{ orderItem.product.brand.name }}</td>
<td>{{ orderItem.product.name }}</td>
<td>{{ orderItem.product.price }} </td>
</tr>

View File

@@ -1,20 +1,20 @@
<script setup lang="ts">
import { ThemeEnum } from '@/data/enums/themeEnums';
import { useTheme } from 'vuetify/lib/framework.mjs';
import { useUserStore } from '@/data/stores/userStore';
import { i18n } from '@/plugins/i18n';
import cardView from '@/components/cardView.vue';
import { usePreferencesStore } from '@/data/stores/preferencesStore';
const userStore = useUserStore()
const preferencesStore = usePreferencesStore()
const theme = useTheme()
const themeEnums = Object.values(ThemeEnum)
function changeTheme() {
theme.global.name.value = userStore.theme
theme.global.name.value = preferencesStore.theme
}
function changeLanguage() {
i18n.global.locale = userStore.language
i18n.global.locale = preferencesStore.language
}
</script>
@@ -24,7 +24,7 @@ function changeLanguage() {
<v-row>
<v-col>
<v-select
v-model="userStore.theme"
v-model="preferencesStore.theme"
:items="themeEnums"
:label="$t('preferences.selectedTheme')"
@update:model-value="changeTheme"
@@ -34,7 +34,7 @@ function changeLanguage() {
<v-row>
<v-col>
<v-select v-model="userStore.language" :items="$i18n.availableLocales" :label="$t('preferences.language')"
<v-select v-model="preferencesStore.language" :items="$i18n.availableLocales" :label="$t('preferences.language')"
@update:model-value="changeLanguage"
/>
</v-col>

View File

@@ -3,16 +3,16 @@ import productCard from "./productCard.vue"
import productDetails from "./productDetailsDialog.vue"
import { ref, watch } from "vue";
import { useProductStore } from "@/data/stores/productStore";
import { ProductWithCategoryModel } from "@/data/models/productWithCategoryModel";
import alertBanner from "@/components/alertBanner.vue";
import filterNavDrawer from "./filterNavDrawer.vue";
import { ProductModel } from '@/data/models/productModel';
const productStore = useProductStore()
const showProductDetails = ref(false)
const dialogProduct = ref(new ProductWithCategoryModel())
const dialogProduct = ref(new ProductModel())
function showProductDialog(product: ProductWithCategoryModel) {
function showProductDialog(product: ProductModel) {
dialogProduct.value = product
showProductDetails.value = true
}

View File

@@ -1,11 +1,11 @@
<script setup lang="ts">
import { ProductWithCategoryModel } from '@/data/models/productWithCategoryModel';
import { ProductModel } from '@/data/models/productModel';
import cardView from '@/components/cardView.vue';
defineProps({
product: {
required: true,
type: ProductWithCategoryModel
type: ProductModel
}
})
</script>
@@ -65,11 +65,11 @@ defineProps({
</div>
<div style="position: absolute; bottom: 0; right: 0;" class="pr-2 pb-2">
<div v-if="product.storedItems > 5" class="text-green-lighten-1">
{{ $t("product.storedItemsAvailable", [product.storedItems]) }}
<div v-if="product.inStock > 5" class="text-green-lighten-1">
{{ $t("product.storedItemsAvailable", [product.inStock]) }}
</div>
<div v-else-if="product.storedItems > 0" class="text-orange-lighten-1">
{{ $t("product.storedItemsAvailable", [product.storedItems]) }}
<div v-else-if="product.inStock > 0" class="text-orange-lighten-1">
{{ $t("product.storedItemsAvailable", [product.inStock]) }}
</div>
<div v-else class="text-red">
{{ $t("product.soldOut") }}

View File

@@ -4,13 +4,13 @@ import { ModelRef, ref, watch } from 'vue';
import { useBasketStore } from '@/data/stores/basketStore';
import { calcProductPrice, productToBasketItem } from '@/scripts/productScripts';
import ActionDialog from '@/components/actionDialog.vue'
import { ProductWithCategoryModel } from '@/data/models/productWithCategoryModel';
import { ProductModel } from '@/data/models/productModel';
import outlinedButton from '@/components/outlinedButton.vue';
const props = defineProps({
product: {
type: ProductWithCategoryModel,
default: new ProductWithCategoryModel()
type: ProductModel,
default: new ProductModel()
}
})
@@ -32,7 +32,7 @@ watch(() => props.product.images, () => {
<template>
<action-dialog
:title="product.brand + ': ' + product.name"
:title="product.brand.name + ': ' + product.name"
:icon="product.category.icon"
:subtitle="product.category.name"
v-model="showDialog"
@@ -107,11 +107,11 @@ watch(() => props.product.images, () => {
<v-row>
<v-col cols="3">
<div class="pt-3">
<div v-if="product.storedItems > 5" class="text-green-lighten-1">
{{ $t("product.storedItemsAvailable", [product.storedItems]) }}
<div v-if="product.inStock > 5" class="text-green-lighten-1">
{{ $t("product.storedItemsAvailable", [product.inStock]) }}
</div>
<div v-else-if="product.storedItems > 0" class="text-orange-lighten-1">
{{ $t("product.storedItemsAvailable", [product.storedItems]) }}
<div v-else-if="product.inStock > 0" class="text-orange-lighten-1">
{{ $t("product.storedItemsAvailable", [product.inStock]) }}
</div>
<div v-else class="text-red">
{{ $t("product.soldOut") }}
@@ -147,14 +147,14 @@ watch(() => props.product.images, () => {
:max="10"
density="comfortable"
:hide-details="true"
:disabled="product.storedItems == 0"
:disabled="product.inStock == 0"
/>
<outlined-button
prepend-icon="mdi-cart-plus"
@click="addProductToBasket"
height="50"
:disabled="product.storedItems == 0"
:disabled="product.inStock == 0"
>
{{ $t('addToBasket') }}
</outlined-button>

View File

@@ -1,9 +1,8 @@
import { BasketItemModel } from "@/data/models/basketItemModel";
import { CategoryModel } from "@/data/models/categoryModel";
import { ProductModel } from "@/data/models/productModel";
import { ProductWithCategoryModel } from "@/data/models/productWithCategoryModel";
export function calcProductPrice(product: ProductWithCategoryModel, quantity: number = 1): number {
export function calcProductPrice(product: ProductModel, quantity: number = 1): number {
return calcPrice(product.price, product.discount, quantity)
}
@@ -29,7 +28,7 @@ export function calcPrice(price: number, discount: number = 0, quantity: number
*
* @returns BasketItemModel
*/
export function productToBasketItem(product: ProductWithCategoryModel, quantity: number): BasketItemModel {
export function productToBasketItem(product: ProductModel, quantity: number): BasketItemModel {
let result = new BasketItemModel()
result.productId = product.id