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.

323 lines
7.6 KiB

  1. <template>
  2. <main>
  3. <div>
  4. <button class="btn btn--primary" style="margin-left: 2rem; margin-top: 2rem;" @click="goBack">
  5. 👈 back
  6. </button>
  7. <h1 style="text-align: center; font-size: 2.5rem;">
  8. {{ selectedOrig.municipality }} 🛩 {{ selectedDest.municipality }}
  9. </h1>
  10. </div>
  11. <ul class="schedule-grid">
  12. <li
  13. v-for="schedule in schedules"
  14. :key="schedule.fields.Record_ID"
  15. class="grid__row"
  16. >
  17. <pre>
  18. {{ schedule.fields.Flight_Number }}
  19. </pre>
  20. <div class="grid__field">
  21. <label> Local Airline </label>
  22. <div class="field__content">
  23. {{ schedule.fields.Carrier_Name }}
  24. </div>
  25. </div>
  26. <div class="grid__field">
  27. <label> Days of the Week </label>
  28. <div class="field__content">
  29. <div class="dow-grid">
  30. <div
  31. v-for="day in daysList(schedule.fields.Frequency_Convert)"
  32. :key="day.name"
  33. :class="['dow-grid__day', 'day--' + day.name]"
  34. >
  35. <span> {{ day.name }} </span>
  36. </div>
  37. </div>
  38. </div>
  39. </div>
  40. <div class="grid__field">
  41. <label> Departing </label>
  42. <div class="field__content">
  43. {{ schedule.fields.Departure_TimeL }}
  44. </div>
  45. </div>
  46. <div class="grid__field">
  47. <label> Arriving </label>
  48. <div class="field__content">
  49. {{ schedule.fields.Arrival_TimeL }}
  50. </div>
  51. </div>
  52. <div class="grid__field">
  53. <label> Available Until </label>
  54. <div class="field__content">
  55. {{ schedule.fields.Effective_End }}
  56. </div>
  57. </div>
  58. <div class="grid__field">
  59. <div class="field__content">
  60. {{ schedule.fields.Price_USD }}
  61. </div>
  62. <button class="btn btn--primary" @click="book(schedule)">
  63. {{ schedule.fields.IsExpedia[0] === 'true' ? 'book it!' : 'see flights' }}
  64. </button>
  65. </div>
  66. </li>
  67. </ul>
  68. </main>
  69. </template>
  70. <script>
  71. export default {
  72. data () {
  73. return {
  74. schedules: [],
  75. startingDate: '',
  76. selectedSchedule: {},
  77. selectedDays: [],
  78. selectedOrig: {},
  79. selectedDest: {}
  80. }
  81. },
  82. async fetch () {
  83. // console.log(this.$route.params.o)
  84. const today = new Date().toLocaleDateString('en-CA')
  85. // function addDays (date, days) {
  86. // const result = new Date(date)
  87. // result.setDate(result.getDate() + days)
  88. // return result
  89. // }
  90. // const tomorrow = addDays(new Date(), 1).toLocaleDateString('en-CA')
  91. 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)`
  92. // console.log(scheduleFetchFilterFormula)
  93. const scheduleFetchSort = '&sort[0][field]=DepartureTimeFormatted&sort[0][direction]=asc'
  94. const response = await fetch(`https://api.airtable.com/v0/appiQwfVZixRgRICe/Schedule?filterByFormula=${scheduleFetchFilterFormula}${scheduleFetchSort}`, {
  95. method: 'GET',
  96. headers: {
  97. 'Content-Type': 'application/x-www-form-urlencoded',
  98. Authorization: 'Bearer keyJ2ht64ZSN57AG1'
  99. }
  100. })
  101. const data = await response.json()
  102. // console.log(data)
  103. this.schedules = [...data.records]
  104. },
  105. computed: {
  106. },
  107. created () {
  108. // console.log(this.$route.path)
  109. if (this.$route && this.$route.params && this.$route.params.o) {
  110. this.fetchSingleAirport(this.$route.params.o, true)
  111. }
  112. if (this.$route && this.$route.params && this.$route.params.d) {
  113. this.fetchSingleAirport(this.$route.params.d, false)
  114. }
  115. },
  116. methods: {
  117. daysList (days) {
  118. const list = days.split(', ').map((day) => {
  119. const name = day.toLowerCase().slice(0, -1)
  120. let num
  121. switch (name) {
  122. case 'su':
  123. num = 0
  124. break
  125. case 'mo':
  126. num = 1
  127. break
  128. case 'tu':
  129. num = 2
  130. break
  131. case 'we':
  132. num = 3
  133. break
  134. case 'th':
  135. num = 4
  136. break
  137. case 'fr':
  138. num = 5
  139. break
  140. case 'sa':
  141. num = 6
  142. break
  143. default:
  144. break
  145. }
  146. return {
  147. name,
  148. num
  149. }
  150. })
  151. return list.sort(function (a, b) {
  152. return a.num - b.num
  153. })
  154. },
  155. goBack () {
  156. this.$router.go(-1)
  157. },
  158. book (schedule) {
  159. if (schedule.fields.IsExpedia[0] === 'true') {
  160. this.startingDate = new Date()
  161. this.selectedSchedule = schedule.fields
  162. this.selectedDays = this.daysList(schedule.fields.Frequency_Convert)
  163. } else {
  164. window.open(schedule.fields['BookingLink (from Carriers_Alaska)'][0])
  165. }
  166. },
  167. clearSelectedSchedule () {
  168. console.log('clear')
  169. this.startingDate = ''
  170. this.selectedSchedule = {}
  171. },
  172. async fetchSingleAirport (iata, isOrig) {
  173. const airportFetchFilterFormula =
  174. isOrig
  175. ? `AND(Is_Origin=1,{IsCurrent-AsOrigin}="Yes",Airport_IATA="${iata}")`
  176. : `AND(Is_Destination=1,{IsCurrent-AsDest}="Yes",Airport_IATA="${iata}")`
  177. const response = await fetch(`https://api.airtable.com/v0/appiQwfVZixRgRICe/Airports_IATA?filterByFormula=${airportFetchFilterFormula}`, {
  178. method: 'GET',
  179. headers: {
  180. 'Content-Type': 'application/x-www-form-urlencoded',
  181. Authorization: 'Bearer keyJ2ht64ZSN57AG1'
  182. }
  183. })
  184. const mapData = await response.json()
  185. const thisAirport = {
  186. iata: mapData.records[0].fields.Airport_IATA,
  187. lat: mapData.records[0].fields.Latitude_Deg,
  188. long: mapData.records[0].fields.Longitude_Deg,
  189. icon: mapData.records[0].fields.Icon_Url,
  190. name: mapData.records[0].fields.Airport_Name,
  191. municipality: mapData.records[0].fields.Municipality,
  192. type: mapData.records[0].fields.Type,
  193. search: mapData.records[0].fields.Search_Field
  194. }
  195. switch (isOrig) {
  196. case true:
  197. this.selectedOrig = { ...thisAirport }
  198. break
  199. case false:
  200. this.selectedDest = { ...thisAirport }
  201. break
  202. default:
  203. break
  204. }
  205. }
  206. }
  207. }
  208. </script>
  209. <style lang="scss">
  210. .schedule-grid {
  211. display: flex;
  212. flex-direction: column;
  213. gap: 1rem;
  214. margin: 2rem;
  215. }
  216. .grid__row {
  217. display: grid;
  218. grid-template-columns: 2fr 2fr 1fr 1fr 2fr 1fr;
  219. grid-template-rows: auto;
  220. gap: 1rem;
  221. padding: 1rem;
  222. }
  223. @media only screen and (max-width: 768px) {
  224. .grid__row {
  225. display: grid;
  226. grid-template-columns: 1fr 1fr;
  227. grid-template-rows: auto;
  228. }
  229. }
  230. .grid__row:nth-child(2n) {
  231. background: #eee;
  232. }
  233. // .grid__field {
  234. // }
  235. label {
  236. font-size: 0.75rem;
  237. font-weight: 700;
  238. color: gray;
  239. display: block;
  240. }
  241. .field__content {
  242. font-size: 1.5rem;
  243. }
  244. .dow-grid {
  245. width: 200px;
  246. display: grid;
  247. grid-template-columns: 1fr 1fr 1fr 1fr 1fr 1fr 1fr;
  248. gap: 0.5rem;
  249. }
  250. .dow-grid__day {
  251. font-size: 0.8rem;
  252. border: 1px solid #ccc !important;
  253. display: flex;
  254. align-items: center;
  255. justify-content: center;
  256. border-radius: 3px !important;
  257. text-transform: capitalize;
  258. }
  259. .day--su {
  260. grid-column: 1 / span 1;
  261. }
  262. .day--mo {
  263. grid-column: 2 / span 1;
  264. }
  265. .day--tu {
  266. grid-column: 3 / span 1;
  267. }
  268. .day--we {
  269. grid-column: 4 / span 1;
  270. }
  271. .day--th {
  272. grid-column: 5 / span 1;
  273. }
  274. .day--fr {
  275. grid-column: 6 / span 1;
  276. }
  277. .day--sa {
  278. grid-column: 7 / span 1;
  279. }
  280. </style>