Skip to content

Instantly share code, notes, and snippets.

@igorbabko
Created August 13, 2017 16:47
Show Gist options
  • Save igorbabko/ee9fe4cec5b3dbe7a086e7e0af7b07f6 to your computer and use it in GitHub Desktop.
Save igorbabko/ee9fe4cec5b3dbe7a086e7e0af7b07f6 to your computer and use it in GitHub Desktop.
Tricky problem
<template>
<div class="custom-pages-wrapper" v-if="currentCustomPage">
<div class="top-action-bar flex-between">
<div>
<div class="title-block">
<i class="icon-pencil"></i>
<input type="text" placeholder="page title" v-model="pageTitle">
</div>
</div>
<div>
<div class="properties-block">
<span class="divider"></span>
<div class="property">
<div id="status-dropdown">
<div :class="dropdownClasses">
<span @click="toggleDropdown" class="status-dropdown-toggler">
<i :class="{'icon-eye': pageStatus === 'Published', 'icon-eye-close': pageStatus === 'Unpublished'}"></i> {{ pageStatus }} <i class="icon-arrow-down"></i>
</span>
<ul class="dropdown-menu dropdown-blue" @click="toggleDropdown">
<li>
<a href="#" @click.prevent="publish(currentCustomPage)"><i class="icon-eye"></i> Publish</a>
</li>
<li>
<a href="#" @click.prevent="unpublish(currentCustomPage)"><i class="icon-eye-close"></i>Unpublish</a>
</li>
</ul>
</div>
</div>
</div>
<div class="property">
<span>Background color: </span>
<input class="color-input" type="text" placeholder="#fff" v-model="pageBgColor">
</div>
<div class="property">
<span class="title-txt">Default font family:</span>
<multiselect
:options="fonts"
:close-on-select="true"
:allow-empty="false"
v-model="pageFont"
/>
</div>
</div>
</div>
<div class="flex buttons-block-wrapper">
<div class="buttons-block">
<button @click="togglePageTemplatesSlider()" class="btn btn-info btn-md choose-template-button"><i class="icon-web"></i> Choose a template</button>
<button @click="toggleMetaDataModal()" class="btn btn-warning btn-md choose-template-button"><i class="icon-web"></i> Meta</button>
</div>
<div class="flex extra-buttons-wrapper">
<span class="divider"></span>
<button @click="updateCustomPage()" class="btn btn-md btn-success">Update</button>
<div class="cross-block">
<router-link :to="{ name: redirectRouteName }">
<i class="icon-cross"></i>
</router-link>
</div>
</div>
</div>
</div>
<page-templates-slider
v-if="isPageTemplatesSliderVisible"
@choose="choosePageTemplate"
@preview="previewPageTemplate"
:active-page-template-id="activePageTemplateId">
</page-templates-slider>
<editable-modals/>
<meta-data-modal
:show="isMetaDataModalVisible"
:meta="metaTags"
@close="toggleMetaDataModal"
@meta-changed="updateMetaTags">
</meta-data-modal>
<preview-template-modal
:show="showPreviewModal"
@close="closePreviewModal"
:template="currentPreviewTemplate">
</preview-template-modal>
<div class="content-wrapper clearfix">
<component :is="renderedPageTemplate" @show-modal="showModal"/>
</div>
</div>
</template>
<script type="text/babel">
import {mapGetters, mapActions} from 'vuex';
import CustomPages from '../../mixins/CustomPages';
import multiselect from 'vue-multiselect'
import TextInputEditable from './../../components/Editables/TextInput.vue';
import TextareaEditable from './../../components/Editables/Textarea.vue';
import MapEditable from './../../components/Editables/Map.vue';
import PhotoGalleryEditable from './../../components/Editables/PhotoGallery.vue';
import VideoGalleryEditable from './../../components/Editables/VideoGallery.vue';
import VideoEditable from './../../components/Editables/Video.vue';
import PhotoEditable from './../../components/Editables/Photo.vue';
import LogoEditable from './../../components/Editables/Logo.vue';
import AuthorEditable from './../../components/Editables/Author.vue';
import LinkEditable from './../../components/Editables/Link.vue';
import BackgroundImageEditable from './../../components/Editables/BackgroundImage.vue';
import ContactFormEditable from './../../components/Editables/ContactForm.vue';
import EditableModals from './../../components/Editables/Modals/Index.vue';
import PreviewTemplateModal from './../../components/Editables/Modals/PreviewTemplate.vue';
import MetaDataModal from './../../components/Editables/Modals/MetaData.vue';
import PageTemplatesSlider from './../../components/PageTemplatesSlider.vue';
import swal from 'sweetalert';
import router from "./../../router";
export default {
mixins: [CustomPages],
data () {
return {
activePageTemplateId: null,
isPageTemplatesSliderVisible: false,
isMetaDataModalVisible: false,
pageTitle: '',
dropdownOpened: false,
pageTemplate: null,
currentEditableType: null,
//custom_page info retrieved from db
currentEditables: null,
showPreviewModal: false,
currentPreviewTemplate: null,
currentEditableId: null,
renderedPageTemplate: null,
customPageEditables: null,
};
},
components: {
multiselect,
PageTemplatesSlider,
EditableModals,
PreviewTemplateModal,
MetaDataModal,
},
mounted() {
//load the custom_page and its template and editables.
this.fetchCurrentCustomPage().then( response => {
this.$page = $('.content-wrapper');
this.editables = JSON.parse(this.currentCustomPage.editables);
this.pageTitle = this.currentCustomPage.title;
this.pageBgColor = this.currentCustomPage.bg_color;
this.metaTags = this.currentCustomPage.meta_tags;
this.changeFont(this.currentCustomPage.font);
this.pageStatus = this.pageStatus ? 'Published' : 'Unpublished';
this.fetchPageTemplateById(this.currentCustomPage.page_template_id).then( response => {
// this.applyStyles(response.data.data.css);
this.activePageTemplateId = response.data.data.id;
this.pageTemplate = response.data.data;
this.choosePageTemplate(this.pageTemplate, false);
});
});
this.fetchPageTemplates({noPackage: true});
document.body.addEventListener('click', this.callOnOutsideClickIfNeeded);
},
destroyed() {
document.body.removeEventListener('click', this.callOnOutsideClickIfNeeded);
},
methods: {
...mapActions(['fetchPageTemplates', 'fetchCurrentCustomPage', 'fetchPageTemplateById', 'publish', 'unpublish', 'resetCurrentEditable', 'setEditables']),
showModal(editableType, editableId) {
},
choosePageTemplate(pageTemplate, toggleSlider = true) {
this.pageTemplate = pageTemplate;
this.activePageTemplateId = pageTemplate.id;
// this.pageBgColor = pageTemplate.bg_color;
// this.changeFont(pageTemplate.font);
this.applyStyles(pageTemplate.css);
if (toggleSlider) {
this.togglePageTemplatesSlider();
}
this.parseEditables(pageTemplate);
let savedEditables = JSON.parse(this.currentCustomPage.editables);
let templateEditables = this.editables;
this.loadCustomPageDataToTemplate(savedEditables, templateEditables);
this.renderedPageTemplate = {
template: this.renderPageTemplate(pageTemplate.html),
components: {
TextInputEditable,
TextareaEditable,
PhotoEditable,
VideoEditable,
PhotoGalleryEditable,
VideoGalleryEditable,
MapEditable,
LogoEditable,
AuthorEditable,
LinkEditable,
BackgroundImageEditable,
ContactFormEditable,
},
methods: {
showModal(editableType) {
this.$emit('show-modal', editableType);
},
},
};
},
previewPageTemplate(pageTemplate){
this.customPageEditables = this.editables;
this.showPreviewModal = true;
this.currentPreviewTemplate = pageTemplate;
},
callOnOutsideClickIfNeeded(e) {
if (!e || !this.currentCustomPage) return;
if (e.target != document.getElementById('status-dropdown') && !document.getElementById('status-dropdown').contains(e.target)) {
this.onOutsideClick();
}
},
toggleDropdown() {
this.dropdownOpened = !this.dropdownOpened;
},
onOutsideClick(){
if(this.dropdownOpened) this.toggleDropdown();
},
updateCustomPage() {
let url = '/api/custom-pages/' + this.currentCustomPage.url;
this.$http.patch(url, this.formData, { emulateJSON: true}).then(
response => {
swal({title: "Custom page has been successfully updated!", type: "success"});
},response => {
this.displayErrors(response.body);
}
);
},
togglePageTemplatesSlider() {
this.isPageTemplatesSliderVisible = ! this.isPageTemplatesSliderVisible;
},
closeModal() {
this.resetCurrentEditable();
},
closePreviewModal() {
$('.preview-modal style').remove();
this.setEditables(this.customPageEditables);
this.showPreviewModal = false;
this.currentPreviewTemplate = null;
},
displayErrors(errors) {
let text = null;
if(errors)
{
text = '<ul class="swal-error-list">';
for (var key in errors) {
text += '<li>' + errors[key][0] + '</li>';
}
text += '</ul>';
}
swal({
title: "Validation Errors!",
text: text,
html: true,
type: "error",
});
}
},
computed: {
...mapGetters(['currentCustomPage', 'currentPageTemplate', 'currentEditable']),
pageStatus() {
return this.currentCustomPage.published ? 'Published' : 'Unpublished';
},
dropdownClasses () {
return this.dropdownOpened ? 'dropdown open' : 'dropdown';
},
formData() {
return {
'title': this.pageTitle,
'url': this.currentCustomPage.url,
'bg_color': this.pageBgColor,
'font': this.pageFont ? this.pageFont : '',
'editables': JSON.stringify(this.editables),
'page_template_id': this.pageTemplate.id,
'meta_tags': this.metaTags,
};
}
},
}
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment