170 lines
4.6 KiB
Vue
170 lines
4.6 KiB
Vue
<template>
|
|
<router-link :to="`/product/${uid}`">
|
|
<article :class="['product-card', `product-card-${type}`]">
|
|
<img :src="coverPath" :alt="title" />
|
|
<div>
|
|
<h2 v-if="type != 'minimal'">
|
|
{{ category[category.length - 1]?.name }}
|
|
</h2>
|
|
<h1>{{ title }}</h1>
|
|
<ul v-if="type != 'minimal' && stars">
|
|
<li v-for="i in 5" :key="i">
|
|
<img :src="`/icons/star.svg`" :class="starsClass(i)" />
|
|
</li>
|
|
</ul>
|
|
<template v-if="type != 'minimal'">
|
|
<Button :icon="`isax isax-heart${like ? '5' : ''}`" severity="secondary" text
|
|
@click.prevent="favorite.update(id)" />
|
|
</template>
|
|
<div v-if="type != 'minimal'">
|
|
<div>
|
|
<span>
|
|
<b>{{ numberFormat(price) }}</b>
|
|
<small>{{ $t('priceUnit') }}</small>
|
|
</span>
|
|
<s v-if="type == 'action' && specialPrice">
|
|
{{ numberFormat(specialPrice) }}
|
|
</s>
|
|
</div>
|
|
<ProductQuantity v-if="type == 'action'" v-model="quantity" :range="orderRange" />
|
|
</div>
|
|
</div>
|
|
</article>
|
|
</router-link>
|
|
</template>
|
|
|
|
<script setup>
|
|
const props = defineProps({
|
|
data: { type: Object, default: {} },
|
|
type: { type: String, default: 'main' }
|
|
})
|
|
const { _id: id, uid, coverPath, category = [], title, price, specialPrice, stars, orderRange } = props.data
|
|
|
|
const favorite = useFavoritesStore()
|
|
const like = computed(() => favorite.find(id))
|
|
|
|
const cart = useCartStore()
|
|
const quantity = computed({
|
|
get: () => cart.find(id)?.quantity || 0,
|
|
set: (v) => cart.update(id, v)
|
|
})
|
|
|
|
const starsClass = (i) => (i > stars ? 'opacity-25' : '')
|
|
const numberFormat = (number) =>
|
|
new Intl.NumberFormat('fa-IR', { maximumSignificantDigits: 3 }).format(number)
|
|
</script>
|
|
|
|
<style lang="scss">
|
|
.product-card {
|
|
box-shadow: 0px 2px 14px 0px #e5eef5;
|
|
@apply bg-white rounded-[0.6rem] border flex flex-col relative;
|
|
|
|
&>img {
|
|
@apply w-[3.8rem] h-[3.8rem] lg:w-[10.3rem] lg:h-[10.3rem] self-center object-contain object-bottom;
|
|
}
|
|
|
|
&>div {
|
|
@apply flex flex-col grow;
|
|
|
|
h2 {
|
|
@apply text-[#7F7F7F] text-[0.6em] leading-5 lg:text-sm font-medium font-vazir;
|
|
}
|
|
|
|
h1 {
|
|
@apply text-[#333] text-[0.7em] leading-5 lg:text-base font-bold font-vazir mt-1 line-clamp-1 lg:line-clamp-2;
|
|
}
|
|
|
|
ul {
|
|
@apply hidden lg:flex gap-1 mt-3 ;
|
|
|
|
img {
|
|
@apply w-4 h-4;
|
|
}
|
|
}
|
|
|
|
&>div {
|
|
@apply flex justify-between items-center gap-4 mt-auto;
|
|
|
|
&>div:nth-of-type(1) {
|
|
@apply flex flex-col items-end font-vazir;
|
|
|
|
span {
|
|
@apply text-[#333];
|
|
|
|
small {
|
|
@apply text-[0.6em] lg:text-[0.8em] font-medium mr-1;
|
|
}
|
|
|
|
b {
|
|
@apply text-sm lg:text-lg;
|
|
}
|
|
}
|
|
|
|
s {
|
|
@apply mt-1 text-[#7F7F7F] text-[0.7em] lg:text-[0.9em] font-medium;
|
|
}
|
|
}
|
|
}
|
|
|
|
&>button {
|
|
@apply absolute rounded-full w-12 h-12 #{!important};
|
|
|
|
.p-button-icon {
|
|
@apply text-base lg:text-2xl text-[#333];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
.product-card-main {
|
|
@apply w-[9.3rem] h-[11.4rem] p-3 lg:w-[18.25rem] lg:h-[25.4rem] lg:p-6 lg:pb-8;
|
|
|
|
&>div {
|
|
h2 {
|
|
@apply mt-6;
|
|
}
|
|
|
|
&>button {
|
|
@apply absolute -bottom-1 -left-1 lg:bottom-[1.4rem] lg:left-3.5;
|
|
}
|
|
}
|
|
}
|
|
|
|
.product-card-action {
|
|
@apply w-[12.6rem] h-[16.5rem] lg:w-[18.3rem] lg:h-[29rem] p-3 lg:p-5;
|
|
|
|
&>img {
|
|
@apply max-lg:mt-1.5 max-lg:w-[5.7rem] max-lg:h-[5.7rem];
|
|
}
|
|
|
|
&>div {
|
|
h2 {
|
|
@apply mt-9;
|
|
}
|
|
|
|
&>div {
|
|
@apply flex-row-reverse;
|
|
}
|
|
|
|
&>button {
|
|
@apply absolute top-1 left-1 lg:top-2 lg:left-2;
|
|
}
|
|
}
|
|
}
|
|
|
|
.product-card-minimal {
|
|
@apply w-[10.1rem] h-[11.4rem] px-2.5 gap-[1.9rem] items-center;
|
|
@apply lg:w-[16.5rem] lg:h-[16.5rem] py-6 lg:p-4 lg:gap-6;
|
|
|
|
&>div {
|
|
h1 {
|
|
@apply text-center text-[0.7em] lg:text-base leading-4;
|
|
}
|
|
}
|
|
|
|
img {
|
|
@apply w-[4.7rem] h-20 lg:w-[8.4rem] lg:h-[8.9rem];
|
|
}
|
|
}
|
|
</style>
|