New cardView component, add database reset confirm dialog

This commit is contained in:
2024-09-22 15:46:33 +02:00
parent eb84351231
commit 98cc551f76
17 changed files with 224 additions and 95 deletions

View File

@@ -1,33 +1,33 @@
<script setup lang="ts">
import { ModelRef } from 'vue';
import cardView from './cardView.vue';
const showDialog: ModelRef<boolean> = defineModel()
defineProps({
title: String,
icon: {
type: String,
default: "mdi-cog"
type: String
},
subtitle: {
type: String,
default: ""
},
imageUrl: {
type: String,
default: ""
}
})
</script>
<template>
<v-dialog max-width="1200" v-model="showDialog">
<v-card :title="title" :subtitle="subtitle" :prepend-icon="icon" density="compact">
<slot name="content"></slot>
<card-view
:title="title"
:subtitle="subtitle"
:icon="icon"
>
<slot></slot>
<v-card-actions>
<template #actions>
<slot name="actions"></slot>
</v-card-actions>
</v-card>
</template>
</card-view>
</v-dialog>
</template>

View File

@@ -0,0 +1,31 @@
<script setup lang="ts">
defineProps({
title: String,
icon: {
type: String
},
subtitle: {
type: String,
}
})
</script>
<template>
<v-card
:title="title"
:subtitle="subtitle"
:prepend-icon="icon"
class="card-outter"
>
<slot></slot>
<v-card-actions v-if="$slots.actions" class="card-actions">
<v-spacer />
<slot name="actions"></slot>
</v-card-actions>
</v-card>
</template>
<style>
</style>

View File

@@ -17,7 +17,8 @@
"language": "Sprache",
"systemSetup": "Systemeinstellungen",
"resetDatabase": "Datenbank zurücksetzen",
"resetPreferences": "Einstellungen zurücksetzen"
"resetPreferences": "Einstellungen zurücksetzen",
"resetConfirm": "Soll die Datenbank wirklich zurückgesetzt werden?"
},
"product": {
"product": "Produkt",
@@ -82,5 +83,8 @@
"basketProductAdded": "Artikel zum Warenkorb hinzugefügt",
"basketProductRemoved": "Artikel aus Warenkorb entfernt"
},
"oclock": "Uhr"
"oclock": "Uhr",
"ordering": {
"ordering": "Bestellabschluss"
}
}

View File

@@ -17,7 +17,8 @@
"language": "Language",
"systemSetup": "System setup",
"resetDatabase": "Reset database",
"resetPreferences": "Reset preferences"
"resetPreferences": "Reset preferences",
"resetConfirm": "Really reset the database?"
},
"product": {
"product": "Product",
@@ -82,5 +83,8 @@
"basketProductAdded": "Add product to basket",
"basketProductRemoved": "Product removed from basket"
},
"oclock": "o'clock"
"oclock": "o'clock",
"ordering": {
"ordering": "Finish order"
}
}

View File

@@ -1,11 +1,12 @@
<script setup lang="ts">
import { useUserStore } from '@/data/stores/userStore';
import cardView from '@/components/cardView.vue';
const userStore = useUserStore()
</script>
<template>
<v-card title="Account">
<card-view title="Account">
<v-container>
<v-row>
<v-col>
@@ -70,8 +71,15 @@ const userStore = useUserStore()
</v-row>
</v-container>
<v-card-actions>
<v-btn @click="userStore.updateAccount()" >Save</v-btn>
</v-card-actions>
</v-card>
<template #actions>
<v-btn
@click="userStore.updateAccount()"
variant="outlined"
prepend-icon="mdi-content-save"
color="green"
>
Save
</v-btn>
</template>
</card-view>
</template>

View File

@@ -2,6 +2,7 @@
import { useBasketStore } from '@/data/stores/basketStore';
import productsTable from './productsTable.vue';
import alertBanner from '@/components/alertBanner.vue';
import cardView from '@/components/cardView.vue';
const basketStore = useBasketStore()
</script>
@@ -15,7 +16,7 @@ const basketStore = useBasketStore()
</v-row>
<v-row>
<v-col>
<v-card :title="$t('menu.basket')" prepend-icon="mdi-cart">
<card-view :title="$t('menu.basket')" prepend-icon="mdi-cart">
<v-card-subtitle v-if="basketStore.itemsInBasket.length > 0">
<div v-if="basketStore.itemsInBasket.length == 1">
{{ basketStore.itemsInBasket.length }} {{ $t('product.product') }}
@@ -33,19 +34,21 @@ const basketStore = useBasketStore()
:text="$t('emptyBasketText')"
/>
<v-card-text class="text-right" v-if="basketStore.itemsInBasket.length > 0">
<v-card-text class="text-right text-h5" v-if="basketStore.itemsInBasket.length > 0">
{{ $t('totalPrice') }}: {{ basketStore.getTotalPrice }}
</v-card-text>
<v-card-actions>
<template #actions>
<v-btn
prepend-icon="mdi-basket-check"
:disabled="basketStore.itemsInBasket.length == 0"
variant="outlined"
color="green"
>
{{ $t('orderNow') }}
</v-btn>
</v-card-actions>
</v-card>
</template>
</card-view>
</v-col>
</v-row>
</v-container>

View File

@@ -0,0 +1,8 @@
<script setup lang="ts">
</script>
<template>
<v-dialog :title="$t('ordering.ordering')">
</v-dialog>
</template>

View File

@@ -8,29 +8,50 @@ const basketStore = useBasketStore()
function removeFromBasket(basketItem: BasketItemModel) {
basketStore.removeItemFromBasket(basketItem)
}
function editQuantity(basketItem: BasketItemModel) {
// todo
}
</script>
<template>
<v-table>
<thead>
<tr>
<th></th>
<th>{{ $t('product.category') }}</th>
<th>{{ $t('product.brand') }}</th>
<th>{{ $t('product.products') }}</th>
<th class="text-center">{{ $t('quantity') }}</th>
<th class="text-right">{{ $t('product.productPrice') }}</th>
<th class="text-right">{{ $t('totalPrice') }}</th>
<th></th>
</tr>
</thead>
<tbody>
<tr v-for="basketItem in basketStore.itemsInBasket">
<td><v-btn icon="mdi-delete" flat @click="removeFromBasket(basketItem)"/></td>
<td><v-icon :icon="basketItem.categoryIcon" /> {{ basketItem.categoryName }} </td>
<td>{{ basketItem.brand }}</td>
<td>{{ basketItem.name }}</td>
<td class="text-center">{{ basketItem.quantity }}x</td>
<td><v-icon :icon="basketItem.categoryIcon" />
{{ basketItem.categoryName }}
</td>
<td>
{{ basketItem.brand }}
</td>
<td>
{{ basketItem.name }}
</td>
<td class="text-center">
{{ basketItem.quantity }}x
<v-btn
icon="mdi-pencil"
@click="editQuantity(basketItem)"
color="orange"
variant="text"
flat
/>
</td>
<td class="text-right">
<div v-if="basketItem.discount > 0">
@@ -46,7 +67,6 @@ function removeFromBasket(basketItem: BasketItemModel) {
</div>
</td>
<td class="text-right">
<div v-if="basketItem.discount > 0">
<strong class="font-weight-bold text-body-1 text-red-lighten-1">
@@ -62,6 +82,10 @@ function removeFromBasket(basketItem: BasketItemModel) {
{{ calcPrice(basketItem.price, 0, basketItem.quantity) }}
</div>
</td>
<td>
<v-btn icon="mdi-delete" flat @click="removeFromBasket(basketItem)" color="red" variant="text"/>
</td>
</tr>
</tbody>
</v-table>

View File

@@ -1,7 +1,7 @@
<script setup lang="ts">
import { BannerStateEnum } from '@/data/enums/bannerStateEnum';
import { useUserStore } from '@/data/stores/userStore';
import { ref } from 'vue';
import cardView from '@/components/cardView.vue';
const userStore = useUserStore()
const showRegisterCard = defineModel("showRegisterCard", { type: Boolean, default: false })
@@ -14,7 +14,7 @@ function startLogin() {
</script>
<template>
<v-card :title="$t('menu.login')" prepend-icon="mdi-login" elevation="8">
<card-view :title="$t('menu.login')" prepend-icon="mdi-login" elevation="8">
<v-container>
<v-row>
<v-col>
@@ -30,14 +30,14 @@ function startLogin() {
</v-row>
</v-container>
<v-card-actions>
<template #actions>
<v-btn variant="outlined" @click="showRegisterCard = true" color="primary" prepend-icon="mdi-plus">
{{ $t('account.noAccountRegister') }}
</v-btn>
<v-spacer />
<v-btn variant="outlined" append-icon="mdi-arrow-right" color="primary"
@click="startLogin">{{ $t('menu.login') }}</v-btn>
</v-card-actions>
</v-card>
</template>
</card-view>
</template>

View File

@@ -1,9 +1,8 @@
<script setup lang="ts">
import { BannerStateEnum } from '@/data/enums/bannerStateEnum';
import { AccountModel } from '@/data/models/accountModel';
import { useUserStore } from '@/data/stores/userStore';
import axios from 'axios';
import { ref } from 'vue';
import cardView from '@/components/cardView.vue';
const newUser = ref(new AccountModel())
const showRegisterCard = defineModel("showRegisterCard", { type: Boolean, default: false })
@@ -11,7 +10,7 @@ const userStore = useUserStore()
</script>
<template>
<v-card :title="$t('account.register')">
<card-view :title="$t('account.register')">
<v-container>
<v-row>
<v-col>
@@ -89,5 +88,5 @@ const userStore = useUserStore()
{{ $t('account.register') }}
</v-btn>
</template>
</v-card>
</card-view>
</template>

View File

@@ -1,5 +1,6 @@
<script setup lang="ts">
import { useUserStore } from '@/data/stores/userStore';
import ordersCard from './ordersCard.vue';
const userStore = useUserStore()
@@ -28,47 +29,7 @@ function formatDateTimeString(string: string) {
<v-container max-width="1000">
<v-row v-for="order in userStore.orders">
<v-col>
<v-card
:title="$t('orders.orderFrom') + ' ' + formatDateTimeString(order.createdAt) + ' ' + $t('oclock')"
:subtitle="$t('totalPrice') + ': ' + order.totalPrice + ' €'"
>
<v-timeline direction="horizontal" side="start">
<v-timeline-item :dot-color="getDotColor(order, 1)" icon="mdi-basket-check">
{{ $t('orders.ordered') }}
</v-timeline-item>
<v-timeline-item :dot-color="getDotColor(order, 2)" icon="mdi-package-variant">
{{ $t('orders.preparingForShipping') }}
</v-timeline-item>
<v-timeline-item :dot-color="getDotColor(order, 3)" icon="mdi-truck-fast">
{{ $t('orders.shipped') }}
</v-timeline-item>
<v-timeline-item :dot-color="getDotColor(order, 4)" icon="mdi-package-check">
{{ $t('orders.delivered') }}
</v-timeline-item>
</v-timeline>
<v-table class="bg-surface-light">
<thead>
<tr>
<th>{{ $t('quantity') }}</th>
<th>{{ $t('product.brand') }}</th>
<th>{{ $t('product.productName') }}</th>
<th>{{ $t('product.productPrice') }}</th>
</tr>
</thead>
<tbody>
<tr v-for="orderItem in order.orderItem">
<td>{{ orderItem.quantity }}x</td>
<td>{{ orderItem.product.brand }}</td>
<td>{{ orderItem.product.name }}</td>
<td>{{ orderItem.product.price }} </td>
</tr>
</tbody>
</v-table>
</v-card>
<orders-card :order="order" />
</v-col>
</v-row>
</v-container>

View File

@@ -0,0 +1,72 @@
<script setup lang="ts">
import cardView from '@/components/cardView.vue';
import { OrderModel } from '@/data/models/orderModel';
defineProps({
order: OrderModel
})
function getDotColor(order, step: number) {
if (order.shippingProgress == step)
{
return "orange"
} else if (order.shippingProgress >= step)
{
return "green"
} else
{
return "grey"
}
}
function formatDateTimeString(string: string) {
let date = new Date(string)
return date.getDate() + '.' + (date.getMonth() + 1) + '.' + date.getFullYear() + ', ' +
date.getHours() + ':' + date.getMinutes()
}
</script>
<template>
<card-view
:title="$t('orders.orderFrom') + ' ' + formatDateTimeString(order.createdAt) + ' ' + $t('oclock')"
:subtitle="$t('totalPrice') + ': ' + order.totalPrice + ' €'"
>
<v-timeline direction="horizontal" side="start">
<v-timeline-item :dot-color="getDotColor(order, 1)" icon="mdi-basket-check">
{{ $t('orders.ordered') }}
</v-timeline-item>
<v-timeline-item :dot-color="getDotColor(order, 2)" icon="mdi-package-variant">
{{ $t('orders.preparingForShipping') }}
</v-timeline-item>
<v-timeline-item :dot-color="getDotColor(order, 3)" icon="mdi-truck-fast">
{{ $t('orders.shipped') }}
</v-timeline-item>
<v-timeline-item :dot-color="getDotColor(order, 4)" icon="mdi-package-check">
{{ $t('orders.delivered') }}
</v-timeline-item>
</v-timeline>
<v-table class="bg-surface-light">
<thead>
<tr>
<th>{{ $t('quantity') }}</th>
<th>{{ $t('product.brand') }}</th>
<th>{{ $t('product.productName') }}</th>
<th>{{ $t('product.productPrice') }}</th>
</tr>
</thead>
<tbody>
<tr v-for="orderItem in order.orderItem">
<td>{{ orderItem.quantity }}x</td>
<td>{{ orderItem.product.brand }}</td>
<td>{{ orderItem.product.name }}</td>
<td>{{ orderItem.product.price }} </td>
</tr>
</tbody>
</v-table>
</card-view>
</template>

View File

@@ -3,6 +3,7 @@ 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';
const userStore = useUserStore()
const theme = useTheme()
@@ -18,7 +19,7 @@ function changeLanguage() {
</script>
<template>
<v-card :title="$t('preferences.pageSetup')" prepend-icon="mdi-view-dashboard" elevation="8">
<card-view :title="$t('preferences.pageSetup')" prepend-icon="mdi-view-dashboard" elevation="8">
<v-container>
<v-row>
<v-col>
@@ -39,5 +40,5 @@ function changeLanguage() {
</v-col>
</v-row>
</v-container>
</v-card>
</card-view>
</template>

View File

@@ -2,8 +2,12 @@
import { BannerStateEnum } from '@/data/enums/bannerStateEnum';
import { useFeedbackStore } from '@/data/stores/feedbackStore';
import axios from 'axios';
import cardView from '@/components/cardView.vue';
import actionDialog from '@/components/actionDialog.vue';
import { ref } from 'vue';
const feedbackStore = useFeedbackStore()
const confirmDialog = ref(false)
function resetDb() {
axios.get("http://127.0.0.1:3000/api/resetdatabase")
@@ -12,20 +16,22 @@ function resetDb() {
feedbackStore.changeBanner(BannerStateEnum.DATABASERESETSUCCESSFUL)
}
})
confirmDialog.value = false
// todo: Request all data
}
function resetSettings() {
// todo
}
</script>
<template>
<v-card :title="$t('preferences.systemSetup')" prepend-icon="mdi-engine" elevation="8">
<card-view :title="$t('preferences.systemSetup')" prepend-icon="mdi-engine" elevation="8">
<v-container>
<v-row>
<v-col class="d-flex justify-center align-center">
<v-btn @click="resetDb" color="primary" prepend-icon="mdi-database-refresh">
<v-btn @click="confirmDialog = true" color="primary" prepend-icon="mdi-database-refresh">
{{ $t('preferences.resetDatabase') }}
</v-btn>
</v-col>
@@ -36,5 +42,14 @@ function resetSettings() {
</v-col>
</v-row>
</v-container>
</v-card>
</card-view>
<action-dialog :title="$t('preferences.resetConfirm')" v-model="confirmDialog" width="600">
<template #actions>
<v-btn variant="outlined" @click="resetDb" color="red">
{{ $t('preferences.resetDatabase') }}
</v-btn>
</template>
</action-dialog>
</template>

View File

@@ -1,6 +1,6 @@
<script setup lang="ts">
import productCard from "./productCard.vue"
import productDetails from "./productDetails.vue"
import productDetails from "./productDetailsDialog.vue"
import { ref, watch } from "vue";
import { useProductStore } from "@/data/stores/productStore";
import { ProductWithCategoryModel } from "@/data/models/productWithCategoryModel";

View File

@@ -1,5 +1,6 @@
<script setup lang="ts">
import { ProductWithCategoryModel } from '@/data/models/productWithCategoryModel';
import cardView from '@/components/cardView.vue';
defineProps({
product: {
@@ -10,7 +11,7 @@ defineProps({
</script>
<template>
<v-card link>
<card-view link>
<v-row>
<v-col cols="3">
<v-sheet color="white">
@@ -76,7 +77,7 @@ defineProps({
</div>
</v-col>
</v-row>
</v-card>
</card-view>
</template>
<style scoped>

View File

@@ -40,7 +40,6 @@ watch(() => props.product.images, () => {
:subtitle="product.category.name"
v-model="showDialog"
>
<template #content>
<v-container class="pt-n3">
<v-row>
<!-- Image col -->
@@ -137,7 +136,6 @@ watch(() => props.product.images, () => {
</v-col>
</v-row>
</v-container>
</template>
<template #actions>
<v-number-input