NEXT craftinamerica.org. Base setup for headless wordpress https://www.craftinamerica.org
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.

list.vue 6.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. <template lang="pug">
  2. .page--list.f-col.between
  3. article.f-grow
  4. header.center.t-up
  5. .title.f-row
  6. h3 {{ type }} list
  7. span(v-if="sortBy")
  8. h3 sorted {{ sortBy.replace('-', ' ') }}
  9. h3(v-if="!loaded") loading...
  10. .content(v-else-if="allPagesLoaded && type && allPages[type]" v-html="allPages[type].content")
  11. .posts(v-if="posts && loaded" :class="{ 'is-grid': grid }")
  12. section(v-for="(post, i) in posts" :key="post.slug").shadow.post
  13. card(:content="post" :type="type" :wide="type == 'exhibitions' && i > 1 || type == 'events' && i > 1 ")
  14. footer
  15. p {{ `${type} count: ${Object.values(posts).length}` }}
  16. p {{ `show sidebar: ${sidebar}` }}
  17. sidebar(v-if="sidebar" :type="`${type}`" layout="list")
  18. </template>
  19. <script>
  20. import featuredImage from '@/components/featured-image'
  21. import card from '@/components/card'
  22. import sidebar from '@/components/sidebars/sidebar'
  23. import { postTypeGetters, scrollTop } from './mixin-post-types'
  24. import { convertTitleCase, typeFromRoute, sortTypes } from '@/utils/helpers'
  25. export default {
  26. components: { sidebar, featuredImage, card },
  27. props: {
  28. sidebar: { type: Boolean },
  29. grid: { type: Boolean },
  30. sortBy: { type: String }
  31. },
  32. mixins: [postTypeGetters, scrollTop],
  33. computed: {
  34. type() { // Checks for type and fixes Episodes route edge case
  35. return typeFromRoute(this.$route)
  36. },
  37. dispatchName() {
  38. let type = convertTitleCase(this.type)
  39. return this.sortBy ? `getAll${type.split('/')[0]}` : `getAll${type}`
  40. },
  41. loaded() {
  42. let type = convertTitleCase(this.type)
  43. if(!type) return
  44. return this[`all${type}Loaded`]
  45. },
  46. posts() {
  47. let type = convertTitleCase(this.type)
  48. if(!type) return
  49. /**
  50. * We override the API to sort by date
  51. * because items are returned by ID so
  52. * we need to re-sort it by date
  53. */
  54. let unsortedOfType = Object.values(this[`all${type}`])
  55. let sortedByRecent = unsortedOfType.sort((postA, postB) => new Date(postB.date) - new Date(postA.date))
  56. /**
  57. * Sorting of this[`all${type}`] is also controlled by API
  58. * so if a sortBy is specified we return it sorted or
  59. * we fail over to sorted by date
  60. */
  61. let returnList = sortedByRecent
  62. if(this.sortBy && sortTypes.includes(this.sortBy)) {
  63. returnList = this[`all${type}`]
  64. }
  65. if(['exhibitions', 'events'].includes(this.type)) {
  66. returnList = this[`all${type}`]
  67. }
  68. return returnList
  69. },
  70. },
  71. methods: {
  72. getPosts() {
  73. // Sorting
  74. let sort = this.sortBy ? this.sortBy : this.$route.path.split('/').pop()
  75. // !: BUG
  76. // if(this.type !== sort || !Object.values(sortTypes).includes(sort)) sort = null
  77. if(Object.values(sortTypes).includes(sort)) {
  78. console.log('trying to sort by:', sort)
  79. console.log(`sortTypes includes ${sort}:`, Object.values(sortTypes).includes(sort))
  80. }
  81. // Don't dispatch if there's no type
  82. if(this.type && this.dispatchName) {
  83. this.$store.dispatch(this.dispatchName, sort)
  84. }
  85. },
  86. async checkAndSetHero(type) {
  87. if(!this['allPagesLoaded']) {
  88. await this.$store.dispatch('getAllPages')
  89. }
  90. const page = this.allPages[type]
  91. if(!page) return
  92. const json = { url: page.featured, heroType: 'image' }
  93. if(page.hero && JSON.parse(page.hero) && JSON.parse(page.hero).url) {
  94. json = JSON.parse(page.hero)
  95. json.heroType = 'video'
  96. }
  97. // No featured or youTube
  98. if(!json.url) {
  99. json.heroType = null
  100. }
  101. // Set the hero text to the post title or excerpt
  102. json.text = page && page.excerpt ? page.excerpt : page.title
  103. this.$store.commit('SET_HERO', json)
  104. },
  105. },
  106. watch: {
  107. async $route(to, from){
  108. // console.log(this.sidebar)
  109. let type = convertTitleCase(this.type)
  110. let sort = this.sortBy ? this.sortBy : to.path.split('/').pop()
  111. this.checkAndSetHero(this.type)
  112. // console.log('---')
  113. // console.log(sort)
  114. if(!this[`all${type}Loaded`] || sort) this.getPosts()
  115. }
  116. },
  117. created() {
  118. let type = convertTitleCase(this.type)
  119. console.log(`${type} already loaded?:`, this[`all${type}Loaded`])
  120. this.checkAndSetHero(this.type)
  121. if(!this[`all${type}Loaded`]) this.getPosts()
  122. }
  123. }
  124. </script>
  125. <style lang="postcss">
  126. @import '../sss/variables.sss'
  127. @import '../sss/theme.sss'
  128. .page--list
  129. /* background-color: white */
  130. article
  131. > header
  132. /* padding: 1em 0 1em 0 */
  133. padding: 1em
  134. > h1
  135. margin: 0
  136. > .content
  137. padding: 0
  138. width: 100%
  139. /* posts not grid list */
  140. ul
  141. img
  142. max-width: 50%
  143. .is-grid
  144. display: flex
  145. flex-direction: row
  146. flex-wrap: wrap
  147. justify-content: space-between
  148. /* extra padding required? */
  149. /* padding: $ms-0 */
  150. /* background-color: white */
  151. section
  152. width: 32.5%
  153. /* 4 column grid see how dense this becomes */
  154. /* width: 24% */
  155. ul
  156. flex-wrap: wrap
  157. list-style: none
  158. img
  159. max-width: 100%
  160. @media (min-width: $medium)
  161. .page--list.f-col
  162. flex-direction: row
  163. </style>