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.
 
 
 
 
 
 

578 lines
14 KiB

<template>
<div class="white-bkg">
<header>
<div class="header__col">
<button class="btn btn--primary" @click="goBack">
<svg
xmlns="http://www.w3.org/2000/svg"
class="icon icon-tabler icon-tabler-chevrons-left"
width="24"
height="24"
viewBox="0 0 24 24"
stroke-width="3"
stroke="#ffffff"
fill="none"
stroke-linecap="round"
stroke-linejoin="round"
>
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
<polyline points="11 7 6 12 11 17" />
<polyline points="17 7 12 12 17 17" />
</svg>
back
</button>
</div>
<div class="header__col">
<Logo />
</div>
<div class="header__col" />
</header>
<main class="main-with-header">
<ChosenFlights
:selected-orig="selectedOrig"
:selected-dest="selectedDest"
:departure="formattedDate($route.params.departure)"
:departure-time="selectedSchedule && selectedSchedule.fields && selectedSchedule.fields.Departure_TimeL"
style="margin: 0 1rem;"
/>
<div class="schedule-wrapper">
<ul class="schedule-grid">
<li
v-for="schedule in schedules"
:key="schedule.fields.Record_ID"
:class="[
'grid__row',
{ 'grid__row--selected': selectedSchedule.id == schedule.id },
]"
>
<div class="row__check">
<label class="radio radio--sched" :for="schedule.id">
<input :id="schedule.id" type="radio" name="schedules">
<span @click="selectedSchedule = { ...schedule }">
<svg
xmlns="http://www.w3.org/2000/svg"
class="icon icon-tabler icon-tabler-check"
width="24"
height="24"
viewBox="0 0 24 24"
stroke-width="3"
stroke="#ffffff"
fill="none"
stroke-linecap="round"
stroke-linejoin="round"
>
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
<path d="M5 12l5 5l10 -10" />
</svg>
</span>
</label>
</div>
<div class="row__dep">
<label class="text--muni">
{{ selectedOrig.municipality }}
</label>
<h1 class="text--time">
{{ schedule.fields.Departure_TimeL }}
</h1>
</div>
<div class="row__trip">
<svg
xmlns="http://www.w3.org/2000/svg"
class="icon icon-tabler icon-tabler-arrow-right-circle"
width="100"
height="100"
viewBox="0 0 24 24"
stroke-width="1.5"
stroke="#007fff"
fill="none"
stroke-linecap="round"
stroke-linejoin="round"
>
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
<path d="M18 15l3 -3l-3 -3" />
<circle cx="5" cy="12" r="2" />
<path d="M7 12h14" />
</svg>
</div>
<div class="row__arr">
<label class="text--muni">
{{ selectedDest.municipality }}
</label>
<h1 class="text--time">
{{ schedule.fields.Arrival_TimeL }}
</h1>
</div>
<div class="row__info">
<h2 class="text--carrier">
{{ schedule.fields.Carrier_Name }}
</h2>
<span v-if="schedule.fields.Flight_Number" class="text--flight-num">
Flight No. {{ schedule.fields.Flight_Number }}
</span>
<span class="text--dow">
{{ schedule.fields.Frequency_Convert }}
</span>
<span class="badge--avail">
Available until
<strong>{{ formattedDate(schedule.fields.Effective_End) }}</strong>
</span>
</div>
</li>
</ul>
</div>
<div
:class="[
'flyout-container',
{ 'flyout-container--hide': !selectedSchedule.id },
{ 'flyout-container--show': selectedSchedule.id },
]"
>
<div class="flyout">
<button
v-if="
selectedSchedule &&
selectedSchedule.fields &&
selectedSchedule.fields.IsExpedia &&
selectedSchedule.fields.IsExpedia[0] !== 'true'
"
class="btn btn--primary"
@click="goToCarrier"
>
see flights
</button>
<div
v-if="
selectedSchedule &&
selectedSchedule.fields &&
selectedSchedule.fields.IsExpedia &&
selectedSchedule.fields.IsExpedia[0] === 'true'
"
class="book-container"
>
<div>
<label for="">How Many Adults?</label>
<v-select
v-model="numAdult"
:options="[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]"
auto
/>
</div>
<div>
<label for="">How Many Children?</label>
<v-select
v-model="numChild"
:options="[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]"
:menu-props="{ top: true, offsetY: true }"
/>
</div>
<button class="btn btn--primary" @click="book">
book now!
</button>
</div>
</div>
</div>
</main>
</div>
</template>
<script>
export default {
data () {
return {
schedules: [],
startingDate: '',
selectedSchedule: {},
selectedDays: [],
selectedOrig: {},
selectedDest: {},
numAdult: 1,
numChild: 0
}
},
async fetch () {
// console.log(this.$route.params.o)
const today = new Date().toLocaleDateString('en-CA')
// function addDays (date, days) {
// const result = new Date(date)
// result.setDate(result.getDate() + days)
// return result
// }
// const tomorrow = addDays(new Date(), 1).toLocaleDateString('en-CA')
const scheduleFetchFilterFormula = `AND(Is_Current="Yes",Origin_IATA="${this.$route.params.o}",Destination_IATA="${this.$route.params.d}",Effective_End>"${today}",SEARCH("${new Date(this.$route.params.departure).getDay()}",Frequency)>0)`
// console.log(scheduleFetchFilterFormula)
const scheduleFetchSort = '&sort[0][field]=Departure_TimeL&sort[0][direction]=asc'
const response = await fetch(`https://api.airtable.com/v0/appiQwfVZixRgRICe/Schedule?filterByFormula=${scheduleFetchFilterFormula}${scheduleFetchSort}`, {
method: 'GET',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
Authorization: 'Bearer keyJ2ht64ZSN57AG1'
}
})
const data = await response.json()
// console.log(data)
this.schedules = [...data.records]
},
created () {
// console.log(this.$route.path)
if (this.$route && this.$route.params && this.$route.params.o) {
this.fetchSingleAirport(this.$route.params.o, true)
}
if (this.$route && this.$route.params && this.$route.params.d) {
this.fetchSingleAirport(this.$route.params.d, false)
}
},
methods: {
formattedDate (date) {
const thisDate = new Date(date)
const month = thisDate.toLocaleString('en-us', { month: 'short' })
const year = ((thisDate.getFullYear() !== new Date().getFullYear()) ? ', ' + thisDate.getFullYear() : '')
return month + ' ' + thisDate.getUTCDate() + year
},
daysList (days) {
const list = days.split(', ').map((day) => {
const name = day.toLowerCase().slice(0, -1)
let num
switch (name) {
case 'su':
num = 0
break
case 'mo':
num = 1
break
case 'tu':
num = 2
break
case 'we':
num = 3
break
case 'th':
num = 4
break
case 'fr':
num = 5
break
case 'sa':
num = 6
break
default:
break
}
return {
name,
num
}
})
return list.sort(function (a, b) {
return a.num - b.num
})
},
goBack () {
this.$router.go(-1)
},
// book2 (schedule) {
// if (schedule.fields.IsExpedia[0] === 'true') {
// this.startingDate = new Date()
// this.selectedSchedule = schedule.fields
// this.selectedDays = this.daysList(schedule.fields.Frequency_Convert)
// } else {
// window.open(schedule.fields['BookingLink (from Carriers_Alaska)'][0])
// }
// },
book () {
// add tracker
window.open(`https://www.anrdoezrs.net/links/100449149/type/am/https://www.expedia.com/go/flight/search/oneway/${this.$route.params.departure}/${this.$route.params.departure}?langid=1033&FromAirport=${this.selectedSchedule.fields.Origin_IATA}&FromTime=${this.selectedSchedule.fields.Departure_TimeL}&ToTime=${this.selectedSchedule.fields.Arrival_TimeL}&ToAirport=${this.selectedSchedule.fields.Destination_IATA}&Class=3&NumAdult=${this.numAdult}&NumChild=${this.numChild}`)
},
goToCarrier () {
// add tracker
window.open(this.selectedSchedule.fields['BookingLink (from Carriers_Alaska)'][0])
},
clearSelectedSchedule () {
// console.log('clear')
this.startingDate = ''
this.selectedSchedule = {}
},
async fetchSingleAirport (iata, isOrig) {
const airportFetchFilterFormula =
isOrig
? `AND(Is_Origin=1,{IsCurrent-AsOrigin}="Yes",Airport_IATA="${iata}")`
: `AND(Is_Destination=1,{IsCurrent-AsDest}="Yes",Airport_IATA="${iata}")`
const response = await fetch(`https://api.airtable.com/v0/appiQwfVZixRgRICe/Airports_IATA?filterByFormula=${airportFetchFilterFormula}`, {
method: 'GET',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
Authorization: 'Bearer keyJ2ht64ZSN57AG1'
}
})
const mapData = await response.json()
const thisAirport = {
iata: mapData.records[0].fields.Airport_IATA,
lat: mapData.records[0].fields.Latitude_Deg,
long: mapData.records[0].fields.Longitude_Deg,
icon: mapData.records[0].fields.Icon_Url,
name: mapData.records[0].fields.Airport_Name,
municipality: mapData.records[0].fields.Municipality,
type: mapData.records[0].fields.Type,
search: mapData.records[0].fields.Search_Field
}
switch (isOrig) {
case true:
this.selectedOrig = { ...thisAirport }
break
case false:
this.selectedDest = { ...thisAirport }
break
default:
break
}
}
}
}
</script>
<style lang="scss">
.schedule-wrapper {
display: flex;
flex-direction: column;
align-items: center;
}
.schedule-grid {
display: flex;
flex-direction: column;
gap: 1rem;
margin: 2rem 2rem 2rem 2rem;
}
.grid__row {
display: flex;
flex-direction: row;
align-items: center;
gap: 1rem;
padding: 1rem 1rem 1rem 4rem;
flex-wrap: wrap;
border-radius: 2rem;
}
.grid__row:nth-child(odd) {
background: #eee;
}
label {
font-size: 0.75rem;
font-weight: 700;
color: white;
display: block;
}
.field__content {
font-size: 1.5rem;
}
.dow-grid {
width: 200px;
display: grid;
grid-template-columns: 1fr 1fr 1fr 1fr 1fr 1fr 1fr;
gap: 0.5rem;
}
.dow-grid__day {
font-size: 0.8rem;
border: 1px solid #ccc !important;
display: flex;
align-items: center;
justify-content: center;
border-radius: 3px !important;
text-transform: capitalize;
}
.day--su {
grid-column: 1 / span 1;
}
.day--mo {
grid-column: 2 / span 1;
}
.day--tu {
grid-column: 3 / span 1;
}
.day--we {
grid-column: 4 / span 1;
}
.day--th {
grid-column: 5 / span 1;
}
.day--fr {
grid-column: 6 / span 1;
}
.day--sa {
grid-column: 7 / span 1;
}
.row__trip {
display: flex;
align-items: center;
}
.row__trip svg {
margin-bottom: -0.5rem;
width: 3.5rem;
height: 3.5rem;
margin-left: -1rem;
margin-right: -1rem;
}
.shape--trip {
height: 0.4rem;
width: 2rem;
background: #007fff;
display: block;
margin-top: 1rem;
position: relative;
}
.shape--trip::before {
height: 0.8rem;
width: 0.8rem;
background: #fff;
border: 0.02rem solid #007fff;
border-radius: 999px;
content: "";
position: absolute;
top: -0.15rem;
left: -0.5rem;
}
.shape--trip::after {
height: 0.8rem;
width: 0.8rem;
background: #007fff;
border: 0.02rem solid #007fff;
border-radius: 999px;
content: "";
position: absolute;
top: -0.15rem;
right: -0.5rem;
}
h1 {
font-size: 3rem;
line-height: 0.85;
}
h2 {
font-size: 2rem;
line-height: 1;
}
label.text--muni {
color: #007fff;
line-height: 1;
padding-left: 0.3rem;
}
span.text--flight-num {
font-weight: 700;
margin-right: 0.5rem;
}
span.text--dow {
font-weight: 300;
font-size: 0.8rem;
color: #007fff;
}
span.badge--avail {
border-radius: 999px;
border: 1px solid gray;
color: gray;
padding: 0.2em 0.8em;
line-height: 1;
font-size: 0.8rem;
display: block;
width: fit-content;
}
.radio span {
border-radius: 999px;
border: 3px solid #007fff;
background-color: white;
height: 2rem;
width: 2rem;
display: flex;
position: relative;
transition: all 0.3s;
align-items: center;
justify-content: center;
}
.radio span svg {
transition: all 0.3s;
stroke: #eee;
}
.radio span:hover {
background: #007fff;
}
.radio input:checked + span {
background: #007fff;
}
.radio input:checked + span svg {
stroke: white;
}
.radio input {
display: none;
}
.row__info {
min-width: fit-content;
}
.row__check {
margin-left: -3rem;
}
.book-container {
display: flex;
flex-direction: column;
justify-content: stretch;
gap: 1rem;
}
.book-container label {
text-transform: uppercase;
font-size: 1rem;
font-weight: 300;
}
</style>