- Complete GGZ Ecademy Nuxt.js user portal - Learning products browser and management - Member management interface - User authentication and roles - Multi-language support (NL/EN) - Vuex store for state management - Component-based architecture
This commit is contained in:
603
components/Learning/ProductOverview/Basic.vue
Normal file
603
components/Learning/ProductOverview/Basic.vue
Normal file
@@ -0,0 +1,603 @@
|
||||
<template>
|
||||
<accordion-card :title="$t('learning.product_overview.basic')">
|
||||
<v-row>
|
||||
<v-col cols="12" sm="12" md="3">
|
||||
<v-subheader class="txt--text font-weight-black">{{
|
||||
$t('learning.product_overview.title')
|
||||
}}</v-subheader>
|
||||
</v-col>
|
||||
<v-col cols="12" sm="12" md="6">
|
||||
<v-text-field
|
||||
v-model="title"
|
||||
:rules="rules.title"
|
||||
:placeholder="$t('learning.product_overview.placeholder.titel')"
|
||||
:hide-details="!editMode"
|
||||
:outlined="editMode"
|
||||
:solo="!editMode"
|
||||
:disabled="!editMode"
|
||||
:flat="!editMode"
|
||||
required
|
||||
error
|
||||
/>
|
||||
</v-col>
|
||||
<v-col cols="12" sm="12" md="3">
|
||||
<v-subheader v-if="editMode"></v-subheader>
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<v-row>
|
||||
<v-col cols="12" sm="12" md="3">
|
||||
<v-subheader class="txt--text font-weight-black">{{
|
||||
$t('learning.product_overview.code')
|
||||
}}</v-subheader>
|
||||
</v-col>
|
||||
<v-col cols="12" sm="12" md="6">
|
||||
<v-text-field
|
||||
v-model="code"
|
||||
:placeholder="$t('learning.product_overview.placeholder.productcode')"
|
||||
:outlined="editMode"
|
||||
:solo="!editMode"
|
||||
:disabled="!editMode"
|
||||
:flat="!editMode"
|
||||
:rules="rules.code"
|
||||
required
|
||||
error
|
||||
></v-text-field>
|
||||
</v-col>
|
||||
<v-col cols="12" sm="12" md="3"> </v-col>
|
||||
</v-row>
|
||||
|
||||
<v-row>
|
||||
<v-col cols="12" sm="12" md="3">
|
||||
<v-subheader class="txt--text font-weight-black in_the_picture"
|
||||
>Van leden voor leden</v-subheader
|
||||
>
|
||||
</v-col>
|
||||
<v-col cols="12" sm="12" md="9" class="mb-4 d-flex flex-column">
|
||||
<div class="pb-0 mb-0 d-flex">
|
||||
<v-switch
|
||||
:disabled="!editMode"
|
||||
inset
|
||||
class="my-3 toggle"
|
||||
v-model="for_members"
|
||||
/>
|
||||
</div>
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<v-row>
|
||||
<v-col cols="12" sm="12" md="3">
|
||||
<v-subheader class="txt--text font-weight-black"> Url </v-subheader>
|
||||
</v-col>
|
||||
<v-col cols="12" sm="12" md="6">
|
||||
<v-text-field
|
||||
v-model="url"
|
||||
:placeholder="$t('learning.product_overview.placeholder.url')"
|
||||
:outlined="editMode"
|
||||
:solo="!editMode"
|
||||
:disabled="!editMode"
|
||||
:flat="!editMode"
|
||||
></v-text-field>
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<v-row>
|
||||
<v-col cols="12" sm="12" md="3">
|
||||
<v-subheader class="txt--text font-weight-black">{{
|
||||
$t('learning.product_overview.status')
|
||||
}}</v-subheader>
|
||||
</v-col>
|
||||
<v-col cols="12" sm="12" md="6">
|
||||
<universalFilterSelector filterTitle="status" :editMode="editMode" />
|
||||
</v-col>
|
||||
<v-col cols="12" sm="12" md="3"> </v-col>
|
||||
</v-row>
|
||||
|
||||
<v-row>
|
||||
<v-col cols="12" sm="12" md="3">
|
||||
<v-subheader class="txt--text font-weight-black">
|
||||
Tegel afbeelding
|
||||
</v-subheader>
|
||||
</v-col>
|
||||
<v-col cols="12" sm="12" md="6" class="pl-6">
|
||||
<vue-dropzone
|
||||
ref="imgDropZoneTile"
|
||||
class="cta-secondary my-4"
|
||||
id="customdropzoneTile"
|
||||
:options="dropzoneOptions"
|
||||
@vdropzone-complete="afterCompleteTile"
|
||||
v-if="editMode"
|
||||
/>
|
||||
|
||||
<v-img
|
||||
:src="tileComputed || noImage"
|
||||
:lazy-src="noImage"
|
||||
contain
|
||||
v-cloak
|
||||
/>
|
||||
</v-col>
|
||||
<v-col cols="12" sm="12" md="3">
|
||||
<v-subheader v-if="editMode" class="mt-12">
|
||||
{{ $t('learning.product_overview.allowed') }} <br />
|
||||
{{ $t('learning.product_overview.allowed2') }}
|
||||
</v-subheader>
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<v-row>
|
||||
<v-col cols="12" sm="12" md="3">
|
||||
<v-subheader class="txt--text font-weight-black">{{
|
||||
$t('general.image')
|
||||
}}</v-subheader>
|
||||
</v-col>
|
||||
<v-col cols="12" sm="12" md="6" class="pl-6">
|
||||
<vue-dropzone
|
||||
ref="imgDropZoneCover"
|
||||
class="cta-secondary my-4"
|
||||
id="customdropzone"
|
||||
:options="dropzoneOptions"
|
||||
@vdropzone-complete="afterCompleteCover"
|
||||
v-if="editMode"
|
||||
/>
|
||||
|
||||
<v-img
|
||||
:src="coverComputed || noImage"
|
||||
:lazy-src="noImage"
|
||||
contain
|
||||
v-cloak
|
||||
/>
|
||||
</v-col>
|
||||
<v-col cols="12" sm="12" md="3">
|
||||
<v-subheader v-if="editMode" class="mt-12">
|
||||
{{ $t('learning.product_overview.allowed') }} <br />
|
||||
{{ $t('learning.product_overview.allowed2') }}
|
||||
</v-subheader>
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<v-row>
|
||||
<v-col cols="12" sm="12" md="3">
|
||||
<v-subheader class="txt--text font-weight-black">Video</v-subheader>
|
||||
</v-col>
|
||||
<v-col cols="12" sm="12" md="6" class="pl-6">
|
||||
<v-text-field
|
||||
v-model="video"
|
||||
prepend-inner-icon="mdi-youtube"
|
||||
:placeholder="$t('learning.product_overview.placeholder.trailer')"
|
||||
:outlined="editMode"
|
||||
:solo="!editMode"
|
||||
:disabled="!editMode"
|
||||
:flat="!editMode"
|
||||
v-if="editMode"
|
||||
class="youtube"
|
||||
/>
|
||||
|
||||
<iframe
|
||||
v-if="video"
|
||||
width="100%"
|
||||
height="480"
|
||||
frameborder="0"
|
||||
scrolling="auto"
|
||||
marginheight="0"
|
||||
marginwidth="0"
|
||||
:src="video"
|
||||
allowfullscreen
|
||||
msallowfullscreen
|
||||
allow="fullscreen"
|
||||
></iframe>
|
||||
</v-col>
|
||||
<v-col cols="12" sm="12" md="3">
|
||||
<v-subheader v-if="editMode">
|
||||
{{ $t('learning.product_overview.allowed_trailer') }}
|
||||
</v-subheader>
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<v-row>
|
||||
<v-col cols="12" sm="12" md="3">
|
||||
<v-subheader class="txt--text font-weight-black">{{
|
||||
$t('learning.product_overview.duration')
|
||||
}}</v-subheader>
|
||||
</v-col>
|
||||
<v-col cols="12" sm="12" md="6">
|
||||
<v-text-field
|
||||
v-model="lead_time"
|
||||
:placeholder="$t('learning.product_overview.duration')"
|
||||
:outlined="editMode"
|
||||
:solo="!editMode"
|
||||
:disabled="!editMode"
|
||||
:flat="!editMode"
|
||||
></v-text-field>
|
||||
</v-col>
|
||||
<v-col cols="12" sm="12" md="3"> </v-col>
|
||||
</v-row>
|
||||
|
||||
<v-row>
|
||||
<v-col cols="12" sm="12" md="3">
|
||||
<v-subheader class="txt--text font-weight-black">{{
|
||||
$t('learning.filters.level') | capitalize
|
||||
}}</v-subheader>
|
||||
</v-col>
|
||||
<v-col cols="12" sm="12" md="6">
|
||||
<universalFilterSelector
|
||||
id="level"
|
||||
filterTitle="level"
|
||||
:editMode="editMode"
|
||||
filterType="mixed"
|
||||
/>
|
||||
</v-col>
|
||||
<v-col cols="12" sm="12" md="3"> </v-col>
|
||||
</v-row>
|
||||
|
||||
<v-row>
|
||||
<v-col cols="12" sm="12" md="3">
|
||||
<v-subheader class="txt--text font-weight-black">
|
||||
SEO Title
|
||||
</v-subheader>
|
||||
</v-col>
|
||||
<v-col cols="12" sm="12" md="6">
|
||||
<v-text-field
|
||||
v-model="seo_title"
|
||||
:placeholder="$t('learning.product_overview.placeholder.seo_title')"
|
||||
:outlined="editMode"
|
||||
:solo="!editMode"
|
||||
:disabled="!editMode"
|
||||
:flat="!editMode"
|
||||
:rules="rules.seo_title"
|
||||
required
|
||||
error
|
||||
></v-text-field>
|
||||
</v-col>
|
||||
<v-col cols="12" sm="12" md="3"> </v-col>
|
||||
</v-row>
|
||||
|
||||
<v-row>
|
||||
<v-col cols="12" sm="12" md="3">
|
||||
<v-subheader class="txt--text font-weight-black">
|
||||
Meta description
|
||||
</v-subheader>
|
||||
</v-col>
|
||||
<v-col cols="12" sm="12" md="6">
|
||||
<v-textarea
|
||||
v-model="meta_description"
|
||||
:placeholder="
|
||||
$t('learning.product_overview.placeholder.meta_description')
|
||||
"
|
||||
:outlined="editMode"
|
||||
:solo="!editMode"
|
||||
:disabled="!editMode"
|
||||
:flat="!editMode"
|
||||
></v-textarea>
|
||||
</v-col>
|
||||
<v-col cols="12" sm="12" md="3"> </v-col>
|
||||
</v-row>
|
||||
|
||||
<v-row>
|
||||
<v-col cols="12" sm="12" md="3">
|
||||
<v-subheader class="txt--text font-weight-black">
|
||||
Synoniemen
|
||||
</v-subheader>
|
||||
</v-col>
|
||||
<v-col cols="12" sm="12" md="6">
|
||||
<synonyms-selector :editMode="editMode" />
|
||||
</v-col>
|
||||
<v-col cols="12" sm="12" md="3"> </v-col>
|
||||
</v-row>
|
||||
</accordion-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import accordionCard from '@/components/UI/AccordionCard/AccordionCard'
|
||||
import universalFilterSelector from '@/components/UniversalFilterSelector/UniversalFilterSelector'
|
||||
import synonymsSelector from '@/components/Learning/SynonymsSelector'
|
||||
import vueDropzone from 'vue2-dropzone'
|
||||
import 'vue2-dropzone/dist/vue2Dropzone.min.css'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
accordionCard,
|
||||
vueDropzone,
|
||||
universalFilterSelector,
|
||||
synonymsSelector,
|
||||
},
|
||||
props: {
|
||||
editMode: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
date: new Date().toISOString().substr(0, 7),
|
||||
menu: false,
|
||||
modal: false,
|
||||
dialog: false,
|
||||
valid: true,
|
||||
lazy: false,
|
||||
loading: false,
|
||||
dropzoneOptions: {
|
||||
url: 'https://httpbin.org/post',
|
||||
maxFilesize: 1.2, // MB
|
||||
maxFiles: 1,
|
||||
thumbnailWidth: 150,
|
||||
thumbnailHeight: 150,
|
||||
addRemoveLinks: true,
|
||||
acceptedFiles: '.jpg, .jpeg, .png',
|
||||
dictDefaultMessage: `<p><i class='icon icon-image mr-2'></i> Upload afbeelding</p>`,
|
||||
},
|
||||
images: [],
|
||||
rules: {
|
||||
// title: [(v) => 'De titel is verplicht'],
|
||||
// code: [(v) => !!v || 'De productcode is verplicht'],
|
||||
// seo_title: [(v) => !!v || 'De SEO-titel is verplicht'],
|
||||
title: [(v) => 'De titel is verplicht'],
|
||||
code: [(v) => 'De productcode is verplicht'],
|
||||
seo_title: [(v) => 'De SEO-titel is verplicht'],
|
||||
},
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
local() {
|
||||
return this.$store.getters.localProduct
|
||||
},
|
||||
|
||||
title: {
|
||||
get() {
|
||||
return this.local.title
|
||||
},
|
||||
set(value) {
|
||||
this.$store.commit('learning/UPDATE_FIELD', { field: 'title', value })
|
||||
},
|
||||
},
|
||||
code: {
|
||||
get() {
|
||||
return this.local.code
|
||||
},
|
||||
set(value) {
|
||||
this.$store.commit('learning/UPDATE_FIELD', { field: 'code', value })
|
||||
},
|
||||
},
|
||||
|
||||
for_members: {
|
||||
get() {
|
||||
return this.local.for_members
|
||||
},
|
||||
set(value) {
|
||||
this.$store.commit('learning/UPDATE_FIELD', {
|
||||
field: 'for_members',
|
||||
value,
|
||||
})
|
||||
},
|
||||
},
|
||||
|
||||
status: {
|
||||
get() {
|
||||
return this.local.status
|
||||
},
|
||||
set(value) {
|
||||
this.$store.commit('learning/UPDATE_FIELD', { field: 'status', value })
|
||||
},
|
||||
},
|
||||
video: {
|
||||
get() {
|
||||
return this.local.video
|
||||
},
|
||||
set(value) {
|
||||
this.$store.commit('learning/UPDATE_FIELD', { field: 'video', value })
|
||||
},
|
||||
},
|
||||
lead_time: {
|
||||
get() {
|
||||
return this.local.lead_time
|
||||
},
|
||||
set(value) {
|
||||
this.$store.commit('learning/UPDATE_FIELD', {
|
||||
field: 'lead_time',
|
||||
value,
|
||||
})
|
||||
},
|
||||
},
|
||||
|
||||
seo_title: {
|
||||
get() {
|
||||
return this.local.seo_title
|
||||
},
|
||||
set(value) {
|
||||
this.$store.commit('learning/UPDATE_FIELD', {
|
||||
field: 'seo_title',
|
||||
value,
|
||||
})
|
||||
},
|
||||
},
|
||||
|
||||
meta_description: {
|
||||
get() {
|
||||
return this.local.meta_description
|
||||
},
|
||||
set(value) {
|
||||
this.$store.commit('learning/UPDATE_FIELD', {
|
||||
field: 'meta_description',
|
||||
value,
|
||||
})
|
||||
},
|
||||
},
|
||||
|
||||
url: {
|
||||
get() {
|
||||
return this.local.url
|
||||
},
|
||||
set(value) {
|
||||
this.$store.commit('learning/UPDATE_FIELD', {
|
||||
field: 'url',
|
||||
value,
|
||||
})
|
||||
},
|
||||
},
|
||||
|
||||
level: {
|
||||
get() {
|
||||
return this.local.level
|
||||
},
|
||||
set(value) {
|
||||
this.$store.commit('learning/UPDATE_FIELD', {
|
||||
field: 'level',
|
||||
value,
|
||||
})
|
||||
},
|
||||
},
|
||||
|
||||
levelItems() {
|
||||
if (!this.$store.getters.filters.length > 0) return []
|
||||
return this.$store.getters.filters.find(
|
||||
(filter) => filter.title === 'level'
|
||||
).items
|
||||
},
|
||||
|
||||
cover() {
|
||||
return this.local.cover
|
||||
},
|
||||
|
||||
coverComputed() {
|
||||
if (this.$store.state.learning.cover.url)
|
||||
return this.$store.state.learning.cover.url
|
||||
if (this.local.cover) return this.local.cover.full
|
||||
return null
|
||||
},
|
||||
|
||||
tile() {
|
||||
return this.local.tile
|
||||
},
|
||||
|
||||
tileComputed() {
|
||||
if (this.$store.state.learning.tile.url)
|
||||
return this.$store.state.learning.tile.url
|
||||
if (this.local.tile) return this.local.tile.full
|
||||
return null
|
||||
},
|
||||
noImage() {
|
||||
return require(`@/assets/img/no_image.png`)
|
||||
},
|
||||
},
|
||||
|
||||
methods: {
|
||||
async afterCompleteTile(file) {
|
||||
if (file === undefined) return
|
||||
if (file.name.lastIndexOf('.') <= 0) return
|
||||
|
||||
if (file.size > 2000000) {
|
||||
this.$notifier.showMessage({
|
||||
content: `Exceeded Max filesize`,
|
||||
color: 'error',
|
||||
icon: 'mdi-alert-circle',
|
||||
})
|
||||
this.$store.commit('learning/RESET_TILE')
|
||||
return
|
||||
}
|
||||
|
||||
this.isLoading = true
|
||||
|
||||
try {
|
||||
const fr = new FileReader()
|
||||
fr.readAsDataURL(file)
|
||||
fr.addEventListener('load', () => {
|
||||
this.$store.commit('learning/UPDATE_TILE', {
|
||||
name: file.name,
|
||||
url: fr.result,
|
||||
file: file,
|
||||
})
|
||||
})
|
||||
this.isLoading = false
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
this.$refs.imgDropZoneTile.removeFile(file)
|
||||
},
|
||||
|
||||
async afterCompleteCover(file) {
|
||||
if (file === undefined) return
|
||||
if (file.name.lastIndexOf('.') <= 0) return
|
||||
|
||||
if (file.size > 2000000) {
|
||||
this.$notifier.showMessage({
|
||||
content: `Exceeded Max filesize`,
|
||||
color: 'error',
|
||||
icon: 'mdi-alert-circle',
|
||||
})
|
||||
this.$store.commit('learning/RESET_COVER')
|
||||
return
|
||||
}
|
||||
|
||||
this.isLoading = true
|
||||
|
||||
try {
|
||||
const fr = new FileReader()
|
||||
fr.readAsDataURL(file)
|
||||
fr.addEventListener('load', () => {
|
||||
this.$store.commit('learning/UPDATE_COVER', {
|
||||
name: file.name,
|
||||
url: fr.result,
|
||||
file: file,
|
||||
})
|
||||
})
|
||||
this.isLoading = false
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
this.$refs.imgDropZoneCover.removeFile(file)
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
#level >>> .v-input__slot .v-select__slot {
|
||||
margin-left: -4px;
|
||||
}
|
||||
|
||||
.image-div {
|
||||
display: flex;
|
||||
margin: 25px;
|
||||
}
|
||||
.image {
|
||||
max-width: 250px;
|
||||
margin: 15px;
|
||||
}
|
||||
|
||||
#customdropzone {
|
||||
margin-top: -10px;
|
||||
}
|
||||
|
||||
#customdropzone >>> .icon {
|
||||
position: relative;
|
||||
top: 4px;
|
||||
}
|
||||
|
||||
#customdropzone >>> p {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.mt-12 {
|
||||
margin-top: 35px !important;
|
||||
}
|
||||
|
||||
.v-input >>> .v-text-field__slot input {
|
||||
color: var(--v-txt-base) !important;
|
||||
}
|
||||
.v-input >>> .v-text-field__slot textarea {
|
||||
color: var(--v-txt-base) !important;
|
||||
}
|
||||
|
||||
.youtube >>> .v-input__icon--prepend-inner i {
|
||||
color: #e64e0f !important;
|
||||
font-size: 30px;
|
||||
}
|
||||
|
||||
.youtube >>> .v-text-field__slot {
|
||||
border-left: 1px solid var(--v-lines-base) !important;
|
||||
padding-left: 15px;
|
||||
}
|
||||
|
||||
.youtube >>> .v-input__icon--prepend-inner {
|
||||
margin: auto 14px auto 10px;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user