Browse Source

linked up map and pickers, styled, everything's working. needs tweaks only.

master
Your Name 3 years ago
parent
commit
9ab170d3d4
4 changed files with 516 additions and 369 deletions
  1. +160
    -0
      components/AirportPicker.vue
  2. +111
    -171
      components/Map.vue
  3. +0
    -178
      components/PickerOrigin.vue
  4. +245
    -20
      pages/go.vue

+ 160
- 0
components/AirportPicker.vue View File

@ -0,0 +1,160 @@
<template>
<div class="picker-wrap">
<!-- <pre style="position: fixed; z-index: 500; right: 0; top: 7rem; font-size: 0.6rem; color: orange;">
{{ selectedAirport }}
</pre> -->
<v-select
:value="selectedAirportComp"
label="iata"
:options="airports"
:filter-by="filterBy"
placeholder="stuff"
@input="changeAirport"
>
<template #no-options="{ search, searching }">
<template v-if="searching">
No results found for <em>{{ search }}</em>.
</template>
<em
v-else
style="opacity: 0.5;"
>
Start typing to search for an airport.
</em>
</template>
<template #selected-option="option">
<div class="picker-item">
<div class="picker-item__section">
<div class="picker-item__iata">
{{ option.iata }}
</div>
</div>
<div class="picker-item__section">
<div class="picker-item__name">
{{ option.name }}
</div>
<div class="picker-item__muni">
{{ option.municipality }}
</div>
</div>
</div>
</template>
<template #option="option">
<div class="picker-item">
<div class="picker-item__section">
<div class="picker-item__iata">
{{ option.iata }}
</div>
</div>
<div class="picker-item__section">
<div class="picker-item__name">
{{ option.name }}
</div>
<div class="picker-item__muni">
{{ option.municipality }}
</div>
</div>
</div>
</template>
</v-select>
</div>
</template>
<script>
export default {
props: {
airports: {
type: [Array],
default () {
return []
}
},
selectedAirport: {
type: [Object],
default () {
return {
iata: '',
lat: '',
long: '',
icon: '',
name: '',
municipality: '',
type: '',
search: ''
}
}
}
},
data () {
return {
mountains: [],
filterBy: (option, label, search) => {
const temp = search.toLowerCase()
return option.search.toLowerCase().includes(temp)
}
}
},
computed: {
selectedAirportComp () {
return {
iata: this.selectedAirport.iata,
lat: this.selectedAirport.lat,
long: this.selectedAirport.long,
icon: this.selectedAirport.icon,
name: this.selectedAirport.name,
municipality: this.selectedAirport.municipality,
type: this.selectedAirport.type,
search: this.selectedAirport.search,
label: this.selectedAirport.label
}
}
},
methods: {
changeAirport (value) {
if (value) {
this.$emit('select-airport', value)
} else {
this.$emit('deselect-airport', value)
}
}
}
}
</script>
<style>
html {
color: black;
}
.picker-wrap {
margin: 1rem;
}
.picker-wrap:last-of-type {
margin-top: 0;
}
.vs__search {
font-size: 3rem !important;
padding: 0.5rem;
}
.picker-item {
padding: 0.5rem;
display: flex;
flex-direction: row;
align-items: center;
}
.picker-item__name {
font-size: 1rem;
}
.picker-item__muni {
color: blue;
}
.picker-item__iata {
font-size: 3rem;
}
</style>

+ 111
- 171
components/Map.vue View File

@ -1,10 +1,16 @@
<template>
<div id="map-wrap">
<!-- <pre style="z-index: 500; position: fixed; right: 0;">
airportsOrig: {{ airportsOrig.length }}
airportsDest: {{ airportsDest.length }}
selectedOrig: {{ selectedOrig.key }}
selectedDest: {{ selectedDest.key }}
</pre> -->
<client-only>
<l-map ref="myMap" v-bind="map">
<v-marker-cluster v-if="!selectedOrigin.key">
<l-map ref="flMap" v-bind="map">
<v-marker-cluster v-if="!selectedOrigNorm.key">
<l-marker
v-for="airport in airports_orig"
v-for="airport in airportsOrig"
:key="airport.iata"
:lat-lng="[airport.lat, airport.long]"
>
@ -24,16 +30,16 @@
{{ airport.municipality }}
</div>
<div class="map__popup-buttons">
<button class="btn btn--primary btn--map" @click="makeOrigin(airport)">
<button class="btn btn--primary btn--map" @click="$emit('make-origin', airport)">
start here
</button>
</div>
</l-popup>
</l-marker>
</v-marker-cluster>
<v-marker-cluster v-if="selectedOrigin.key && !selectedDestination.key">
<v-marker-cluster v-if="selectedOrigNorm.key && !selectedDestNorm.key">
<l-marker
v-for="airport in airports_dest"
v-for="airport in airportsDest"
:key="airport.iata"
:lat-lng="[airport.lat, airport.long]"
>
@ -55,58 +61,58 @@
<div class="map__popup-buttons">
<button
class="btn btn--primary btn--map"
@click="makeDestination(airport)"
@click="$emit('make-destination', airport)"
>
land here
</button>
<button class="btn btn--secondary btn--map" @click="makeOrigin(airport)">
<button class="btn btn--secondary btn--map" @click="$emit('make-origin', airport)">
start here
</button>
</div>
</l-popup>
</l-marker>
</v-marker-cluster>
<l-marker v-if="selectedOrigin.key" v-bind="selectedOrigin">
<l-marker v-if="selectedOrigNorm.key" v-bind="selectedOrigNorm">
<l-icon
:icon-anchor="[16, 37]"
class-name="airport-icon orig-icon selected"
>
<div class="map__icon-muni">
{{ selectedOrigin.municipality }}
{{ selectedOrig.municipality }}
</div>
</l-icon>
<l-popup class="map__popup">
<div class="map__popup-iata">
{{ selectedOrigin.iata }}
{{ selectedOrig.iata }}
</div>
<div class="map__popup-muni">
{{ selectedOrigin.municipality }}
{{ selectedOrig.municipality }}
</div>
<div class="map__popup-buttons">
<button class="btn btn--cancel btn--map" @click="clearOrigin()">
<button class="btn btn--cancel btn--map" @click="$emit('clear-origin')">
remove
</button>
</div>
</l-popup>
</l-marker>
<l-marker v-if="selectedDestination.key" v-bind="selectedDestination">
<l-marker v-if="selectedDestNorm.key" v-bind="selectedDestNorm">
<l-icon
:icon-anchor="[16, 37]"
class-name="airport-icon dest-icon selected"
>
<div class="map__icon-muni">
{{ selectedDestination.municipality }}
{{ selectedDest.municipality }}
</div>
</l-icon>
<l-popup class="map__popup">
<div class="map__popup-iata">
{{ selectedDestination.iata }}
{{ selectedDest.iata }}
</div>
<div class="map__popup-muni">
{{ selectedDestination.municipality }}
{{ selectedDest.municipality }}
</div>
<div class="map__popup-buttons">
<button class="btn btn--cancel btn--map" @click="clearDestination()">
<button class="btn btn--cancel btn--map" @click="$emit('clear-destination')">
remove
</button>
</div>
@ -122,6 +128,32 @@
<script>
export default {
props: {
airportsOrig: {
type: [Array, Object],
default () {
return []
}
},
airportsDest: {
type: [Array, Object],
default () {
return []
}
},
selectedOrig: {
type: [Object],
default () {
return {}
}
},
selectedDest: {
type: [Object],
default () {
return {}
}
}
},
data () {
return {
map: {
@ -148,93 +180,25 @@ export default {
osmUrl: 'http://{s}.tile.osm.org/{z}/{x}/{y}.png',
osmAttribution:
'© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors',
mapBoxUrl: 'https://api.mapbox.com/styles/v1/flylocal/ckt9x8aho0igb18mmm9ks2fsv/tiles/{z}/{x}/{y}?access_token=pk.eyJ1IjoiZmx5bG9jYWwiLCJhIjoiY2t0OHUxZXB6MTVueTJ4cGVwOHRuc2s2NyJ9.YF9frLvISHfOuT7nqs3TNg',
// address: {
// long: '',
// display: ''
// },
// polyline: {
// color: 'red',
// latlngs: []
// },
airports_orig: [],
airports_dest: [],
airportFetch_filterFormula: 'AND(Is_Origin=1,{IsCurrent-AsOrigin}=\'Yes\')',
airportFetch_fields: [
'Airport_IATA',
'Icon_Url',
'Latitude_Deg',
'Longitude_Deg',
'Municipality',
'Type'
],
airportFetch_sort: '&sort[0][field]=Airport_IATA&sort[0][direction]=asc',
selectedOrigin: {
key: '',
iata: '',
'lat-lng': [],
municipality: ''
},
selectedDestination: {
key: '',
iata: '',
'lat-lng': [],
municipality: ''
}
mapBoxUrl: 'https://api.mapbox.com/styles/v1/flylocal/ckt9x8aho0igb18mmm9ks2fsv/tiles/{z}/{x}/{y}?access_token=pk.eyJ1IjoiZmx5bG9jYWwiLCJhIjoiY2t0OHUxZXB6MTVueTJ4cGVwOHRuc2s2NyJ9.YF9frLvISHfOuT7nqs3TNg'
}
},
async fetch () {
let response2 = {}
let mapData2 = {}
const response = await fetch(`https://api.airtable.com/v0/appiQwfVZixRgRICe/Airports_IATA?filterByFormula=${this.airportFetch_filterFormula}${this.airportFetch_fields_string}${this.airportFetch_sort}`, {
method: 'GET',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
Authorization: 'Bearer keyJ2ht64ZSN57AG1'
computed: {
selectedOrigNorm () {
return {
key: this.selectedOrig.iata,
iata: this.selectedOrig.iata,
'lat-lng': [this.selectedOrig.lat, this.selectedOrig.long],
municipality: this.selectedOrig.municipality
}
})
if (await response.offset) {
response2 = fetch(`https://api.airtable.com/v0/appiQwfVZixRgRICe/Airports_IATA?filterByFormula=${this.airportFetch_filterFormula}&fields[]=Airport_IATA&fields[]=Icon_Url&fields[]=Latitude_Deg&fields[]=Longitude_Deg&sort[0][field]=Airport_IATA&sort[0][direction]=asc&offset=${response.offset}`, {
method: 'GET',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
Authorization: 'Bearer keyJ2ht64ZSN57AG1'
}
})
mapData2 = await response2.json()
}
const mapData = await response.json()
const r1 = mapData.records
const r2 = mapData2.records
console.log(r2)
// const mapDataTotal = [...r1, ...r2]
const mapDataTotal = [...r1]
this.airports_orig = mapDataTotal.map((record) => {
},
selectedDestNorm () {
return {
iata: record.fields.Airport_IATA,
lat: record.fields.Latitude_Deg,
long: record.fields.Longitude_Deg,
icon: record.fields.Icon_Url,
municipality: record.fields.Municipality,
type: record.fields.Type
key: this.selectedDest.iata,
iata: this.selectedDest.iata,
'lat-lng': [this.selectedDest.lat, this.selectedDest.long],
municipality: this.selectedDest.municipality
}
})
},
computed: {
airportFetch_fields_string () {
const vm = this
const array = vm.airportFetch_fields.map((field) => {
return '&fields[]=' + field
})
return array.join('')
},
mapBoxApiUrl () {
return `https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token=${this.mapBoxAccessToken}`
@ -251,73 +215,41 @@ export default {
}
}
},
updated () {
/* selected none */
if (!this.selectedOrigNorm.key && !this.selectedDestNorm.key) {
const o = this.airportsOrig.map((m) => { return [m.lat, m.long] })
this.$refs.flMap.mapObject.fitBounds([...o])
}
/* selected org */
if (this.selectedOrigNorm.key && !this.selectedDestNorm.key) {
const so = [this.selectedOrig.lat, this.selectedOrig.long]
const d = this.airportsDest.map((m) => { return [m.lat, m.long] })
this.$refs.flMap.mapObject.fitBounds([so, ...d])
}
/* selected both */
if (this.selectedOrigNorm.key && this.selectedDestNorm.key) {
const so = [this.selectedOrig.lat, this.selectedOrig.long]
const sd = [this.selectedDest.lat, this.selectedDest.long]
this.$refs.flMap.mapObject.fitBounds([so, sd])
}
// const o = this.airportsOrig.map((m) => { return [m.lat, m.long] })
// const d = this.airportsDest.map((m) => { return [m.lat, m.long] })
// const so = [this.selectedOrig.lat, this.selectedOrig.long]
// const sd = [this.selectedDest.lat, this.selectedDest.long]
// this.$refs.flMap.mapObject.fitBounds([...o, ...d, ...so, ...sd])
// this.$refs.flMap.mapObject.fitBounds([[40, -73], [5, -55]])
},
methods: {
makeOrigin (airport) {
this.selectedOrigin = {
key: airport.iata,
iata: airport.iata,
'lat-lng': [airport.lat, airport.long],
municipality: airport.municipality
}
this.fetchDestinations(airport.iata)
},
makeDestination (airport) {
this.selectedDestination = {
key: airport.iata,
iata: airport.iata,
'lat-lng': [airport.lat, airport.long],
municipality: airport.municipality
}
},
clearOrigin () {
this.selectedOrigin = {
key: '',
iata: '',
'lat-lng': [],
municipality: ''
}
this.selectedDestination = {
key: '',
iata: '',
'lat-lng': [],
municipality: ''
}
},
clearDestination () {
this.selectedDestination = {
key: '',
iata: '',
'lat-lng': [],
municipality: ''
}
},
async fetchDestinations (iata) {
const airportFetchDestfilterFormula = `AND(Is_Destination=1,{IsCurrent-AsDest}="Yes",(FIND("${iata}", Associated_Origin_Search)>0))`
const test = `https://api.airtable.com/v0/appiQwfVZixRgRICe/Airports_IATA?filterByFormula=${airportFetchDestfilterFormula}${this.airportFetch_fields_string}${this.airportFetch_sort}`
console.log(test)
const response = await fetch(`https://api.airtable.com/v0/appiQwfVZixRgRICe/Airports_IATA?filterByFormula=${airportFetchDestfilterFormula}${this.airportFetch_fields_string}${this.airportFetch_sort}`, {
method: 'GET',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
Authorization: 'Bearer keyJ2ht64ZSN57AG1'
}
})
const mapData = await response.json()
this.airports_dest = mapData.records.map((record) => {
return {
iata: record.fields.Airport_IATA,
lat: record.fields.Latitude_Deg,
long: record.fields.Longitude_Deg,
icon: record.fields.Icon_Url,
municipality: record.fields.Municipality,
type: record.fields.Type
}
})
onReady () {
// const o = this.airportsOrig.map((m) => { return [m.lat, m.long] })
// const d = this.airportsDest.map((m) => { return [m.lat, m.long] })
// const so = [this.selectedOrig.lat, this.selectedOrig.long]
// const sd = [this.selectedDest.lat, this.selectedDest.long]
// this.$refs.flMap.mapObject.fitBounds(...o, ...d, ...so, ...sd)
this.$refs.flMap.mapObject.fitBounds([[40, -73], [5, -55]])
}
}
}
@ -329,7 +261,8 @@ export default {
}
#map-wrap {
height: 100vh;
height: 0;
flex: 1 0 auto;
}
.map__icon-muni {
@ -376,6 +309,17 @@ export default {
margin: 0.75rem;
}
/* TODO: change these? */
.leaflet-top {
top: auto;
bottom: 0;
}
.leaflet-top .leaflet-control {
margin-top: auto;
margin-bottom: 10px;
}
.airport-icon {
padding: 0.55rem;
border-radius: 0.2rem 1.5rem 1.5rem 1.5rem;
@ -497,8 +441,4 @@ export default {
color: #000;
}
/* .btn.btn--map {
//..
} */
</style>

+ 0
- 178
components/PickerOrigin.vue View File

@ -1,178 +0,0 @@
<template>
<div class="picker-wrap">
<v-select :options="testlist" label="slug">
<template #option="option">
<span>{{ option.slug }}</span>
<span>{{ option.title }}</span>
</template>
</v-select>
<v-select :options="airports" label="iata" :filter-by="filterBy" @input="setSelectedOrigin">
<template #no-options="{ search, searching }">
<template v-if="searching">
No results found for <em>{{ search }}</em>.
</template>
<em v-else style="opacity: 0.5;">Start typing to search for an airport.</em>
</template>
<template #option="option">
<div class="picker-item">
<div class="picker-item__section">
<div class="picker-item__iata">
{{ option.iata }}
</div>
</div>
<div class="picker-item__section">
<div class="picker-item__name">
{{ option.name }}
</div>
<div class="picker-item__muni">
{{ option.municipality }}
</div>
</div>
</div>
</template>
</v-select>
</div>
</template>
<script>
export default {
props: {
testlist: {
type: [Array, Object],
default () {
return []
}
}
},
data () {
return {
mountains: [],
airports: [],
airportFetch_url: 'https://api.airtable.com/v0/appiQwfVZixRgRICe/Airports_IATA',
airportFetch_filterFormula: 'AND(Is_Origin=1,{IsCurrent-AsOrigin}=\'Yes\')',
airportFetch_fields: [
'Airport_IATA',
'Icon_Url',
'Latitude_Deg',
'Longitude_Deg',
'Municipality',
'Airport_Name',
'Type',
'Search_Field'
],
airportFetch_sort: '&sort[0][field]=Airport_IATA&sort[0][direction]=asc',
filterBy: (option, label, search) => {
const temp = search.toLowerCase()
return option.search.toLowerCase().includes(temp)
},
selectedOrigin: {},
selectedDestination: {}
}
},
async fetch () {
let response2 = {}
let mapData2 = {}
const response = await fetch(`${this.airportFetch_url}?filterByFormula=${this.airportFetch_filterFormula}${this.airportFetch_fields_string}${this.airportFetch_sort}`, {
method: 'GET',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
Authorization: 'Bearer keyJ2ht64ZSN57AG1'
}
})
if (await response.offset) {
response2 = fetch(`${this.airportFetch_url}?filterByFormula=${this.filterFormula}${this.airportFetch_fields_string}${this.airportFetch_sort}&offset=${response.offset}`, {
method: 'GET',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
Authorization: 'Bearer keyJ2ht64ZSN57AG1'
}
})
mapData2 = await response2.json()
}
const mapData = await response.json()
const r1 = mapData.records
const r2 = mapData2.records
console.log(r2)
// const mapDataTotal = [...r1, ...r2]
const mapDataTotal = [...r1]
this.airports = mapDataTotal.map((record) => {
return {
iata: record.fields.Airport_IATA,
lat: record.fields.Latitude_Deg,
long: record.fields.Longitude_Deg,
icon: record.fields.Icon_Url,
name: record.fields.Airport_Name,
municipality: record.fields.Municipality,
type: record.fields.Type,
search: record.fields.Search_Field
}
})
},
computed: {
airportFetch_fields_string () {
const vm = this
const array = vm.airportFetch_fields.map((field) => {
return '&fields[]=' + field
})
return array.join('')
}
},
methods: {
setSelectedOrigin (value) {
this.selectedOrigin = value
this.$router.push('/go/' + value.iata)
},
setSelectedDestination (value) {
this.selectedDestination = value
this.$router.push('/go/' + this.selectedOrigin + '/' + value.iata)
}
}
}
</script>
<style>
html {
color: black;
}
.picker-wrap {
margin: 1rem;
}
.vs__search {
font-size: 2rem !important;
}
.picker-item {
padding: 0.5rem;
display: flex;
flex-direction: row;
align-items: center;
gap: 1rem;
}
.picker-item__section {
display: flex;
flex-direction: column;
}
.picker-item__name {
font-size: 1rem;
}
.picker-item__muni {
color: blue;
}
.picker-item__iata {
font-size: 3rem;
}
</style>

+ 245
- 20
pages/go.vue View File

@ -1,46 +1,254 @@
<template>
<main>
<div class="page-container">
<header>
<div>logo</div>
<div>
logo
</div>
<div>
<span>
click the map, or&nbsp;
<div v-show="!isPickerVisible">
tap an airport on the map, or&nbsp;
<button class="btn btn--primary" @click="showPicker">
search here
</button>
</div>
<div v-show="isPickerVisible">
<button class="btn btn--primary" @click="showPicker">
search
hide search
</button>
</span>
</div>
</div>
</header>
<Map />
<aside class="nav">
<PickerOrigin v-show="isPickerVisible" :testlist="mountains" />
</aside>
</main>
<!-- <pre style="position: fixed; z-index: 500; right: 0; top: 2rem; font-size: 0.6rem; color: gray;">
{{ selectedOrig }}
{{ selectedDest }}
</pre> -->
<main>
<aside v-show="isPickerVisible" class="nav">
<AirportPicker
:airports="airports_orig"
:selected-airport="selectedOrig"
@select-airport="makeOrigin"
@deselect-airport="clearOrigin"
/>
<AirportPicker
v-show="selectedOrig.iata"
:airports="airports_dest"
:selected-airport="selectedDest"
@select-airport="makeDestination"
@deselect-airport="clearDestination"
/>
</aside>
<Map
:airports-orig="airports_orig"
:airports-dest="airports_dest"
:selected-orig="selectedOrig"
:selected-dest="selectedDest"
@make-origin="makeOrigin"
@make-destination="makeDestination"
@clear-origin="clearOrigin"
@clear-destination="clearDestination"
/>
</main>
</div>
</template>
<script>
import PickerOrigin from '../components/PickerOrigin.vue'
import AirportPicker from '../components/AirportPicker.vue'
export default {
components: { PickerOrigin },
components: { AirportPicker },
data () {
return {
color: 'red',
mountains: [
{
slug: 'sluggy',
title: 'titly'
}
],
isPickerVisible: false
isPickerVisible: false,
airports_orig: [],
airports_dest: [],
airportFetch_filterFormula: 'AND(Is_Origin=1,{IsCurrent-AsOrigin}=\'Yes\')',
airportFetch_fields: [
'Airport_IATA',
'Icon_Url',
'Latitude_Deg',
'Longitude_Deg',
'Municipality',
'Airport_Name',
'Type',
'Search_Field'
],
airportFetch_sort: '&sort[0][field]=Airport_IATA&sort[0][direction]=asc',
selectedOrig: {
iata: '',
lat: '',
long: '',
icon: '',
name: '',
municipality: '',
type: '',
search: ''
},
selectedDest: {
iata: '',
lat: '',
long: '',
icon: '',
name: '',
municipality: '',
type: '',
search: ''
},
emptyAirport: {
iata: '',
lat: '',
long: '',
icon: '',
name: '',
municipality: '',
type: '',
search: ''
}
}
},
async fetch () {
this.mountains = await fetch(
'https://api.nuxtjs.dev/mountains'
).then(res => res.json())
let response2 = {}
let mapData2 = {}
const response = await fetch(`https://api.airtable.com/v0/appiQwfVZixRgRICe/Airports_IATA?filterByFormula=${this.airportFetch_filterFormula}${this.airportFetch_fields_string}${this.airportFetch_sort}`, {
method: 'GET',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
Authorization: 'Bearer keyJ2ht64ZSN57AG1'
}
})
if (await response.offset) {
response2 = fetch(`https://api.airtable.com/v0/appiQwfVZixRgRICe/Airports_IATA?filterByFormula=${this.airportFetch_filterFormula}&fields[]=Airport_IATA&fields[]=Icon_Url&fields[]=Latitude_Deg&fields[]=Longitude_Deg&sort[0][field]=Airport_IATA&sort[0][direction]=asc&offset=${response.offset}`, {
method: 'GET',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
Authorization: 'Bearer keyJ2ht64ZSN57AG1'
}
})
mapData2 = await response2.json()
}
const mapData = await response.json()
const r1 = mapData.records
const r2 = mapData2.records
console.log(r2)
// const mapDataTotal = [...r1, ...r2]
const mapDataTotal = [...r1]
this.airports_orig = mapDataTotal.map((record) => {
return {
iata: record.fields.Airport_IATA,
lat: record.fields.Latitude_Deg,
long: record.fields.Longitude_Deg,
icon: record.fields.Icon_Url,
name: record.fields.Airport_Name,
municipality: record.fields.Municipality,
type: record.fields.Type,
search: record.fields.Search_Field
}
})
},
computed: {
airportFetch_fields_string () {
const vm = this
const array = vm.airportFetch_fields.map((field) => {
return '&fields[]=' + field
})
return array.join('')
}
},
methods: {
makeOrigin (airport) {
// console.log(airport)
this.selectedOrig = { ...airport }
this.selectedDest = { ...this.emptyAirport }
// this.$router.push('/go/' + airport.iata)
history.pushState(
{},
null,
this.$route.path + encodeURIComponent(airport.iata)
)
this.fetchDestinations(airport.iata, this)
},
makeDestination (airport) {
this.selectedDest = { ...airport }
// this.$router.push('/go/' + this.selectedOrig.iata + '/' + airport.iata)
history.pushState(
{},
null,
this.$route.path + encodeURIComponent(this.selectedOrig.iata) + '/' + encodeURIComponent(airport.iata)
)
},
clearOrigin () {
this.selectedOrig = { ...this.emptyAirport }
this.selectedDest = { ...this.emptyAirport }
history.pushState(
{},
null,
this.$route.path
)
},
clearDestination () {
this.selectedDest = { ...this.emptyAirport }
history.pushState(
{},
null,
this.$route.path + encodeURIComponent(this.selectedOrig.iata)
)
},
async fetchDestinations (iata) {
const airportFetchDestfilterFormula = `AND(Is_Destination=1,{IsCurrent-AsDest}="Yes",(FIND("${iata}", Associated_Origin_Search)>0))`
const response = await fetch(`https://api.airtable.com/v0/appiQwfVZixRgRICe/Airports_IATA?filterByFormula=${airportFetchDestfilterFormula}${this.airportFetch_fields_string}${this.airportFetch_sort}`, {
method: 'GET',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
Authorization: 'Bearer keyJ2ht64ZSN57AG1'
}
})
const mapData = await response.json()
// console.log('mapData.records length: ' + mapData.records.length)
// console.log('this.airports_dest length (before): ' + this.airports_dest.length)
this.color = 'fetchDestinations'
this.airports_dest = mapData.records.map((record) => {
return {
iata: record.fields.Airport_IATA,
lat: record.fields.Latitude_Deg,
long: record.fields.Longitude_Deg,
icon: record.fields.Icon_Url,
name: record.fields.Airport_Name,
municipality: record.fields.Municipality,
type: record.fields.Type,
search: record.fields.Search_Field
}
})
// this.$refs.flMap.mapObject.fitBounds(this.markers.map((m) => { return [m.lat, m.lng] }))
// console.log('this.airports_dest length (after)' + this.airports_dest.length)
},
showPicker () {
this.isPickerVisible = !this.isPickerVisible
}
@ -48,7 +256,15 @@ export default {
}
</script>
<style scoped>
<style>
html,
body,
#__nuxt,
#__layout,
.page-container,
main {
height: 100%;
}
header {
position: fixed;
@ -60,21 +276,30 @@ header {
padding: 1rem;
}
main {
display: flex;
flex-direction: column;
/* grid-template-rows: min-content 1fr; */
}
.nav {
position: fixed;
flex: 0 0 auto;
/* position: fixed;
top: 0;
padding-top: 4rem;
width: 100vw;
z-index: 401;
z-index: 401; */
background: white;
display: flex;
flex-direction: column;
justify-items: center;
margin-top: 3.5rem;
}
.btn--nav-open {
padding: 1rem;
display: block;
}
</style>

Loading…
Cancel
Save