{"version":3,"file":"ProductCard2-bTZ-7PjQ.js","sources":["../../../app/javascript/src/modules/Explore/Product2/index.vue","../../../app/javascript/src/modules/Explore/ProductCard2.vue"],"sourcesContent":["<template>\n <div ref=\"root\" class=\"explore-product\" @click=\"$emit('click', $event)\">\n <a class=\"explore-product__link\" :target=\"openInNewTab ? '_blank' : '_self'\" :href=\"externalLink\" @click='productClick'>\n <div class=\"feature-image-section\">\n <FeatureImage :url=\"featureImageUrl\" :inactive=\"inactive\"/>\n <ProductCardHero :src=\"heroImageUrl\" />\n </div>\n\n <div class=\"product__detail\">\n <div class=\"product__country\">\n <span>\n {{ country }}\n </span>\n <span v-if=\"reference\">\n ID: {{ reference }}\n </span>\n </div>\n <div class=\"product__title\">\n {{ title }}\n </div>\n <slot name=\"productMeta\"/>\n <slot name=\"detailFooter\"/>\n </div>\n <div class=\"product__tags\">\n <div class=\"product__spots-left\" v-if=\"showSpotsLeft\">\n {{ t('spots_left', spotsLeft, { count: spotsLeft }) }}\n </div>\n <div class=\"product__mba-exclusive\" v-if=\"isMba\">\n {{ t('mba_trip') }}\n </div>\n </div>\n <div class=\"product__right-tags\">\n <div class=\"product__cancelled\" v-if=\"status\">\n {{ t(status) }}\n </div>\n </div>\n </a>\n </div>\n</template>\n\n<script setup>\nimport { isEmpty } from 'lodash';\nimport { trackClick, trackImpression, isInViewport } from '@/utils/eec.js'\nimport { blankHref } from '@/utils/stringUtils.js';\nimport { ref, computed, onBeforeUnmount, onMounted } from 'vue';\nimport { useShared } from \"@/helpers/vueHelpers.js\";\nimport FeatureImage from \"./FeatureImage.vue\"\nimport ProductCardHero from \"@/modules/Explore/Product2/ProductCardHero.vue\";\n\nconst root = ref(null)\nconst { t } = useShared();\n\nconst props = defineProps({\n featureImageUrl: String,\n heroImageUrl: String,\n country: String,\n title: String,\n isMba: { type: Boolean, default: false },\n spotsLeft: { type: Number, default: undefined },\n position: Number,\n trackingHash: { type: Object, default: () => ({}) },\n status: String,\n externalLink: { type: String, required: true },\n reference: { type: [Number, String], default: null },\n product: Object,\n openInNewTab: { type: Boolean, default: false }\n});\n\ndefineEmits(['click']);\n\nonMounted(() => {\n trackProductImpression();\n window.addEventListener('scroll', trackProductImpression);\n});\n\nonBeforeUnmount(() => {\n window.removeEventListener('scroll', trackProductImpression);\n});\n\nconst inactive = computed(() => props.status == \"cancelled\" || props.status == \"payment_error\");\nconst showSpotsLeft = computed(() => props.spotsLeft === null ? false : props.spotsLeft >= 0);\n\nfunction productClick(evt) {\n if (isEmpty(props.trackingHash)) return;\n if (blankHref(props.externalLink)) {\n trackClick(props.trackingHash, null, evt);\n }\n}\n\nlet impressionTracked = false;\n\nfunction trackProductImpression() {\n if (isEmpty(props.trackingHash)) return;\n if (!impressionTracked && isInViewport(root.value)) {\n trackImpression(props.trackingHash);\n impressionTracked = true;\n }\n}\n</script>\n\n<style lang=\"scss\" scoped>\n\n@mixin tag {\n text-transform: uppercase;\n background-color: $white;\n border-radius: $spacing-1;\n padding: $spacing-1 $spacing-2;\n font-size: $text-xs;\n font-weight: $font-bold;\n width: min-content;\n white-space: nowrap;\n}\n\n.explore-product {\n cursor: pointer;\n overflow: hidden;\n font-weight: $font-semibold;\n padding: 16px;\n border-radius: 15px;\n border: 1px solid $grey-25;\n background: white;\n box-shadow: 0 4px 12px 0 rgba(164, 164, 164, 0.10);\n\n &:hover {\n border-radius: 15px;\n border: 1px solid $grey-25;\n background: $green-50;\n box-shadow: 0 4px 12px 0 rgba(164, 164, 164, 0.10);\n }\n\n &, a {\n flex: 1;\n @include flex-column;\n position: relative;\n gap: 16px;\n }\n\n a:hover {\n color: unset;\n }\n}\n\n.feature-image-section {\n position: relative;\n}\n\n.product__country {\n color: $gray;\n font-size: 12px;\n font-weight: 700;\n line-height: 14px;\n text-transform: uppercase;\n}\n\n.product__detail {\n flex-grow: 1;\n display: grid;\n row-gap: $spacing-2;\n align-content: start;\n}\n\n.product__tags {\n position: absolute;\n top: $spacing-3;\n left: $spacing-3;\n display: grid;\n gap: $spacing-2;\n}\n\n.product__spots-left {\n color: $brand-secondary;\n @include tag;\n}\n\n.product__mba-exclusive {\n color: $brand-primary;\n @include tag;\n}\n\n.product__right-tags {\n position: absolute;\n top: $spacing-3;\n right: $spacing-3;\n display: grid;\n gap: $spacing-2;\n}\n\n.product__cancelled {\n color: $black;\n @include tag;\n}\n</style>\n\n<i18n lang=\"yaml\">\nen:\n spots_left: 'Sold out | {count} spot left | {count} spots left'\n mba_trip: MBA Trip\n cancelled: Cancelled\n payment_error: Payment error\n</i18n>\n","<template>\n <Product\n :featureImageUrl=\"product.itinerary.featureImageUrl\"\n :heroImageUrl=\"product.itinerary.heroImageUrl\"\n :country=\"product.itinerary.targetCountryName\"\n :title=\"product.itinerary.title\"\n :isMba=\"product.itinerary.mbaExclusive\"\n :externalLink=\"externalLink || product.meta.link\"\n :spotsLeft=\"product.event.spotsLeft\"\n :product=\"product\"\n :trackingHash=\"trackingHash\"\n :openInNewTab=\"openInNewTab\"\n >\n <template #productMeta>\n <div class=\"product__price\">\n <span>From </span>\n <Money\n :currency=\"product.itinerary.baseCurrency\"\n :options=\"{ maximumFractionDigits: 0, currencyDisplay: 'code' }\"\n :value=\"product.event.lowestAmountCents\"\n inline\n />\n </div>\n <div class=\"product__date\">\n {{ eventDate(product.event.startsAt, product.event.timezone) }} -\n <span>\n {{ t('nights', { count: product.itinerary.durationNights }, product.itinerary.durationNights) }}\n </span>\n </div>\n </template>\n </Product>\n</template>\n\n<script setup>\nimport { useShared } from \"@/helpers/vueHelpers.js\";\nimport Product from './Product2/index.vue';\n\nimport { formatDate } from '@/utils/dateUtils.ts';\nimport Money from '@/components/Money.vue';\n\nconst { t } = useShared();\n\ndefineProps({\n product: Object,\n booking: Object,\n externalLink: String,\n trackingHash: { type: Object, default: () => ({}) },\n openInNewTab: { type: Boolean, default: false }\n})\n\nfunction eventDate(date, timezone) {\n if (date && timezone) {\n return formatDate(date, timezone, 'MMM D, YYYY');\n }\n}\n</script>\n\n<style lang=\"scss\" scoped>\n.product__price {\n color: $brand-secondary;\n font-size: 14px;\n line-height: 16px;\n}\n\n.product__date {\n color: $gray;\n font-size: 12px;\n line-height: 14px;\n text-transform: uppercase;\n}\n</style>\n\n<i18n lang=\"yaml\">\nen:\n loading: Loading ...\n trips_available: 'No trip available | {count} trip available | {count} trips available'\n mba_trip: MBA Trip\n nights: '{count} night | {count} nights'\n</i18n>\n"],"names":["root","ref","t","useShared","props","__props","onMounted","trackProductImpression","onBeforeUnmount","inactive","computed","showSpotsLeft","productClick","evt","isEmpty","blankHref","trackClick","impressionTracked","isInViewport","trackImpression","eventDate","date","timezone","formatDate"],"mappings":"o7DAiDA,MAAMA,EAAOC,EAAI,IAAI,EACf,CAAE,EAAAC,CAAG,EAAGC,EAAW,EAEnBC,EAAQC,EAkBdC,EAAU,IAAM,CACdC,EAAwB,EACxB,OAAO,iBAAiB,SAAUA,CAAsB,CAC1D,CAAC,EAEDC,EAAgB,IAAM,CACpB,OAAO,oBAAoB,SAAUD,CAAsB,CAC7D,CAAC,EAED,MAAME,EAAWC,EAAS,IAAMN,EAAM,QAAU,aAAeA,EAAM,QAAU,eAAe,EACxFO,EAAgBD,EAAS,IAAMN,EAAM,YAAc,KAAO,GAAQA,EAAM,WAAa,CAAC,EAE5F,SAASQ,EAAaC,EAAK,CACrBC,EAAO,QAACV,EAAM,YAAY,GAC1BW,EAAUX,EAAM,YAAY,GAC9BY,EAAWZ,EAAM,aAAc,KAAMS,CAAG,CAE5C,CAEA,IAAII,EAAoB,GAExB,SAASV,GAAyB,CAC5BO,EAAO,QAACV,EAAM,YAAY,GAC1B,CAACa,GAAqBC,EAAalB,EAAK,KAAK,IAC/CmB,EAAgBf,EAAM,YAAY,EAClCa,EAAoB,GAExB,mkDCzDA,KAAM,CAAE,EAAAf,CAAG,EAAGC,EAAW,EAUzB,SAASiB,EAAUC,EAAMC,EAAU,CACjC,GAAID,GAAQC,EACV,OAAOC,EAAWF,EAAMC,EAAU,aAAa,CAEnD"}