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.

305 lines
7.9 KiB

  1. <template>
  2. <div class="page-container">
  3. <header>
  4. <div>logo</div>
  5. <div>
  6. <div v-show="!isPickerVisible">
  7. tap an airport on the map, or&nbsp;
  8. <button class="btn btn--primary" @click="showPicker">
  9. search here
  10. </button>
  11. </div>
  12. <div v-show="isPickerVisible">
  13. <button class="btn btn--primary" @click="showPicker">
  14. hide search
  15. </button>
  16. </div>
  17. </div>
  18. </header>
  19. <!-- <pre style="position: fixed; z-index: 500; right: 0; top: 2rem; font-size: 0.6rem; color: gray;">
  20. {{ selectedOrig }}
  21. {{ selectedDest }}
  22. </pre> -->
  23. <main>
  24. <aside v-show="isPickerVisible" class="nav">
  25. <AirportPicker
  26. :airports="airports_orig"
  27. :selected-airport="selectedOrig"
  28. @select-airport="makeOrigin"
  29. @deselect-airport="clearOrigin"
  30. />
  31. <AirportPicker
  32. v-show="selectedOrig.iata"
  33. :airports="airports_dest"
  34. :selected-airport="selectedDest"
  35. @select-airport="makeDestination"
  36. @deselect-airport="clearDestination"
  37. />
  38. </aside>
  39. <Map
  40. :airports-orig="airports_orig"
  41. :airports-dest="airports_dest"
  42. :selected-orig="selectedOrig"
  43. :selected-dest="selectedDest"
  44. @make-origin="makeOrigin"
  45. @make-destination="makeDestination"
  46. @clear-origin="clearOrigin"
  47. @clear-destination="clearDestination"
  48. />
  49. </main>
  50. </div>
  51. </template>
  52. <script>
  53. import AirportPicker from '../components/AirportPicker.vue'
  54. export default {
  55. components: { AirportPicker },
  56. data () {
  57. return {
  58. color: 'red',
  59. mountains: [
  60. {
  61. slug: 'sluggy',
  62. title: 'titly'
  63. }
  64. ],
  65. isPickerVisible: false,
  66. airports_orig: [],
  67. airports_dest: [],
  68. airportFetch_filterFormula: 'AND(Is_Origin=1,{IsCurrent-AsOrigin}=\'Yes\')',
  69. airportFetch_fields: [
  70. 'Airport_IATA',
  71. 'Icon_Url',
  72. 'Latitude_Deg',
  73. 'Longitude_Deg',
  74. 'Municipality',
  75. 'Airport_Name',
  76. 'Type',
  77. 'Search_Field'
  78. ],
  79. airportFetch_sort: '&sort[0][field]=Airport_IATA&sort[0][direction]=asc',
  80. selectedOrig: {
  81. iata: '',
  82. lat: '',
  83. long: '',
  84. icon: '',
  85. name: '',
  86. municipality: '',
  87. type: '',
  88. search: ''
  89. },
  90. selectedDest: {
  91. iata: '',
  92. lat: '',
  93. long: '',
  94. icon: '',
  95. name: '',
  96. municipality: '',
  97. type: '',
  98. search: ''
  99. },
  100. emptyAirport: {
  101. iata: '',
  102. lat: '',
  103. long: '',
  104. icon: '',
  105. name: '',
  106. municipality: '',
  107. type: '',
  108. search: ''
  109. }
  110. }
  111. },
  112. async fetch () {
  113. this.mountains = await fetch(
  114. 'https://api.nuxtjs.dev/mountains'
  115. ).then(res => res.json())
  116. let response2 = {}
  117. let mapData2 = {}
  118. const response = await fetch(`https://api.airtable.com/v0/appiQwfVZixRgRICe/Airports_IATA?filterByFormula=${this.airportFetch_filterFormula}${this.airportFetch_fields_string}${this.airportFetch_sort}`, {
  119. method: 'GET',
  120. headers: {
  121. 'Content-Type': 'application/x-www-form-urlencoded',
  122. Authorization: 'Bearer keyJ2ht64ZSN57AG1'
  123. }
  124. })
  125. if (await response.offset) {
  126. 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}`, {
  127. method: 'GET',
  128. headers: {
  129. 'Content-Type': 'application/x-www-form-urlencoded',
  130. Authorization: 'Bearer keyJ2ht64ZSN57AG1'
  131. }
  132. })
  133. mapData2 = await response2.json()
  134. }
  135. const mapData = await response.json()
  136. const r1 = mapData.records
  137. const r2 = mapData2.records
  138. console.log(r2)
  139. // const mapDataTotal = [...r1, ...r2]
  140. const mapDataTotal = [...r1]
  141. this.airports_orig = mapDataTotal.map((record) => {
  142. return {
  143. iata: record.fields.Airport_IATA,
  144. lat: record.fields.Latitude_Deg,
  145. long: record.fields.Longitude_Deg,
  146. icon: record.fields.Icon_Url,
  147. name: record.fields.Airport_Name,
  148. municipality: record.fields.Municipality,
  149. type: record.fields.Type,
  150. search: record.fields.Search_Field
  151. }
  152. })
  153. },
  154. computed: {
  155. airportFetch_fields_string () {
  156. const vm = this
  157. const array = vm.airportFetch_fields.map((field) => {
  158. return '&fields[]=' + field
  159. })
  160. return array.join('')
  161. }
  162. },
  163. methods: {
  164. makeOrigin (airport) {
  165. // console.log(airport)
  166. this.selectedOrig = { ...airport }
  167. this.selectedDest = { ...this.emptyAirport }
  168. // this.$router.push('/go/' + airport.iata)
  169. history.pushState(
  170. {},
  171. null,
  172. this.$route.path + encodeURIComponent(airport.iata)
  173. )
  174. this.fetchDestinations(airport.iata, this)
  175. },
  176. makeDestination (airport) {
  177. this.selectedDest = { ...airport }
  178. // this.$router.push('/go/' + this.selectedOrig.iata + '/' + airport.iata)
  179. history.pushState(
  180. {},
  181. null,
  182. this.$route.path + encodeURIComponent(this.selectedOrig.iata) + '/' + encodeURIComponent(airport.iata)
  183. )
  184. },
  185. clearOrigin () {
  186. this.selectedOrig = { ...this.emptyAirport }
  187. this.selectedDest = { ...this.emptyAirport }
  188. history.pushState(
  189. {},
  190. null,
  191. this.$route.path
  192. )
  193. },
  194. clearDestination () {
  195. this.selectedDest = { ...this.emptyAirport }
  196. history.pushState(
  197. {},
  198. null,
  199. this.$route.path + encodeURIComponent(this.selectedOrig.iata)
  200. )
  201. },
  202. async fetchDestinations (iata) {
  203. const airportFetchDestfilterFormula = `AND(Is_Destination=1,{IsCurrent-AsDest}="Yes",(FIND("${iata}", Associated_Origin_Search)>0))`
  204. const response = await fetch(`https://api.airtable.com/v0/appiQwfVZixRgRICe/Airports_IATA?filterByFormula=${airportFetchDestfilterFormula}${this.airportFetch_fields_string}${this.airportFetch_sort}`, {
  205. method: 'GET',
  206. headers: {
  207. 'Content-Type': 'application/x-www-form-urlencoded',
  208. Authorization: 'Bearer keyJ2ht64ZSN57AG1'
  209. }
  210. })
  211. const mapData = await response.json()
  212. // console.log('mapData.records length: ' + mapData.records.length)
  213. // console.log('this.airports_dest length (before): ' + this.airports_dest.length)
  214. this.color = 'fetchDestinations'
  215. this.airports_dest = mapData.records.map((record) => {
  216. return {
  217. iata: record.fields.Airport_IATA,
  218. lat: record.fields.Latitude_Deg,
  219. long: record.fields.Longitude_Deg,
  220. icon: record.fields.Icon_Url,
  221. name: record.fields.Airport_Name,
  222. municipality: record.fields.Municipality,
  223. type: record.fields.Type,
  224. search: record.fields.Search_Field
  225. }
  226. })
  227. // this.$refs.flMap.mapObject.fitBounds(this.markers.map((m) => { return [m.lat, m.lng] }))
  228. // console.log('this.airports_dest length (after)' + this.airports_dest.length)
  229. },
  230. showPicker () {
  231. this.isPickerVisible = !this.isPickerVisible
  232. }
  233. }
  234. }
  235. </script>
  236. <style>
  237. html,
  238. body,
  239. #__nuxt,
  240. #__layout,
  241. .page-container,
  242. main {
  243. height: 100%;
  244. }
  245. header {
  246. position: fixed;
  247. top: 0;
  248. width: 100vw;
  249. z-index: 402;
  250. display: flex;
  251. flex-direction: row;
  252. padding: 1rem;
  253. }
  254. main {
  255. display: flex;
  256. flex-direction: column;
  257. /* grid-template-rows: min-content 1fr; */
  258. }
  259. .nav {
  260. flex: 0 0 auto;
  261. /* position: fixed;
  262. top: 0;
  263. padding-top: 4rem;
  264. width: 100vw;
  265. z-index: 401; */
  266. background: white;
  267. display: flex;
  268. flex-direction: column;
  269. justify-items: center;
  270. margin-top: 3.5rem;
  271. }
  272. .btn--nav-open {
  273. padding: 1rem;
  274. display: block;
  275. }
  276. </style>