You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
geodata-catalog/frontend/src/components/Navbar.vue

182 lines
7.1 KiB

<template>
<div>
<va-navbar shape color="#79589f" class="navbar">
<template #left>
<va-navbar-item class="top-icon">
<va-popover message="Карта" prevent-overflow stick-to-edges>
<va-icon size="3rem" color="#babfc2" name="public" @click="$router.push('/')" />
</va-popover>
</va-navbar-item>
<slot></slot>
</template>
<template #right>
<va-dropdown :close-on-content-click="false" placement="bottom-end" prevent-overflow>
<template #anchor>
<va-navbar-item class="top-icon">
<va-popover message="Корзина" prevent-overflow stick-to-edges>
<va-icon size="3rem" color="#babfc2" name="shopping_basket" @click="" />
</va-popover>
</va-navbar-item>
</template>
<va-dropdown-content>
<va-card class="flex">
<va-card-title>Корзина</va-card-title>
<va-card-content v-if="!itemsInCart.length" class="cart-inner cart-empty">
<p class="cart-empty__text">Корзина пуста</p>
<p class="cart-empty__text">Попробуйте перейти на страницу образца</p>
<p v-if="isItemPath" class="cart-empty__text">
и <va-button @click="addToCart">Добавить в корзину</va-button>
</p>
</va-card-content>
<template v-else>
<va-card-actions align="between">
<template v-if="isItemPath">
<va-button v-if="!isPathInCart" @click="addToCart">Добавить в корзину
</va-button>
<va-button v-else @click="removeFromCart">Убрать из корзины</va-button>
</template>
<va-button @click="copyCart">{{ copyCartText }}</va-button>
<va-button color="warning" @click="emptyCart">Очистить корзину</va-button>
</va-card-actions>
<va-card-content class="cart-inner">
<va-data-table :items="itemsInCart" :columns="filteredColumns" :hoverable="true"
:clickable="true" select-mode="single" @row:click="(e) => handleClick(e)"
class="similar-items-table" />
</va-card-content>
</template>
</va-card>
</va-dropdown-content>
</va-dropdown>
<va-navbar-item class="top-icon">
<va-popover message="Аккаунт" prevent-overflow stick-to-edges>
<va-icon size="3rem" color="#babfc2" name="account_box" @click="$emit('accountClick')" />
</va-popover>
</va-navbar-item>
</template>
</va-navbar>
</div>
</template>
<script>
export default {
name: "navbar",
data() {
return {
columnHeaders: [],
showColumns: [
"internal_id",
"description",
],
itemsInCart: [],
cartListCopied: false,
}
},
methods: {
addToCart() {
if (!this.isPathInCart) {
fetch(`/api/v1/item/${this.$route.params.id}`)
.then(res => res.json())
.then(data => {
this.itemsInCart.push(data);
localStorage.setItem("cart", JSON.stringify(this.itemsInCart));
this.cartListCopied = false;
})
.catch((e) => console.log(e));
}
},
removeFromCart() {
const routeId = Number.parseInt(this.$route.params.id);
this.itemsInCart = this.itemsInCart.filter(item => item.id !== routeId)
localStorage.setItem("cart", JSON.stringify(this.itemsInCart));
this.cartListCopied = false;
},
copyCart() {
const textToCopy = this.itemsInCart
.map(item => item.internal_id)
.reduce((list, item_id) => list + "," + item_id)
navigator.clipboard.writeText(textToCopy)
.then(() => this.cartListCopied = true)
.catch(e => console.log("Error copying item list ("
+ textToCopy
+ ") from cart: "
+ e))
},
emptyCart() {
this.itemsInCart = [];
localStorage.removeItem("cart");
},
restoreCart() {
if (localStorage.getItem("cart")) {
this.itemsInCart = JSON.parse(localStorage.getItem("cart"))
}
},
async fetchColumnHeaders() {
fetch(`/api/v1/headers/`)
.then(res => res.json())
.then(data => this.columnHeaders = data)
.catch((e) => console.log(e));
},
handleClick(e) {
if (String(e.item.id) !== this.$route.params.id) {
window.open(`/items/${e.item.id}`, '_blank')
}
}
},
mounted() {
this.fetchColumnHeaders();
this.restoreCart()
},
computed: {
isItemPath() {
return this.$route.name === "item-details";
},
filteredColumns() {
return this.columnHeaders
.filter(header => this.showColumns.includes(header.database))
.sort((header1, header2) => {
return this.showColumns.indexOf(header1.database) - this.showColumns.indexOf(header2.database)
})
.map(header => {
return {
key: header.database,
label: header.spreadsheet,
sortable: true,
}
})
},
isPathInCart() {
const routeId = Number.parseInt(this.$route.params.id);
return this.itemsInCart.some(item => item.id === routeId)
},
copyCartText() {
return (this.cartListCopied ? 'Скопировано ✓✓' : 'Скопировать список образцов')
}
},
}
</script>
<style lang="css" scoped>
.navbar {
position: relative;
}
.cart-inner {
display: flex;
flex-direction: column;
min-width: 30rem;
min-height: 30rem;
}
.cart-empty {
justify-content: center;
}
.cart-empty__text {
margin: 1rem auto;
}
</style>