{"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"}