%PDF- %PDF-
Direktori : /home/forge/takeaseat.eco-n-tech.co.uk/components/blocks/Account/profile/ |
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>