%PDF- %PDF-
Mini Shell

Mini Shell

Direktori : /home/forge/takeaseat.eco-n-tech.co.uk/pages/blog/
Upload File :
Create Path :
Current File : //home/forge/takeaseat.eco-n-tech.co.uk/pages/blog/index.vue

<template>
  <div class="page-wrapper">
    <PageHeader classObject='bg-purple'>
      <img class="relative z-20 mb-8"
        src="~assets/images/logo-white-small.svg" alt="Takeaseat" />
      <h1 class="relative z-20 text-5xl lg:text-7xl font-bold">Blog</h1>
      <div class="page-header-bottom grid grid-cols-2 gap-x-4">
        <div class="flex items-center justify-start">
          <SearchForm 
            v-model="search_query"
            placeholder="Search Blog Posts" />
        </div>
        <div class="flex items-center justify-end">
          <button @click="is_filters_showing =! is_filters_showing"
            class="flex items-center uppercase text-sm font-medium focus:outline-none"
            type="button">
            <span v-if="is_filters_showing == false">Show Filters</span>
            <span v-else>Hide Filters</span>
            <span class="block w-4 h-4 ml-3 icon-filters bg-contain bg-center bg-no-repeat"></span>
          </button>
        </div>
      </div>
    </PageHeader>
    <div :class="is_filters_showing ? 'grid grid-cols-1 lg:grid-cols-8 gap-10' : ''"
      class="px-6 lg:px-0">
      <div v-if="is_filters_showing"
        class="lg:col-span-2">
        <span class="mb-8 block text-xl font-bold">Filter</span>
        <button v-if="filter.categories.length || filter.subjects.length || filter.authors.length"
          class="block -mt-3 mb-6 uppercase transition text-blue-light hover:text-black focus:outline-none"
          @click="resetFilters">Reset Filters</button>
        <Widget v-if="filters.categories.length"
          title="Category">
          <t-checkbox-group 
            @change="filterPosts"
            :classes="{
              groupWrapper: 'flex flex-col justify-center px-0.5',
              label: 'block pl-2.5',
              input: 'rounded w-5 h-5 text-black transition duration-100 ease-in-out border-gray-300 shadow-sm focus:border-black focus:ring-2 focus:ring-black focus:outline-none focus:ring-opacity-50 focus:ring-offset-0  disabled:opacity-50 disabled:cursor-not-allowed',
              inputWrapper: 'inline-flex',
              wrapper: 'flex items-center my-1',
            }"
            v-model="filter.categories"
            name="categories" 
            valueAttribute="id"
            textAttribute="name"
            :options="filters.categories"></t-checkbox-group>
        </Widget>
        <Widget v-if="filters.subjects.length"
          title="Subject">
          <t-checkbox-group 
            @change="filterPosts"
            :classes="{
              groupWrapper: 'flex flex-col justify-center px-0.5',
              label: 'block pl-2.5',
              input: 'rounded w-5 h-5 text-black transition duration-100 ease-in-out border-gray-300 shadow-sm focus:border-black focus:ring-2 focus:ring-black focus:outline-none focus:ring-opacity-50 focus:ring-offset-0  disabled:opacity-50 disabled:cursor-not-allowed',
              inputWrapper: 'inline-flex',
              wrapper: 'flex items-center my-1',
            }"
            v-model="filter.subjects"
            name="subjects" 
            valueAttribute="id"
            textAttribute="name"
            :options="filters.subjects"></t-checkbox-group>
        </Widget>
        <Widget v-if="filters.authors.length"
          title="Author">
          <t-checkbox-group 
            @change="filterPosts"
            :classes="{
              groupWrapper: 'flex flex-col justify-center px-0.5',
              label: 'block pl-2.5',
              input: 'rounded w-5 h-5 text-black transition duration-100 ease-in-out border-gray-300 shadow-sm focus:border-black focus:ring-2 focus:ring-black focus:outline-none focus:ring-opacity-50 focus:ring-offset-0  disabled:opacity-50 disabled:cursor-not-allowed',
              inputWrapper: 'inline-flex',
              wrapper: 'flex items-center my-1',
            }"
            v-model="filter.authors"
            name="authors" 
            valueAttribute="id"
            textAttribute="full_name"
            :options="filters.authors"></t-checkbox-group>
        </Widget>
      </div>
      <div v-if="posts.length > 0"
        :class="is_filters_showing ? 'lg:col-span-6' : ''">
        <div :class="is_filters_showing ? 'sm:grid-cols-2 md:grid-cols-3' : ' sm:grid-cols-3 md:grid-cols-4'"
          class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-8">
          <Post v-for="(post, key) in posts"
            v-bind:key="key"
            :post="post" />
        </div>
        <t-pagination
          @change="changePage"
          v-if="meta.total > meta.per_page"
          :total-items="meta.total"
          :per-page="meta.per_page"
          :limit="meta.last_page"
          v-model="filter.page"
        />
      </div>
      <div v-else
        :class="is_filters_showing ? 'lg:col-span-6' : ''"
        class="p-20 bg-gray flex flex-col items-center">
        <h2 class="text-3xl font-bold">Whoops!</h2>
        <p class="text-lg my-6">We don't have any posts that match your search!</p>
        <button v-if="filter.categories.length || filter.subjects.length || filter.authors.length"
          class="btn btn-small btn-primary"
          @click="resetFilters">Reset Search</button>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  head () {
    return {
      titleTemplate: 'Blog | %s',
    }
  },

  computed: {
    posts() {
      return this.$store.state.blog.list
    },
    filters() {
      return this.$store.state.blog.filters
    },
    meta() {
      return this.$store.state.blog.meta
    },
  },

  data() {
    return {
      is_filters_showing: true,
      search_query: '',
      filter: {
        page: 1,
        categories: [],
        subjects: [],
        authors: []
      }
    }
  },

  async asyncData ({ store, query }) {
    await store.dispatch('blog/filters')
    await store.dispatch('blog/get', query)
  },

  mounted() {
    const query = this.$route.query;
    for (const [key, value] of Object.entries(query)) {
      if(value !== null) {
        if(Array.isArray(this.filter[key])) {
          this.filter[key] = value;
        } else {
          this.filter[key] = Number(value);
        }
      } else if(Array.isArray(value) && value !== null) {
        this.filter[key].push(Number(value));
      }
    }
  },

  methods: {
    async search() {
      this.filter = {
        page: 1,
        categories: [],
        subjects: [],
        authors: []
      }
      await this.$store.dispatch('blog/get', {
        search_query: this.search_query
      })
    },
  
    async filterPosts() {
      this.filter.page = 1;
      this.$router.push({ query: this.filter })
      await this.$store.dispatch('blog/get', this.filter)
    },

    async changePage() {
      this.$router.push({ query: this.filter })
      await this.$store.dispatch('blog/get', this.filter)
    },

    async resetFilters() {
      this.filter = {
        categories: [],
        subjects: [],
        authors: []
      }

      await this.$store.dispatch('blog/get')
    }
  },

  watch: {
    search_query: function () {
      this.search()
    }
  },
}
</script>

Zerion Mini Shell 1.0