%PDF- %PDF-
Direktori : /home/forge/takeaseat.eco-n-tech.co.uk/pages/therapists/ |
Current File : //home/forge/takeaseat.eco-n-tech.co.uk/pages/therapists/index.vue |
<template> <div class="page-wrapper"> <PageHeader classObject="bg-green z-30"> <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">Find a therapist</h1> <div ref="scrollTo" class="page-header-bottom grid grid-cols-1 md:grid-cols-2 gap-x-4"> <div class="flex items-center justify-center md:justify-start"> <SearchForm v-model="selected_filters.search_query" placeholder="Search Therapists" /> </div> <div class="flex items-center justify-center md:justify-end mt-6 md:mt-0"> <button @click="toggleFilters" 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 lg:gap-10' : ''" class="px-6 lg:px-0"> <div v-if="is_filters_showing" class="lg:col-span-2"> <div @click="toggleFilters" v-if="is_filters_showing" class="block fixed top-0 left-0 w-full h-full z-40 bg-black bg-opacity-20 lg:hidden"></div> <div :class="isFiltersActive ? 'pb-28' : 'pb-20'" class="fixed z-50 bottom-0 right-0 w-10/12 h-screen p-4 overflow-y-auto bg-white lg:static lg:h-auto lg:w-auto lg:p-0 lg:z-1"> <span class="mb-8 block text-xl font-bold">Filter</span> <button v-if="isFiltersActive" class="block -mt-3 mb-6 uppercase transition text-blue-light hover:text-black focus:outline-none" @click="resetFilters">Reset Filters</button> <Widget title="Location"> <div class="grid grid-cols-1 sm:grid-cols-6 gap-x-4"> <div class="sm:col-span-4"> <ValidationProvider name="postcode" :rules="{ regex: /^(([gG][iI][rR] {0,}0[aA]{2})|((([a-pr-uwyzA-PR-UWYZ][a-hk-yA-HK-Y]?[0-9][0-9]?)|(([a-pr-uwyzA-PR-UWYZ][0-9][a-hjkstuwA-HJKSTUW])|([a-pr-uwyzA-PR-UWYZ][a-hk-yA-HK-Y][0-9][abehmnprv-yABEHMNPRV-Y]))) {0,}[0-9][abd-hjlnp-uw-zABD-HJLNP-UW-Z]{2}))$/ }" v-slot="{ errors }"> <t-input-group label="Postcode"> <t-input @keyup="filterOnKeyUp" v-model="selected_filters.postcode" placeholder="Enter your postcode" /> <span class="field-invalid" v-if="errors[0]">{{ errors[0] }}</span> </t-input-group> </ValidationProvider> </div> <div class="sm:col-span-2"> <ValidationProvider name="postcode" rules="required" v-slot="{ errors }"> <t-input-group label="Distance"> <t-select @change="filter" v-model="selected_filters.distance" :options="[ { id: 5, text: '5 miles' }, { id: 10, text: '10 miles' }, { id: 20, text: '20 miles' }, { id: 30, text: '30 miles' }, { id: 40, text: '40 miles' }, { id: 50, text: '50 miles' }, ]" /> <span class="field-invalid" v-if="errors[0]">{{ errors[0] }}</span> </t-input-group> </ValidationProvider> </div> </div> </Widget> <Widget title="Session Types"> <t-checkbox-group @change="filter" :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="selected_filters.session_types" name="session_types" valueAttribute="id" textAttribute="name" :options="filters.session_types"></t-checkbox-group> </Widget> <Widget title="Specialisms"> <t-checkbox-group @change="filter" :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="selected_filters.specialisms" name="specialisms" valueAttribute="id" textAttribute="name" :options="filters.specialisms"></t-checkbox-group> </Widget> <Widget title="Languages"> <t-checkbox-group @change="filter" :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="selected_filters.languages" name="languages" valueAttribute="id" textAttribute="name" :options="filters.languages"></t-checkbox-group> </Widget> <Widget title="Tags"> <t-checkbox-group @change="filter" :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="selected_filters.tags" name="tags" valueAttribute="id" textAttribute="name" :options="filters.tags"></t-checkbox-group> </Widget> <div class="block lg:hidden text-center fixed bottom-0 right-0 w-10/12 p-3 border-t border-black border-opacity-20 bg-white"> <button v-if="isFiltersActive" class="inline-block mb-3 uppercase transition text-blue-light hover:text-black focus:outline-none" @click="resetFilters">Reset Filters</button> <button @click="viewResults" class="btn btn-primary btn-small w-full">View Results</button> </div> </div> </div> <div v-if="meta.total > 0" :class="is_filters_showing ? 'lg:col-span-6' : ''"> <div :class="is_filters_showing ? 'grid-cols-1 md:grid-cols-2' : ' grid-cols-1 md:grid-cols-2 lg:grid-cols-3'" class="grid gap-x-8 gap-y-12"> <Therapist v-for="(therapist, key) in therapists" v-bind:key="key" :therapist="therapist" /> </div> <div v-if="meta.total > meta.current_page" class="mt-8 sm:flex sm:items-center sm:justify-center sm:px-6 lg:px-0"> <button v-if="current_page !== 1" @click="previousPage" class="btn btn-primary rounded-full shadow-md my-2 sm:my-0 sm:mx-3">Previous Page</button> <button v-if="current_page < meta.last_page" @click="nextPage" class="btn btn-primary rounded-full shadow-md my-2 sm:my-0 sm:mx-3">Next Page</button> </div> </div> <div v-else :class="is_filters_showing ? 'lg:col-span-6' : ''" class="text-center py-10 md:py-20 px-6 md:px-8 bg-gray"> <p class="text-2xl md:text-4xl font-bold m-0">No therapists found</p> </div> </div> </div> </template> <script> export default { head () { return { titleTemplate: 'Therapists | %s', } }, data() { return { timer: null, is_filters_showing: false, is_sortby_showing: false, current_page: 1, selected_filters: { search_query: null, postcode: null, distance: 30, session_types: [], specialisms: [], tags: [], languages: [] } } }, computed: { therapists() { return this.$store.state.therapists.list }, filters() { return this.$store.state.therapists.filters }, meta() { return this.$store.state.therapists.meta }, isFiltersActive() { return this.selected_filters.session_types.length || this.selected_filters.specialisms.length || this.selected_filters.tags.length || this.selected_filters.languages.length || this.selected_filters.postcode != null; } }, async asyncData ({ store, query, params }) { await store.dispatch('therapists/filters') await store.dispatch('therapists/get', query) }, mounted() { const query = this.$route.query; this.current_page = Number(query.page) || 1; for (const [key, value] of Object.entries(query)) { if(Array.isArray(this.selected_filters[key])) { if(Array.isArray(query[key])) { this.selected_filters[key] = value.map(function (x) { return parseInt(x, 10); }); } else { this.selected_filters[key] = [parseInt(value, 10)]; } } else { this.selected_filters[key] = value; } } if(Object.keys(query).length !== 0 && window.innerWidth >= 1024) { this.is_filters_showing = true; } }, methods: { async filter() { this.current_page = 1; this.$router.push({ path: '/therapists', query: this.selected_filters }) await this.$store.dispatch('therapists/get', this.selected_filters) }, filterOnKeyUp() { if (this.timer) { clearTimeout(this.timer); this.timer = null; } this.timer = setTimeout(() => { this.filter(); }, 500); }, async sortBy() { this.$router.push({ path: '/therapists', query: this.selected_filters }) await this.$store.dispatch('therapists/get', this.selected_filters) }, async previousPage() { this.scrollToTop(); this.current_page = this.current_page - 1; this.$router.push({ query: { specialisms: this.filter.specialisms, session_types: this.selected_filters.session_types, tags: this.selected_filters.tags, page: this.current_page }} ); await this.$store.dispatch('therapists/get', { specialisms: this.filter.specialisms, session_types: this.selected_filters.session_types, tags: this.selected_filters.tags, page: this.current_page }) }, async nextPage() { this.scrollToTop(); this.current_page = this.current_page + 1; this.$router.push({ query: { specialisms: this.filter.specialisms, session_types: this.selected_filters.session_types, tags: this.selected_filters.tags, page: this.current_page }} ); await this.$store.dispatch('therapists/get', { specialisms: this.filter.specialisms, session_types: this.selected_filters.session_types, tags: this.selected_filters.tags, page: this.current_page }) }, toggleFilters() { if(this.is_filters_showing == false) { this.is_filters_showing = true; } else { this.is_filters_showing = false; } }, viewResults() { this.scrollToTop(); this.is_filters_showing = false; }, async resetFilters() { this.selected_filters = { postcode: null, distance: 30, session_types: [], specialisms: [], tags: [], languages: [] } await this.$store.dispatch('therapists/get') }, scrollToTop() { if (this.$refs.scrollTo) { this.$SmoothScroll(this.$refs.scrollTo, 500); } } }, watch: { 'selected_filters.search_query': function () { this.filter() } }, } </script>