%PDF- %PDF-
Mini Shell

Mini Shell

Direktori : /home/forge/takeaseat.eco-n-tech.co.uk/components/blocks/Account/profile/
Upload File :
Create Path :
Current File : //home/forge/takeaseat.eco-n-tech.co.uk/components/blocks/Account/profile/Personalisation.vue

<template>
  <Block title="Personalisation"
    description="Upload a photo & choose a colour that makes you stand out">
    <ValidationObserver ref="form">
      <form @submit.prevent="uploadPhoto" role="form" method="POST">
        <ValidationProvider rules="image|size:10000" ref="provider" v-slot="{ validate, errors }">
          <div style="max-width: 170px"
            class="w-full mx-auto mb-8 text-center">
            <label class="block cursor-pointer"
              for="file">
              <div v-if="photo_url"
                class="relative">
                <div :class="'tas-border-'+selected_colour"
                  class="absolute top-0 left-0 w-full h-full border-15 border-opacity-50"></div>
                <img
                  class="w-full"
                  :src="photo_url"
                  :alt="user.data.full_name" />
              </div>
              <div style="height: 170px"
                class="w-full flex items-center justify-center border-2 border-dashed border-black border-opacity-20 rounded-md"
                v-else>
                <span class="text-sm text-black">Click to upload</span>
              </div>
              <input
                @change="handleFileChange()"
                class="hidden"
                type="file"
                ref="file"
                id="file"
                accept="image/*" />
              <span class="mt-4 block uppercase text-blue-light">Upload Photo</span>
            </label>
            <span class="field-invalid" v-if="errors[0]">{{ errors[0] }}</span>
          </div>
          <t-modal
            ref="cropModal"
            header="Crop & Upload">
            <vue-croppie
              ref="croppieRef"
              :enableOrientation="true"
              :enableResize="false"
              :boundary="{ width: 270, height: 270}"
              :viewport="{ width: 250, height: 250}"
              @result="result">
            </vue-croppie>
            <template v-slot:footer>
              <div class="flex flex-wrap justify-between">
                <button
                  @click="$refs.cropModal.hide()"
                  class="btn btn-small btn-primary"
                  type="button">
                  Cancel
                </button>
                <button
                  class="btn btn-small btn-primary"
                  @click="crop()"
                  type="button">
                  <span v-if="working == false">Crop & Upload</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>Processing</span>
                  </span>
                </button>
              </div>
            </template>
          </t-modal>
        </ValidationProvider>
      </form>
    </ValidationObserver>
    <div class="grid grid-cols-1 sm:grid-cols-4 bg-black mb-8">
      <div class="relative col-span-1">
        <div :class="'tas-border-'+selected_colour"
          class="absolute top-0 left-0 w-full h-full border-10 border-opacity-75"></div>
        <img class="w-full"
          :src="photo_url" :alt="user.data.full_name" />
      </div>
      <div class="sm:col-span-3 py-6 sm:py-0 flex flex-col items-center justify-center">
        <span
          :class="'tas-text-'+selected_colour"
          class="text-5xl text-white ">{{ user.data.first_name }}</span>
        <span class="uppercase text-xl text-white">{{ user.data.last_name }}</span>
      </div>
    </div>
    <t-input-group label="Colour Options">
      <div class="grid grid-cols-4 sm:grid-cols-5 gap-5 sm:gap-10 mb-10 pt-3">
        <div v-for="(colour, key) in colours"
          v-bind:key="key"
          class="flex items-center justify-center">
          <label
            :class="'tas-bg-'+colour.name"
            class="flex items-center justify-center relative w-10 h-10 rounded cursor-pointer">
            <svg v-if="colour.name == selected_colour"
              class="text-white w-8 h-8" 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="M5 13l4 4L19 7" />
            </svg>
            <input
              @change="saveTheme"
              v-model="selected_colour"
              name="colours"
              class="absolute top-0 left-0 w-full h-full hidden"
              type="radio"
              :value="colour.name" />
          </label>
        </div>
      </div>
    </t-input-group>
  </Block>
</template>

<script>
export default {
  data() {
    return {
      working: false,
      showModal: false,
      photo_url: null,
      file: null,
      selected_colour: 'yellow',
      colours: [
        {
          name: 'yellow'
        },
        {
          name: 'green'
        },
        {
          name: 'pink'
        },
        {
          name: 'blue-light'
        },
        {
          name: 'blue-medium'
        },
        {
          name: 'orange'
        },
        {
          name: 'green-dark'
        },
        {
          name: 'red'
        },
        {
          name: 'blue'
        },
        {
          name: 'purple'
        }
      ],
    }
  },

  computed: {
    user() {
      return this.$auth.user;
    }
  },

  async mounted() {
    await this.$axios.$get('/profile').then((response) => {
      this.selected_colour = response.data.colour
      this.photo_url = response.data.user.photo_url;
    })
  },

  methods: {
    async handleFileChange(e) {
      const { valid } = await this.$refs.provider.validate(e);
      let fileUrl = this.$refs.file.files[0];

      if (valid == true) {
        this.$refs.cropModal.show()
        if(fileUrl) {
          setTimeout(() => {
            this.$refs.croppieRef.bind({
              url: URL.createObjectURL(fileUrl)
            });
          }, 250)
        }
      }
    },

    crop() {
      let options = {
        format: 'jpeg'
      }

      this.$refs.croppieRef.result(options, (output) => {
        this.file = output;
        this.uploadPhoto();
      });
    },

    result(output) {
      this.file = output;
    },

    async uploadPhoto() {
      this.$refs.form.validate().then(success => {
        if (!success) {
          return;
        }

        this.working = true;
        this.$axios.$post('/account/profile/photo', {
          file: this.file
        }).then((response) => {
          this.working = false;
          this.photo_url = response;
          this.$refs.cropModal.hide()
          this.$store.dispatch('account/progress/get', { slug: 'profile' })
          this.$toast.success('Successfully updated your photo').goAway(1500);
        }).catch(error => {
          this.working = false;
          this.$refs.cropModal.hide()
          this.$refs.form.setErrors(error.response.data.errors);
        })
      })
    },

    async saveTheme() {
      this.working = true;
      this.$axios.$post('/profile/update', {
        colour: this.selected_colour
      }).then((response) => {
        this.working = false;
        this.$toast.success('Successfully updated your colour').goAway(1500);
      })
    }
  }
}
</script>

Zerion Mini Shell 1.0