floranet/src/components/ui/Card.vue

288 lines
5.6 KiB
Vue

<script>
import { defineComponent, ref } from "vue";
import IconEyes from "../icons/IconEyes.vue";
export default defineComponent({
name: "card-component",
components: { IconEyes },
props: {
price: {
type: String,
default: "",
required: true,
},
title: {
type: String,
default: "",
required: true,
},
discount: {
type: String,
default: "",
},
imgSrc: {
type: String,
default: "",
required: true,
},
imgClass: {
type: String,
default: "",
},
headClass: {
type: String,
default: "",
},
isNew: {
type: Boolean,
default: false,
},
size: {
type: String,
default: "md-card",
},
alt: {
type: String,
default: "",
},
id: {
type: Number,
required: true,
},
},
setup({ price, discount }) {
const isLoaded = ref(false);
const isError = ref(false);
const percent = +discount / 100;
//const priceWithoutLetter = ~~price?.replaceAll("€", "");
const priceWithoutLetter = price;
const finalValue = ~~(priceWithoutLetter - priceWithoutLetter * percent);
console.log(price);
const onLoad = () => {
isLoaded.value = true;
};
const onError = () => {
isError.value = true;
};
return {
onLoad,
onError,
isLoaded,
isError,
finalValue,
priceWithoutLetter,
};
},
});
</script>
<template>
<div class="card-container" :class="size">
<RouterLink
:to="`/product/${id}`"
class="card-container-head"
:class="[headClass]"
role="heading"
>
<div v-if="isNew || discount" class="tags">
<p v-if="isNew" class="tag new">Nuevo</p>
<p v-if="discount" class="tag discount">-{{ discount }}%</p>
</div>
<img
class="card-img"
:class="[imgClass]"
:src="imgSrc && !isError ? imgSrc : '../../assets/empty-img.jpg'"
:alt="alt"
:key="imgSrc"
@load="onLoad"
@error="onError"
/>
<q-skeleton
v-if="!isLoaded"
class="skeleton"
width="100%"
height="100%"
/>
<div class="head-hovered">
<IconEyes />
<p class="head-hovered-paragraph">Ver producto</p>
</div>
</RouterLink>
<div class="card-container-body">
<p class="card-name" v-if="title">{{ title }}</p>
<div class="card-values">
<p class="price" v-if="finalValue">{{ finalValue }}€</p>
<p class="price offer tachado" v-if="+price !== finalValue">
{{ price }}
</p>
</div>
</div>
</div>
</template>
<style lang="scss" scoped>
.card-container {
display: flex;
flex-direction: column;
gap: 12px;
user-select: none;
height: 100%;
&:focus {
outline: 2px solid $secondary;
}
&.md-card {
& .card-container-head {
height: 300px;
@media only screen and (min-width: $med-hg) {
height: 352px;
}
@media only screen and (max-width: $med-md) {
border-radius: 10px;
height: 188px;
}
}
}
&.lg-card {
& .card-container-head {
height: 409px;
@media only screen and (max-width: $med-lg) {
border-radius: 10px;
height: 188px;
}
}
}
& .card-container-head {
border-radius: 15px;
overflow: hidden;
position: relative;
height: 100%;
max-height: 409px;
&.list-products-head {
min-height: 365px;
@media only screen and (max-width: $med-sm) {
min-height: 190px;
}
}
&:focus-visible {
outline: 2px solid $primary-light;
}
&:hover {
& .tags {
opacity: 0;
visibility: hidden;
}
& .head-hovered {
visibility: visible;
background-color: $primary-dark-transparent;
}
}
& .tags,
& .head-hovered {
transition: 100ms ease-out;
}
& .tags {
position: absolute;
left: 15px;
top: 14px;
display: flex;
gap: 4px;
& .tag {
border-radius: 3px;
padding: 2px 6px 2px 9px;
font-family: $font-lora;
user-select: none;
font-weight: 600;
font-size: $font-12;
&.new {
color: $white;
background: $primary-dark;
}
&.discount {
background: $primary-light;
color: $primary-dark;
}
@media only screen and (max-width: $med-lg) {
font-size: $font-10;
}
}
}
& .card-img {
width: 100%;
height: 100%;
object-fit: cover;
&.list-products {
@media only screen and (min-width: calc($med-md + 1px)) {
min-height: 352px;
}
@media only screen and (max-width: $med-md) {
min-height: 190px;
}
}
&.carousel {
max-height: 410px;
}
}
& .skeleton {
position: absolute;
inset: 0;
background-color: $primary;
opacity: 0.5;
}
& .head-hovered {
position: absolute;
inset: 0;
visibility: hidden;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
gap: 4px;
& .head-hovered-paragraph {
font-family: $font-lora;
color: $white;
}
}
@media only screen and (max-width: $med-md) {
border-radius: 10px;
}
}
& .card-container-body {
display: flex;
flex-direction: column;
gap: 8px;
text-align: start;
& .card-values {
display: flex;
gap: 6px;
}
}
}
</style>