Merge pull request #119 from paoloar77/Newsletter_Page

Newsletter page
This commit is contained in:
Paolo Arena
2019-12-07 00:21:59 +01:00
committed by GitHub
102 changed files with 4149 additions and 2841 deletions

1811
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -29,6 +29,7 @@
"@babel/plugin-transform-runtime": "^7.4.0",
"@babel/runtime": "^7.0.0",
"@quasar/extras": "^1.3.2",
"@types/googlemaps": "^3.38.0",
"@types/vuelidate": "^0.7.0",
"@vue/eslint-config-standard": "^4.0.0",
"acorn": "^6.0.0",

View File

@@ -5,6 +5,8 @@ const helpers = require('./helpers');
const webpack = require('webpack')
const envparser = require('./config/envparser')
const PrerenderSPAPlugin = require('prerender-spa-plugin')
const Renderer = PrerenderSPAPlugin.PuppeteerRenderer
const extendTypescriptToWebpack = (config) => {
config.resolve
@@ -53,6 +55,30 @@ const extendHTMLToWebpack = (config) => {
.loader('vue-html-loader')
};
const extendPrerender = (config) => {
config
.plugin('prerender-spa-plugin')
.use(PrerenderSPAPlugin, [{
// Required - The path to the webpack-outputted app to prerender.
staticDir: path.join(__dirname, 'dist/spa'),
// Required - Routes to render.
routes: ['/'],
renderer: new Renderer({
injectProperty: '__PRERENDER_INJECTED',
inject: {
foo: 'bar'
},
// renderAfterDocumentEvent: 'custom-post-render-event',
renderAfterTime: 5000,
// maxConcurrentRoutes: 4,
// renderAfterElementExists: '#content',
headless: true,
})
}])
};
module.exports = function (ctx) {
return {
htmlVariables: {
@@ -109,6 +135,8 @@ module.exports = function (ctx) {
.rule('template-engine')
.test(/\.(gql|graphql)$/)
.loader('graphql-tag/loader') */
// extendPrerender(config);
}
},
dev: {

View File

@@ -1,4 +1,4 @@
import VeeValidate from "vee-validate";
import VeeValidate from 'vee-validate'
export default ({ Vue }) => {
Vue.use(VeeValidate, { inject: false })

View File

@@ -1 +1 @@
../../../freeplanet_serverside/server/tools/shared_nodejs.js
/home/paolo/myproject/freeplanet_serverside/src/server/tools/shared_nodejs.js

View File

@@ -27,7 +27,7 @@ export const shared_consts = {
},
fieldsUserToChange() {
return ['_id', 'username', 'email', 'cell', 'name', 'surname', 'perm', 'date_reg', 'verified_email', 'img', 'ipaddr', 'lasttimeonline', 'profile']
return ['_id', 'username', 'email', 'cell', 'name', 'surname', 'perm', 'date_reg', 'verified_email', 'img', 'ipaddr', 'lasttimeonline', 'profile', 'news_on']
}
}

View File

@@ -19,8 +19,16 @@
.tothebottomfixed {
position: fixed;
left: 0;
right: 0;
right: 60px;
bottom: 0;
height: -100%;
z-index: 1000;
}
.margin_buttons_cook {
margin: -8px -8px;
}
.margin_buttons_cook > * {
margin: 8px 8px !important;
}

View File

@@ -5,10 +5,12 @@
<q-banner class="bg-primary text-white" transition-show="jump-down">
{{$t('cookies')}}
<template v-slot:action>
<q-btn v-if="disableDecline === false" flat color="white" label="Declina"
@click="decline"></q-btn>
<q-btn flat color="white" label="INFO" type="a" :href="urlInfo" @click="clickInfo"></q-btn>
<q-btn flat color="white" label="OK" @click="accept"></q-btn>
<div class="row justify-center margin_buttons_cook q-gutter-lg text-center" >
<q-btn v-if="disableDecline === false" flat color="white" label="Declina"
@click="decline"></q-btn>
<q-btn flat color="white" label="INFO" type="a" :href="urlInfo" @click="clickInfo"></q-btn>
<q-btn flat color="white" label="OK" @click="accept"></q-btn>
</div>
</template>
</q-banner>
</transition>

View File

@@ -1,6 +1,6 @@
<template>
<q-card class="my-card text-center">
<q-img :src="myop.img" class="myimg">
<q-img :src="myop.img" class="myimg" :alt="`${myop.name} ${myop.surname}`">
<div class="absolute-bottom text-spacetrans text-shadow">
<div class="text-h6 text-trans">{{myop.name}}</div>
<div class="text-subtitle-carica text-trans">{{myop.qualification}}</div>
@@ -9,7 +9,7 @@
<q-tabs v-model="tab" class="text-teal">
<q-tab label="Info" name="one"></q-tab>
<q-tab label="Storia" name="two"></q-tab>
<q-tab label="Biografia" name="two"></q-tab>
</q-tabs>
<q-separator></q-separator>

View File

@@ -36,6 +36,7 @@ export default class CCard extends Vue {
name: '',
surname: '',
qualification: '',
usertelegram: '',
disciplines: '',
certifications: '',
img: '',

View File

@@ -9,7 +9,7 @@
<q-tabs v-model="tab" class="text-teal">
<q-tab label="Info" name="one"></q-tab>
<q-tab label="Storia" name="two"></q-tab>
<q-tab label="Biografia" name="two"></q-tab>
</q-tabs>
<q-separator></q-separator>
@@ -20,18 +20,29 @@
<div v-if="myop.certifications" class="text-subtitle-certificato">{{myop.certifications}}</div>
<div class="op__cell">
<q-icon class="flex-icon" name="mobile_friendly"></q-icon>
<span class="q-mx-sm">{{myop.cell}}</span>
<span class="q-ma-sm">{{myop.cell}}</span>
<q-btn fab-mini icon="fab fa-whatsapp"
color="green" type="a"
size="xs"
<div class="row justify-center margin_buttons q-gutter-lg">
<q-btn v-if="myop.email" fab-mini icon="fas fa-envelope"
color="blue-grey-6" type="a"
size="sm"
:href="tools.getemailto(myop.email)" target="__blank">
</q-btn>
<q-btn v-if="tools.getHttpForWhatsapp(myop.cell)" fab-mini icon="fab fa-whatsapp"
color="green" type="a"
size="sm"
:href="tools.getHttpForWhatsapp(myop.cell)" target="__blank">
</q-btn>
:href="tools.getHttpForWhatsapp(myop.cell)" target="__blank">
</q-btn>
<q-btn v-if="tools.getHttpForTelegram(myop.usertelegram)" fab-mini icon="fab fa-telegram"
color="blue" type="a"
size="sm"
:href="tools.getHttpForTelegram(myop.usertelegram)" target="__blank">
</q-btn>
</div>
</div>
<div class="op__email">
<q-icon class="flex-icon" name="contact_mail"> </q-icon>&nbsp;
<q-icon class="flex-icon" name="contact_mail"></q-icon>&nbsp;
<a :href="tools.getemailto(myop.email)" target="_blank">{{myop.email}}
</a>
</div>

View File

@@ -0,0 +1,12 @@
.landing__swirl-bg {
background-repeat: no-repeat !important;
background-position: top;
background-size: contain !important;
background-image: url(../../statics/images/landing_first_section.png) !important
}
.landing__features {
opacity: .9;
font-size: 1rem;
line-height: 1.5;
}

View File

@@ -0,0 +1,31 @@
import Vue from 'vue'
import { Component, Prop, Watch } from 'vue-property-decorator'
import { tools } from '../../store/Modules/tools'
import { toolsext } from '@src/store/Modules/toolsext'
import { GlobalStore } from '../../store'
import { CCardDiscipline } from '../CCardDiscipline'
import { ICategory } from '../../model'
import MixinBase from '../../mixins/mixin-base'
@Component({
name: 'CCardCarousel',
mixins: [MixinBase],
components: { CCardDiscipline }
})
export default class CCardCarousel extends Vue {
@Prop({ required: true }) public myarr: []
public slidedisc = 0
get autoplaydisc() {
return GlobalStore.state.autoplaydisc
}
set autoplaydisc(value) {
GlobalStore.state.autoplaydisc = value
}
}

View File

@@ -0,0 +1,92 @@
<template>
<div class="row items-center q-gutter-md ">
<div class="padding">
<div class="landing__features">
<q-list bordered class="q-ma-md">
<q-item>
<q-item-section>
<q-item-label overline class="text-subtitle3">Discipline Offerte:</q-item-label>
</q-item-section>
</q-item>
<div v-for="(disc, index) in myarr" :key="index">
<q-item clickable v-ripple
:to="disc.linkpage">
<q-item-section avatar v-if="tools.getimgev(disc)">
<q-avatar>
<img :src="tools.getimgev(disc)" :alt="disc.label">
</q-avatar>
</q-item-section>
<q-item-section>{{disc.label}}</q-item-section>
</q-item>
<q-separator/>
</div>
</q-list>
</div>
</div>
<q-carousel
swipeable
animated
:autoplay="autoplaydisc"
v-model="slidedisc"
thumbnails
infinite
ref="carousel"
transition-next="slide-left"
transition-prev="slide-right"
height="600px"
width="100%"
>
<template v-slot:control>
<q-carousel-control
position="top"
class="text-center"
style="padding: 4px 8px 4px 0; border-radius: 4px; font-weight: bold;"
>
<q-toggle dark color="white" v-model="autoplaydisc" label="Auto Play" class="shadow-8"
style="background-color: rgba(0,0,0, 0.2);"></q-toggle>
</q-carousel-control>
<q-carousel-control
position="top-left"
class="q-gutter-xs"
style="opacity: 0.7;"
>
<q-btn
push round color="white" text-color="black" icon="keyboard_arrow_left"
@click="$refs.carousel.previous()"></q-btn>
</q-carousel-control>
<q-carousel-control
position="top-right"
class="q-gutter-xs"
style="opacity: 0.7;"
>
<q-btn
push round color="white" text-color="black" icon="keyboard_arrow_right"
@click="$refs.carousel.next()"></q-btn>
</q-carousel-control>
</template>
<q-carousel-slide v-for="(myrec, index) in myarr" :key="index"
:img-src="`statics/`+myrec.img_small"
:alt="myrec.label"
:name="index">
<div class="row q-ma-xs">
<CCardDiscipline :discipline="myrec" mystyle="height: 500px" :autoplay.sync="autoplaydisc">
</CCardDiscipline>
</div>
<div class="absolute-bottom sfondo-grigio">
<span class="text-h6 text-grey-1 shadow-max alignleft">{{index + 1}}. </span>
</div>
</q-carousel-slide>
</q-carousel>
</div>
</template>
<script lang="ts" src="./CCardCarousel.ts">
</script>
<style lang="scss" scoped>
@import './CCardCarousel.scss';
</style>

View File

@@ -0,0 +1 @@
export {default as CCardCarousel} from './CCardCarousel.vue'

View File

@@ -0,0 +1,110 @@
$heightBtn: 100%;
$grayshadow: #555;
.text-subtitle-carica {
font-size: 1rem;
font-weight: 400;
line-height: 1.75rem;
letter-spacing: .00937em;
text-shadow: .1rem .1rem .1rem $grayshadow;
}
.text-subtitle-certificato {
font-size: 0.75rem;
line-height: 1rem;
}
@media (max-width: 718px) {
// PER VERSIONE MOBILE
.text-subtitle-carica {
font-size: 1rem;
}
}
.my-card-discipline {
width: 100%;
max-width: 350px;
min-width: 300px;
padding: 0;
box-shadow: none;
border-radius: 30px;
}
.my-card-shadow {
width: 100%;
max-width: 350px;
min-width: 300px;
padding-bottom: 20px;
margin-left: 0;
margin-right: 0;
margin-top: 1rem;
margin-bottom: 1rem;
border-radius: 30px;
transition: transform .2s ease-out;
}
.yes_shadow {
-webkit-box-shadow: 0 0 24px 0 rgba(0, 0, 0, 0.16);
box-shadow: 0 0 24px 0 rgba(0, 0, 0, 0.16);
}
.my-card-shadow:hover {
transition: transform .2s ease-in;
transform: scale(1.03);
}
.disc {
text-align: center !important;
font-size: 1rem;
font-weight: 400;
line-height: 1.75rem;
letter-spacing: .00937em;
text-shadow: .1rem .1rem .1rem $grayshadow;
&__title {
//color: white;
text-shadow: .125rem .125rem .125rem #2d2260;
}
&__cell {
font-size: 1rem;
color: red;
}
&__email {
font-size: 1rem;
color: #3b5998;
}
&__description {
font-size: 1rem;
color: #000000;
height: 150px;
overflow: hidden;
text-overflow: ellipsis;
}
&__email a {
text-decoration: none;
}
}
.myimg {
height: 200px;
border-radius: 30px !important;
}
.q-img {
&__image {
border-radius: 30px !important;
}
}
.q-card__section{
padding: 4px !important;
}

View File

@@ -0,0 +1,55 @@
import Vue from 'vue'
import { Component, Prop, Watch } from 'vue-property-decorator'
import { tools } from '../../store/Modules/tools'
import { toolsext } from '@src/store/Modules/toolsext'
import { IDiscipline, IEvents } from '../../model'
import MixinBase from '../../mixins/mixin-base'
import MixinOperator from '../../mixins/mixin-operator'
import MixinUsers from '../../mixins/mixin-users'
import { CMyTeacher } from '../CMyTeacher'
import { CalendarStore } from '../../store/Modules'
@Component({
mixins: [MixinBase, MixinOperator, MixinUsers],
name: 'CCardDiscipline',
components: { CMyTeacher }
})
export default class CCardDiscipline extends Vue {
@Prop({ required: true }) public discipline: IDiscipline
@Prop({ required: false, default: '' }) public mystyle: string
@Prop({ required: false, default: false }) public autoplay: boolean
public nextlesson: IEvents
@Watch('discipline')
public disciplinechanged(value) {
this.nextlesson = this.getNextLesson(value.typol_code)
// console.log('nextlesson', this.nextlesson)
}
public getNextLesson(typol) {
// Get next lesson
const datenow = tools.addDays(tools.getDateNow(), -1)
return CalendarStore.state.eventlist.find((myevent) => (myevent.typol === typol) && (new Date(myevent.dateTimeEnd) >= datenow))
// return CalendarStore.state.eventlist.find((myevent) => (myevent.typol === typol))
}
public ExistLesson() {
return !!this.nextlesson
}
public NextEventDate() {
return tools.getstrDateTimeEventSimple(this, this.nextlesson)
}
get getLinkEvent() {
return `event/${this.nextlesson.typol}/${this.nextlesson._id}`
}
public created() {
this.disciplinechanged(this.discipline)
}
}

View File

@@ -0,0 +1,48 @@
<template>
<div class="my-card-shadow yes_shadow" style="opacity: 1 !important;">
<q-card class="my-card-discipline text-center inset-shadow" :style="mystyle">
<q-img :src="`statics/` + discipline.img_small" class="myimg" :alt="discipline.label">
<div class="absolute-bottom text-spacetrans">
<q-btn rounded :to="discipline.linkpage">
<div class="text-h5 disc__title shadow-max">{{discipline.label}}</div>
</q-btn>
</div>
</q-img>
<q-card-section>
<div class="disc__description" v-html="discipline.description"></div>
</q-card-section>
<q-card-section v-if="ExistLesson()" class="text-blue">
<span v-if="!tools.isMobile()">{{ $t('cal.nextevent') }}:</span>
<q-btn rounded type="a" :to="getLinkEvent" color="primary" icon="event" :label="NextEventDate()">
</q-btn>
</q-card-section>
<span v-if="!tools.isMobile()"><q-separator inset></q-separator></span>
<q-card-section class="row justify-center">
<div v-for="(teach, index) in discipline.teachers" :key="index"
v-if="getImgTeacherByUsername(teach) && isValidUsername(teach)">
<CMyTeacher :username="teach">
</CMyTeacher>
</div>
</q-card-section>
<q-btn class="q-mb-md" rounded size="md" color="primary" :to="discipline.linkpage" :label="$t('cal.readall')"></q-btn>
<!--<q-card-section>-->
<!--<div class="text-subtitle3">{{myop.disciplines}}</div>-->
<!--{{myop.info}}-->
<!--</q-card-section>-->
</q-card>
</div>
</template>
<script lang="ts" src="./CCardDiscipline.ts">
</script>
<style lang="scss" scoped>
@import './CCardDiscipline.scss';
</style>

View File

@@ -0,0 +1 @@
export {default as CCardDiscipline} from './CCardDiscipline.vue'

View File

@@ -40,6 +40,10 @@ export default class CDateTime extends Vue {
// console.log('Opening', 'myvalue', this.myvalue, 'value', this.value)
this.saveit = false
this.valueprec = this.myvalue
if (this.myvalue === undefined) {
this.valueDate = new Date()
this.myvalue = tools.getstrYYMMDDDateTime(this.valueDate)
}
this.$emit('show')
}
@@ -55,7 +59,8 @@ export default class CDateTime extends Vue {
@Watch('valueDate')
public changevalueDate() {
this.myvalue = tools.getstrYYMMDDDateTime(this.valueDate)
if (this.valueDate)
this.myvalue = tools.getstrYYMMDDDateTime(this.valueDate)
// console.log('changevalueDate myvalue', this.myvalue)
}
@Watch('value')
@@ -67,7 +72,7 @@ export default class CDateTime extends Vue {
public savetoclose() {
this.saveit = true
this.showDateTimeScroller = false
this.$emit('savetoclose', this.myvalue, this.valueprec)
// this.$emit('savetoclose', this.myvalue, this.valueprec)
}
get scrollerPopupStyle280() {
@@ -95,7 +100,7 @@ export default class CDateTime extends Vue {
else
this.myvalue = tools.getstrYYMMDDDateTime(this.valueDate)
// console.log('myvalue', this.myvalue)
console.log('created myvalue', this.myvalue)
}
public changeval(newval) {

View File

@@ -39,21 +39,22 @@
<q-icon v-if="canEdit" name="event" class="cursor-pointer">
<q-popup-proxy v-model="showDateTimeScroller" @before-show="Opening" @before-hide="Closing">
<q-date-time-scroller
<q-scroller
v-model="myvalue"
view="date-time"
:locale="toolsext.getLocale()"
:hour24-format="true"
:rounded-borders="true"
border-color="#2196f3"
bar-color="#2196f3"
color="white"
background-color="primary"
inner-color="primary"
inner-background-color="white"
text-color="white"
color="primary"
minute-interval="5"
inner-text-color="primary"
inner-color="white"
:style="scrollerPopupStyle280"
@input="changeval"
@close="() => { savetoclose(); }"
/>
></q-scroller>
</q-popup-proxy>
</q-icon>

View File

@@ -10,6 +10,17 @@ $graytext: #555;
font-size: 12px;
}
.my-event-rel {
width: 100%;
font-size: 0.75rem;
line-height: 1.25rem;
text-align: center;
vertical-align: center;
margin-bottom: 5px;
cursor: pointer;
padding: 4px 2px 4px 2px !important;
}
.flex-container {
background-color: #ccc;
padding: 10px;
@@ -114,8 +125,7 @@ $graytext: #555;
letter-spacing: 0.03333em;
&__date {
font-weight: bold;
color: #2ba0fd;
color: #061220;
font-size: 1rem;
}
@@ -153,6 +163,9 @@ $graytext: #555;
border-radius: 1rem;
}
&__table tr:hover {
background-color: #deecef;
}
&__align_center_mobile {
text-align: left;
@@ -270,14 +283,14 @@ $graytext: #555;
.windowcol {
background-color: #ffffff;
// background: radial-gradient(circle, #ffffff 0%, #94dbfb 100%)
// background: radial-gradient(circle, #ffffff 0%, #94dbfb 100%)
}
.mysel{
.mysel {
color: white;
}
.myflex{
.myflex {
display: flex;
flex: 1;
@media (max-width: 400px) {

View File

@@ -1,5 +1,5 @@
import Vue from 'vue'
import { Component, Prop, Watch } from 'vue-property-decorator'
import { Component, Mixins, Prop, Watch } from 'vue-property-decorator'
import { CalendarStore, UserStore } from '@store'
import { Logo } from '../../components/logo/index'
@@ -17,8 +17,6 @@ import { CMySelect } from '../../components/CMySelect/index'
import { CMyEditor } from '../../components/CMyEditor/index'
import { stop, prevent, stopAndPrevent } from 'quasar/src/utils/event'
import QDateScroller from '@quasar/quasar-app-extension-qscroller/src/component/QDateScroller'
import QDateTimeScroller from '@quasar/quasar-app-extension-qscroller/src/component/QDateTimeScroller'
import { CTodo } from '@src/components/todos/CTodo'
import { SingleProject } from '@src/components/projects/SingleProject'
import { IEvents } from '@src/model'
@@ -31,23 +29,40 @@ import { lists } from '../../store/Modules/lists'
import { GlobalStore, MessageStore } from '../../store/Modules'
import { IMessagePage, IMessage, IIdentity, MsgDefault } from '../../model'
import MixinUsers from '../../mixins/mixin-users'
import { CDateTime } from '../CDateTime'
import MixinOperator from '../../mixins/mixin-operator'
import MixinEvents from '../../mixins/mixin-events'
import { CDateTime } from '../CDateTime'
import { CMyAvatar } from '../CMyAvatar'
import { CMySingleEvent } from '../CMySingleEvent'
import { CMyTeacher } from '../CMyTeacher'
@Component({
mixins: [MixinOperator, MixinUsers],
mixins: [MixinOperator, MixinUsers, MixinEvents],
name: 'CEventsCalendar',
components: { Logo, Footer, CTitle, CImgText, QDateTimeScroller, QDateScroller, CMySelect, CMyEditor, CDateTime, CMyAvatar }
components: {
Logo,
Footer,
CTitle,
CImgText,
CMySelect,
CMyEditor,
CDateTime,
CMyAvatar,
CMySingleEvent, CMyTeacher
}
})
export default class CEventsCalendar extends Vue {
export default class CEventsCalendar extends MixinEvents {
@Prop({ required: false, default: null }) public mysingleevent: IEvents
@Prop({ required: false, default: 0 }) public showfirstN: number
public $q
public $t: any
public calendarView = 'month'
public selectedDate = '2019-04-01'
public tabeditor: string = 'details'
public formDefault: IEvents = {
title: '',
details: '',
bodytext: '',
dateTimeStart: tools.getstrYYMMDDDateTime(tools.getDateNow()),
dateTimeEnd: tools.getstrYYMMDDDateTime(tools.getDateNow()),
icon: '',
@@ -189,6 +204,10 @@ export default class CEventsCalendar extends Vue {
// }
// ]
get visuAllCal() {
return this.mysingleevent === null
}
get title_cal() {
if (this.titleFormatter && this.locale) {
const mydate = new Date(this.selectedDate)
@@ -254,7 +273,9 @@ export default class CEventsCalendar extends Vue {
}
get dayHeight() {
if (Screen.height < 500)
if (Screen.height < 400)
return 80
else if (Screen.height < 500)
return 100
if (Screen.height < 700)
return 110
@@ -284,10 +305,6 @@ export default class CEventsCalendar extends Vue {
return (CalendarStore.state.intervalRange.max - CalendarStore.state.intervalRange.min) * (1 / CalendarStore.state.intervalRangeStep)
}
get editable() {
return CalendarStore.state.editable
}
get containerStyle() {
const styles = { height: '' }
if (this.calendarView !== 'month' || (this.calendarView === 'month' && CalendarStore.state.dayHeight === 0)) {
@@ -492,6 +509,13 @@ export default class CEventsCalendar extends Vue {
return (this.isAlreadyBooked(event) ? 'text-left bg-light-green-1' : 'text-left')
}
public checkFieldUndef() {
if (this.eventForm.bodytext === undefined)
this.eventForm.bodytext = ''
if (this.eventForm.details === undefined)
this.eventForm.details = ''
}
public editEvent(eventparam) {
console.log('editEvent - INIZIO')
this.resetForm()
@@ -500,6 +524,8 @@ export default class CEventsCalendar extends Vue {
this.eventForm = { ...eventparam }
this.checkFieldUndef()
this.eventForm.dateTimeStart = tools.getstrYYMMDDDateTime(eventparam.dateTimeStart)
this.eventForm.dateTimeEnd = tools.getstrYYMMDDDateTime(eventparam.dateTimeEnd)
@@ -510,14 +536,15 @@ export default class CEventsCalendar extends Vue {
tools.CancelEvent(this, eventparam)
}
public duplicateEvent(eventparam, numgg, numev: number = 1 ) {
public duplicateEvent(eventparam, numgg, numev: number = 1) {
for (let i = 0; i < numev; ++i) {
GlobalStore.actions.DuplicateRec({ table: tools.TABEVENTS, id: eventparam._id }).then((rec) => {
rec.dateTimeStart = tools.addDays(new Date(rec.dateTimeStart), numgg * (i + 1))
rec.dateTimeEnd = tools.addDays(new Date(rec.dateTimeEnd), numgg * (i + 1))
CalendarStore.state.eventlist.push(rec)
this.editEvent(rec)
if (rec) {
rec.dateTimeStart = tools.addDays(new Date(rec.dateTimeStart), numgg * (i + 1))
rec.dateTimeEnd = tools.addDays(new Date(rec.dateTimeEnd), numgg * (i + 1))
CalendarStore.state.eventlist.push(rec)
this.editEvent(rec)
}
})
}
// tools.ActionRecTable(this, lists.MenuAction.DUPLICATE_RECTABLE, tools.TABEVENTS, eventparam._id, eventparam, 'db.duplicatedrecord')
@@ -851,17 +878,6 @@ export default class CEventsCalendar extends Vue {
return await CalendarStore.actions.BookEvent(eventparam)
}
public isAlreadyBooked(eventparam: IEvents) {
return CalendarStore.getters.findEventBooked(eventparam, true)
}
public getImgEvent(event: IEvents) {
if (!!event.img)
return '../../statics/' + event.img
else
return '../../statics/images/noimg.png'
}
get getContribTypeArr() {
return CalendarStore.state.contribtype
}
@@ -874,13 +890,8 @@ export default class CEventsCalendar extends Vue {
return CalendarStore.state.wheres
}
public isShowPrice(event: IEvents) {
const rec = CalendarStore.getters.getContribtypeRec(event.contribtype)
return (rec) ? rec.showprice : true
}
public getContribtypeById(id) {
return CalendarStore.getters.getContribtypeById(id)
get getDisciplines() {
return GlobalStore.state.disciplines
}
public createContribType(value) {
@@ -897,26 +908,6 @@ export default class CEventsCalendar extends Vue {
return this.dateFormatter.format(mydate)
}
public getPrice(event: IEvents) {
let myprice = (event.price > 0) ? event.price + ' €' : ''
myprice = (event.price === -1) ? this.$t('event.askinfo') : myprice
if (event.infoafterprice)
myprice += ' ' + event.infoafterprice
return myprice
}
public getWhereIcon(where) {
const whererec = CalendarStore.getters.getWhereRec(where)
return (whererec) ? whererec.whereicon : ''
}
public getWhereName(where) {
const whererec = CalendarStore.getters.getWhereRec(where)
return (whererec) ? whererec.placename : ''
}
public badgeClasses(eventparam, type) {
const cssColor = tools.isCssColor(eventparam.bgcolor)
const isHeader = type === 'header'
@@ -929,7 +920,7 @@ export default class CEventsCalendar extends Vue {
}
public badgeStyles(eventparam, type, timeStartPos, timeDurationHeight) {
const s = { color: '', top: '', height: '' }
const s = { color: '', top: '', height: '', opacity: 1 }
if (tools.isCssColor(eventparam.bgcolor)) {
s['background-color'] = eventparam.bgcolor
@@ -941,6 +932,11 @@ export default class CEventsCalendar extends Vue {
if (timeDurationHeight) {
s.height = timeDurationHeight(this.func_tools.getMinutesDuration(eventparam.dateTimeStart, eventparam.dateTimeEnd)) + 'px'
}
if (!this.isEventEnabled(eventparam)) {
s.opacity = 0.5
}
s['align-items'] = 'flex-start'
return s
}
@@ -973,21 +969,11 @@ export default class CEventsCalendar extends Vue {
}
public getEventList() {
const eventsloc = []
const datenow = tools.addDays(tools.getDateNow(), -1)
for (let i = 0; i < CalendarStore.state.eventlist.length; ++i) {
// console.log(' ciclo i = ', i, CalendarStore.state.eventlist[i])
// const dateEvent = new Date(CalendarStore.state.eventlist[i].date + ' 00:00:00')
const dateEvent = new Date(CalendarStore.state.eventlist[i].dateTimeEnd)
if (dateEvent >= datenow) {
eventsloc.push(CalendarStore.state.eventlist[i])
}
}
return eventsloc
const mylist = CalendarStore.state.eventlist.filter((rec) => (new Date(rec.dateTimeEnd) >= tools.getDateNowEvent()))
if (this.showfirstN > 0)
return mylist.slice(0, this.showfirstN)
else
return mylist
}
public getEvents(dt) {
@@ -1039,10 +1025,8 @@ export default class CEventsCalendar extends Vue {
public getTitleEv(event: IEvents) {
return (!!event.short_tit) ? event.short_tit : event.title
}
public getStyleByEvent(event: IEvents) {
if (event === this.myevent) {
return 'border: inset; border-color: darkblue; border-width: 3px; padding: 5px !important; '
}
public getLongTitleEv(event: IEvents) {
return event.title
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,55 @@
import Vue from 'vue'
import { Component, Prop, Watch } from 'vue-property-decorator'
import { tools } from '@src/store/Modules/tools'
import { toolsext } from '@src/store/Modules/toolsext'
import { date } from 'quasar'
import { CalendarStore } from '../../store/Modules'
import MixinBase from '../../mixins/mixin-base'
import VueScrollReveal from 'vue-scroll-reveal'
import { CImgText } from '../CImgText'
Vue.use(VueScrollReveal, {
class: 'v-scroll-reveal', // A CSS class applied to elements with the v-scroll-reveal directive; useful for animation overrides.
duration: 1200,
scale: 0.95,
distance: '10px',
rotate: {
x: 0,
y: 0,
z: 0
}
// mobile: true
})
@Component({
name: 'CFacebookFrame',
components: { CImgText },
mixins: [MixinBase]
})
export default class CFacebookFrame extends Vue {
public $q
public $t
@Prop({ required: true }) public urlfbpage: string
@Prop({ required: true }) public title: string
@Prop({ required: true }) public fbimage: string
@Prop({ required: false, default: '' }) public myclass: string
public geturlfbpageEncoded() {
return encodeURIComponent(this.urlfbpage)
}
get mywidth() {
let myw = 340
if (tools.getwidth(this) < 400)
return myw
if ((tools.getwidth(this) > 400) && (tools.getwidth(this) < 1100))
return Math.round((tools.getwidth(this) / 3) - 30)
else
return myw
}
}

View File

@@ -0,0 +1,29 @@
<template>
<div v-if="urlfbpage && fbimage" :class="myclass">
<!--<div class="fb-page" :data-href="urlfbpage" data-tabs="timeline"-->
<!--data-width="" data-height="" data-small-header="false" data-adapt-container-width="true"-->
<!--data-hide-cover="false" data-show-facepile="true">-->
<!--<blockquote :cite="urlfbpage" class="fb-xfbml-parse-ignore"><a-->
<!--:href="urlfbpage">{{title}}</a>-->
<!--</blockquote>-->
<!--</div>-->
<a :href="urlfbpage" target="_blank">
<q-img :src="`statics/` + fbimage" class="imgautosize" alt="facebook page">
</q-img>
</a>
<!--
<iframe :src="`https://www.facebook.com/plugins/page.php?href=`+geturlfbpageEncoded()+`&tabs=timeline&width=`+mywidth+`&height=500&small_header=false&adapt_container_width=true&hide_cover=false&show_facepile=true&appId=164292303671962`"
width="340" height="500" style="border:none;overflow:hidden" scrolling="no" frameborder="0"
allowTransparency="true" allow="encrypted-media"></iframe>
-->
</div>
</template>
<script lang="ts" src="./CFacebookFrame.ts">
</script>
<style lang="scss" scoped>
@import './CFacebookFrame.scss';
</style>

View File

@@ -0,0 +1 @@
export {default as CFacebookFrame} from './CFacebookFrame.vue'

View File

@@ -0,0 +1,4 @@
#map {
height: 400px;
width: 90%;
}

View File

@@ -0,0 +1,28 @@
import Vue from 'vue'
import { Component, Prop, Watch } from 'vue-property-decorator'
import { toolsext } from '@src/store/Modules/toolsext'
@Component({
name: 'CGoogleMap'
})
export default class CGoogleMap extends Vue {
@Prop({ required: true, default: 'one' }) public tab
public map = null
public initMap() {
// this.map = new window.google.maps.Map(document.getElementById('map'), {
// center: { lat: -34.397, lng: 150.644 },
// zoom: 8
// })
}
public async mounted() {
// await this.$google()
// this.initMap()
}
}

View File

@@ -0,0 +1,12 @@
<template>
<q-page class="flex flex-center">
<div id="map"></div>
</q-page>
</template>
<script lang="ts" src="./CGoogleMap.ts">
</script>
<style lang="scss" scoped>
@import './CGoogleMap.scss';
</style>

View File

@@ -0,0 +1 @@
export {default as CGoogleMap} from './CGoogleMap.vue'

View File

@@ -12,13 +12,14 @@ import { lists } from '../../store/Modules/lists'
import { IParamsQuery } from '../../model/GlobalStore'
import { fieldsTable } from '../../store/Modules/fieldsTable'
import { CMyPopupEdit } from '../CMyPopupEdit'
import { CTitleBanner } from '../CTitleBanner'
@Component({
components: { CMyPopupEdit }
components: { CMyPopupEdit, CTitleBanner }
})
export default class CGridTableRec extends Vue {
@Prop({ required: false }) public prop_mytable: string
@Prop({ required: true }) public prop_mytitle: string
@Prop({ required: false }) public prop_mytable: string
@Prop({ required: false, default: null }) public prop_mycolumns: any[]
@Prop({ required: false, default: '' }) public prop_colkey: string
@Prop({ required: false, default: '' }) public nodataLabel: string
@@ -52,7 +53,7 @@ export default class CGridTableRec extends Vue {
public valPrec: string = ''
public separator: 'horizontal'
public filter = undefined
public myfilter = undefined
public rowsel: any
public dark: boolean = true
public canEdit: boolean = false
@@ -62,6 +63,11 @@ export default class CGridTableRec extends Vue {
public colVisib: any[] = []
public colExtra: any[] = []
public rowclicksel: any = null
public colclicksel: any = null
public selected: any = []
get lists() {
return lists
}
@@ -96,16 +102,36 @@ export default class CGridTableRec extends Vue {
}
public SaveValue(newVal, valinitial) {
console.log('SaveValue', newVal, 'rowsel', this.rowsel)
public SaveValdb(newVal, valinitial) {
// console.log('SaveValdb', newVal)
// console.log('SaveValue', newVal, 'rowsel', this.rowsel)
// Update value in table memory
if (this.colsel.subfield !== '') {
if (this.rowsel[this.colsel.field] === undefined)
this.rowsel[this.colsel.field] = {}
this.rowsel[this.colsel.field][this.colsel.subfield] = newVal
} else {
this.rowsel[this.colsel.field] = newVal
this.colsel = this.colclicksel
// console.log('this.colsel', this.colsel)
this.SaveValue(newVal, valinitial)
this.colsel = null
}
public showandsel(row, col, newval, valinitial) {
// console.log('showandsel', row, col, newval)
this.rowsel = row
this.colsel = col
this.idsel = row._id
this.SaveValue(newval, valinitial)
}
public SaveValue(newVal, valinitial) {
// console.log('SaveValue', newVal, 'rowsel', this.rowsel)
if (this.colsel) {
// Update value in table memory
if (this.colsel.subfield !== '') {
if (this.rowsel[this.colsel.field] === undefined)
this.rowsel[this.colsel.field] = {}
this.rowsel[this.colsel.field][this.colsel.subfield] = newVal
} else {
this.rowsel[this.colsel.field] = newVal
}
}
const mydata = {
@@ -140,7 +166,7 @@ export default class CGridTableRec extends Vue {
}
public updatedcol() {
console.log('updatedcol')
// console.log('updatedcol')
if (this.mycolumns) {
this.colVisib = []
this.colExtra = []
@@ -160,9 +186,9 @@ export default class CGridTableRec extends Vue {
}
public onRequest(props) {
console.log('onRequest', 'filter = ' , this.filter)
console.log('onRequest', 'myfilter = ', this.myfilter)
const { page, rowsPerPage, rowsNumber, sortBy, descending } = props.pagination
const filter = this.filter
const myfilter = this.myfilter
if (!this.mytable)
return
@@ -180,21 +206,27 @@ export default class CGridTableRec extends Vue {
const startRow = (page - 1) * rowsPerPage
const endRow = startRow + fetchCount
// fetch data from "server"
this.fetchFromServer(startRow, endRow, filter, sortBy, descending).then((ris) => {
console.log('startRow', startRow)
this.pagination.rowsNumber = this.getRowsNumberCount(filter)
this.serverData = []
// fetch data from "server"
this.fetchFromServer(startRow, endRow, myfilter, sortBy, descending).then((ris) => {
this.pagination.rowsNumber = this.getRowsNumberCount(myfilter)
// clear out existing data and add new
if (this.returnedData === []) {
this.serverData = []
} else {
if (this.serverData.length > 0)
this.serverData.splice(0, this.serverData.length, ...this.returnedData)
else
this.serverData = [...this.returnedData]
// if (this.serverData.length > 0)
// this.serverData.splice(0, this.serverData.length, ...this.returnedData)
// else
this.serverData = [...this.returnedData]
}
console.log('this.serverData', this.serverData)
// don't forget to update local pagination object
this.pagination.page = page
this.pagination.rowsPerPage = rowsPerPage
@@ -209,7 +241,7 @@ export default class CGridTableRec extends Vue {
// emulate ajax call
// SELECT * FROM ... WHERE...LIMIT...
public async fetchFromServer(startRow, endRow, filter, sortBy, descending) {
public async fetchFromServer(startRow, endRow, myfilter, sortBy, descending) {
let myobj = null
if (sortBy) {
@@ -224,7 +256,7 @@ export default class CGridTableRec extends Vue {
table: this.mytable,
startRow,
endRow,
filter,
filter: myfilter,
sortBy: myobj,
descending
}
@@ -241,15 +273,15 @@ export default class CGridTableRec extends Vue {
return true
// if (!filter) {
// if (!myfilter) {
// data = this.original.slice(startRow, startRow + count)
// }
// else {
// let found = 0
// for (let index = startRow, items = 0; index < this.original.length && items < count; ++index) {
// let row = this.original[index]
// // match filter?
// if (!row['name'].includes(filter)) {
// // match myfilter?
// if (!row['name'].includes(myfilter)) {
// // get a different row, until one is found
// continue
// }
@@ -279,14 +311,14 @@ export default class CGridTableRec extends Vue {
}
// emulate 'SELECT count(*) FROM ...WHERE...'
public getRowsNumberCount(filter) {
public getRowsNumberCount(myfilter) {
// if (!filter) {
// if (!myfilter) {
// return this.original.length
// }
// let count = 0
// this.original.forEach((treat) => {
// if (treat['name'].includes(filter)) {
// if (treat['name'].includes(myfilter)) {
// ++count
// }
// })
@@ -331,9 +363,11 @@ export default class CGridTableRec extends Vue {
public mounted() {
this.canEdit = tools.getCookie(tools.CAN_EDIT, this.canEdit) === 'true'
if (!!this.tablesList) {
this.canEdit = tools.getCookie(tools.CAN_EDIT, this.canEdit) === 'true'
this.tablesel = tools.getCookie('tablesel', this.tablesel)
}
this.tablesel = tools.getCookie('tablesel', this.tablesel)
if (this.tablesel === '') {
if (!!this.tablesList)
this.tablesel = this.tablesList[0].value
@@ -351,14 +385,18 @@ export default class CGridTableRec extends Vue {
console.log('refresh')
// console.log('this.search', this.search)
if (!!this.search && this.search !== '')
this.filter = this.search
this.myfilter = this.search
else
this.filter = undefined
this.myfilter = undefined
// console.log('this.filter', this.filter)
// console.log('this.myfilter', this.myfilter)
this.refresh_table()
}
public refresh_table() {
this.onRequest({
pagination: this.pagination,
pagination: this.pagination
})
}
@@ -370,8 +408,10 @@ export default class CGridTableRec extends Vue {
public ActionAfterYes(action, item, data) {
if (action === lists.MenuAction.DELETE_RECTABLE) {
if (this.serverData.length > 0)
if (this.serverData.length > 0) {
this.serverData.splice(this.serverData.indexOf(item), 1)
this.refresh_table()
}
} else if (action === lists.MenuAction.DUPLICATE_RECTABLE) {
// Add record duplicated
// this.serverData.push(data)
@@ -399,7 +439,9 @@ export default class CGridTableRec extends Vue {
if (this.tablesel === undefined || this.tablesel === '')
return
console.log('changeTable mysel=', mysel, 'tablesel', this.tablesel)
// console.log('changeTable mysel=', mysel, 'tablesel', this.tablesel)
// console.log('this.tablesList=')
// console.table(this.tablesList)
let mytab = null
if (this.tablesList) {
@@ -445,6 +487,11 @@ export default class CGridTableRec extends Vue {
const myselcol = tools.getCookie(this.mytable, '')
if (!!myselcol && myselcol.length > 0) {
this.colVisib = myselcol.split('|')
} else {
this.mycolumns.forEach((elem) => {
if (elem.field !== tools.NOFIELD)
this.colVisib.push(elem.field + elem.subfield)
})
}
}
@@ -467,4 +514,21 @@ export default class CGridTableRec extends Vue {
tools.setCookie(tools.CAN_EDIT, newval)
}
public clickrowcol(row, col) {
if (!this.canEdit) {
if (this.rowclicksel) {
this.rowclicksel = null
} else {
this.rowclicksel = row
this.colclicksel = col
}
}
}
public getclrow(myrow) {
if (this.rowclicksel === myrow)
return 'colsel'
else
return ''
}
}

View File

@@ -4,7 +4,7 @@
<q-table
:data="serverData"
:columns="mycolumns"
:filter="filter"
:filter="myfilter"
:pagination.sync="pagination"
:row-key="colkey"
:loading="loading"
@@ -35,7 +35,8 @@
<!--<p style="color:red"> Rows: {{ getrows }}</p>-->
<q-input v-model="search" filled dense type="search" debounce="500" hint="Search" v-on:keyup.enter="doSearch">
<q-input v-model="search" filled dense type="search" debounce="500" hint="Search"
v-on:keyup.enter="doSearch">
<template v-slot:after>
<q-btn v-if="mytable" label="" color="primary" @click="refresh" icon="search"></q-btn>
</template>
@@ -91,16 +92,20 @@
</template>
<q-tr v-if="mytable" slot="body" slot-scope="props" :props="props">
<q-td v-for="col in mycolumns" :key="col.name" :props="props" v-if="colVisib.includes(col.field + col.subfield)">
<CMyPopupEdit :canEdit="canEdit"
:col="col"
:row.sync="props.row"
:field="col.field"
:subfield="col.subfield"
@save="SaveValue"
@show="selItem(props.row, col)">
<q-td v-for="col in mycolumns" :key="col.name" :props="props"
v-if="colVisib.includes(col.field + col.subfield)" @click="clickrowcol(props.row, col)">
<div :class="getclrow(props.row)">
<CMyPopupEdit :canEdit="canEdit"
:col="col"
:row.sync="props.row"
:field="col.field"
:subfield="col.subfield"
@save="SaveValue"
@show="selItem(props.row, col)"
@showandsave="showandsel">
</CMyPopupEdit>
</CMyPopupEdit>
</div>
</q-td>
<q-td v-for="col in mycolumns" :key="col.name" :props="props" v-if="colExtra.includes(col.name)">
<div v-if="col.action && visCol(col)">
@@ -119,6 +124,38 @@
-->
<!---->
</q-table>
<div v-if="rowclicksel">
<CTitleBanner title="Record:"></CTitleBanner>
<div class="q-ma-xs q-pa-xs text-center rounded-borders q-list--bordered"
v-for="mycol in mycolumns" :key="mycol.name"
v-if="colVisib.includes(mycol.field + mycol.subfield)">
<div class="row items-center justify-center q-gutter-md q-ma-xs">
<div class="q-ma-xs">
<q-field rounded outlined bg-color="orange-3" dense>
<template v-slot:control>
<div class="self-center full-width no-outline" tabindex="0">{{mycol.label}}</div>
</template>
</q-field>
</div>
<div class="q-ma-sm q-pa-sm colmodif col-grow rounded-borders " style="border: 1px solid #bbb"
@click="colclicksel = mycol">
<CMyPopupEdit :canEdit="true"
:col="mycol"
:showall="true"
:row="rowclicksel"
:field="mycol.field"
:subfield="mycol.subfield"
@save="SaveValdb"
@show="selItem(rowclicksel, mycol)"
@showandsave="showandsel">
</CMyPopupEdit>
</div>
</div>
</div>
</div>
</div>
</template>
<script lang="ts" src="./CGridTableRec.ts">

View File

@@ -28,4 +28,6 @@ export default class CImgText extends Vue {
@Prop({ required: false, default: '' }) public src2: string
@Prop({ required: false, default: 'myclimg' }) public class1: string
@Prop({ required: false, default: '' }) public style1: string
@Prop({ required: false, default: 'image' }) public alt1: string
@Prop({ required: false, default: 'image' }) public alt2: string
}

View File

@@ -3,8 +3,8 @@
<section class="padding_testo bg-white text-grey-10 text-justify" > <!-- v-scroll-reveal.reset -->
<div class="row items-start q-col-gutter-xs imgtext">
<div class="imgtext__img">
<img v-if="src" :src="src" class="myclimg" :style="style1">
<img v-if="src2" :src="src2" class="myclimg" :style="style1">
<img v-if="src" :src="src" class="myclimg" :style="style1" :alt="alt1">
<img v-if="src2" :src="src2" class="myclimg" :style="style1" :alt="alt2">
<div class="section_text">
<slot></slot>
</div>

View File

@@ -41,4 +41,10 @@ export default class CImgTitle extends Vue {
return tools.getimgbysize(filefull.path, filefull.file)
}
get getaltimg() {
const filefull = tools.getimgFullpathbysize(this.src)
return tools.getaltimg(filefull.path, filefull.file, this.title)
}
}

View File

@@ -1,7 +1,7 @@
<template>
<div>
<q-parallax :src="getsrc" :height="tools.myheight_imgtitle(myheight, myheightmobile)">
<h2 class="text-white center_to_image title">{{title}}</h2>
<h1 class="text-white center_to_image title">{{title}}</h1>
<div v-if="legendinside" class="mylegendinside absolute-bottom custom-caption center_to_image" v-html="legendinside"></div>
</q-parallax>
<div v-if="legend" class="mylegend" v-html="legend"></div>

View File

@@ -4,7 +4,7 @@
</q-avatar>
<q-avatar v-if="myimgint" class="q-mb-sx center_img">
<img :src="myimgint" :font-size="size">
<img :src="myimgint" :font-size="size" alt="my avatar">
</q-avatar>
</div>
</template>

View File

@@ -12,6 +12,7 @@ export default class CMyChipList extends Vue {
public $t
@Prop({ required: true }) public options: []
@Prop({ required: true }) public value
@Prop({ required: true }) public type
@Prop({ required: true, default: '' }) public optlab
@Prop({ required: true, default: '' }) public optval
@Prop({ required: false, default: '' }) public myclass
@@ -35,21 +36,49 @@ export default class CMyChipList extends Vue {
// console.table(this.options)
this.options.forEach((rec, index) => {
if (tools.isBitActive(this.value, rec[this.optval])) {
const mydata = {
label: this.$t(rec[this.optlab]),
value: rec[this.optval],
valbool: tools.isBitActive(this.value, rec[this.optval]),
icon: '',
color: tools.getColorByIndexBest(index)
if (this.type === tools.FieldType.multiselect) {
if (this.value.includes(rec[this.optval])) {
const mydata = {
label: null,
value: rec[this.optval],
// myris = mylist.filter((myrec) => arrval.includes(myrec[key]))
valbool: true,
icon: '',
color: tools.getColorByIndexBest(index)
}
if (tools.isObject(this.optlab)) {
mydata.label = this.options.filter((myrec) => myrec[this.optval] === mydata.value).map(this.optlab)
if (mydata.label)
mydata.label = mydata.label[0]
} else {
mydata.label = rec[this.optlab]
}
if (this.opticon)
mydata.icon = rec[this.opticon]
if (this.optcolor)
mydata.color = rec[this.optcolor]
this.myarrvalues.push(mydata)
}
} else {
if (tools.isBitActive(this.value, rec[this.optval])) {
const mydata = {
label: this.$t(rec[this.optlab]),
value: rec[this.optval],
valbool: tools.isBitActive(this.value, rec[this.optval]),
icon: '',
color: tools.getColorByIndexBest(index)
}
if (this.opticon)
mydata.icon = rec[this.opticon]
if (this.optcolor)
mydata.color = rec[this.optcolor]
if (this.opticon)
mydata.icon = rec[this.opticon]
if (this.optcolor)
mydata.color = rec[this.optcolor]
this.myarrvalues.push(mydata)
this.myarrvalues.push(mydata)
}
}
})

View File

@@ -5,14 +5,17 @@ import { tools } from '../../store/Modules/tools'
import { toolsext } from '@src/store/Modules/toolsext'
import { QEditor } from 'quasar'
import { CTitleBanner } from '../CTitleBanner'
@Component({
name: 'CMyEditor'
name: 'CMyEditor',
components: { CTitleBanner }
})
export default class CMyEditor extends Vue {
public $q
public editor = null
@Prop({ required: false, default: '' }) public title
@Prop({ required: true }) public value
@Prop({ required: false, default: '' }) public myclass

View File

@@ -1,5 +1,6 @@
<template>
<div>
<CTitleBanner :title="title"></CTitleBanner>
<form
autocorrect="off"
autocapitalize="off"
@@ -19,9 +20,11 @@
toolbar-toggle-color="yellow-8"
toolbar-bg="primary"
:toolbar="toolbarcomp"
debounce="500"
:fonts="myfonts"
@input="changeval"
@paste.native="evt => pasteCapture(evt)"
@keyup.enter.stop
v-model="myvalue">
</q-editor>
</form>

View File

@@ -0,0 +1,17 @@
.colmodif {
cursor: pointer;
}
.colmodif:hover {
background-color: #a8f0ff;
cursor: pointer;
}
.colsel {
background-color: #81b8ff;
}
.cldisable{
color: gray !important;
}

View File

@@ -0,0 +1,101 @@
import { Component, Prop, Watch } from 'vue-property-decorator'
import { tools } from '../../store/Modules/tools'
import { toolsext } from '@src/store/Modules/toolsext'
import { QEditor } from 'quasar'
import { CMyEditor } from '../CMyEditor'
import MixinBase from '../../mixins/mixin-base'
import { fieldsTable } from '../../store/Modules/fieldsTable'
import { IColGridTable } from '../../model'
import { CMySelect } from '../CMySelect'
@Component({
name: 'CMyFieldDb',
components: { CMyEditor, CMySelect }
})
export default class CMyFieldDb extends MixinBase {
@Prop({ required: true }) public title
@Prop({ required: true }) public mykey: string
@Prop({ required: true }) public type: number
@Prop({ required: false, default: false }) public serv: boolean
@Prop({ required: false, default: false }) public disable: boolean
@Prop({ required: false, default: '' }) public jointable: string
public $t
public myvalue = ''
public col: IColGridTable = { name: 'test' }
public canEdit: boolean = true
public created() {
this.myvalue = this.getValDb(this.mykey, this.serv)
this.col.jointable = this.jointable
this.col.fieldtype = this.type
this.col.label = this.title
// console.log('created', this.myvalue)
}
public visuValByType(val) {
if (this.col.fieldtype === tools.FieldType.date) {
if (val === undefined) {
return '[]'
} else {
return tools.getstrDateTime(val)
}
} else if (this.col.fieldtype === tools.FieldType.boolean) {
return (val) ? this.$t('dialog.yes') : this.$t('dialog.no')
} else if (this.col.fieldtype === tools.FieldType.binary) {
if (val === undefined)
return '[---]'
else
return fieldsTable.getArrStrByValueBinary(this, this.col, val)
} else if (this.col.fieldtype === tools.FieldType.select) {
if (val === undefined)
return '[---]'
else
return fieldsTable.getValueByTable(this.col, val)
} else if (this.col.fieldtype === tools.FieldType.multiselect) {
if (val === undefined)
return '[---]'
else
return fieldsTable.getMultiValueByTable(this.col, val)
} else if (this.col.fieldtype === tools.FieldType.password) {
if (val === undefined)
return '[---]'
else
return '***************'
} else {
if (val === undefined)
return '-'
else if (val === '') {
return '-'
} else {
let mystr = tools.firstchars(val, 5000)
if (val) {
if (val.length > 5000)
mystr += '...'
} else {
return val
}
return mystr
}
}
}
get mycl() {
if (this.disable) {
return 'cldisable'
}
}
get myvalprinted() {
return this.visuValByType(this.myvalue)
}
public savefield(value, initialval) {
this.myvalue = value
this.setValDb(this.mykey, this.myvalue, this.type, this.serv)
}
}

View File

@@ -0,0 +1,147 @@
<template>
<div class="text-center">
<div class="row items-center justify-center q-gutter-md q-ma-xs">
<div class="q-ma-xs">
<q-field rounded outlined bg-color="orange-3" dense>
<template v-slot:control>
<div class="self-center full-width no-outline" tabindex="0">{{title}}</div>
</template>
</q-field>
</div>
<div class="q-ma-sm q-pa-sm colmodif col-grow rounded-borders " style="border: 1px solid #bbb">
<div v-if="type === tools.FieldType.date">
<CDateTime
:label="col.label"
class="cursor-pointer"
:value.sync="myvalue"
:readonly="false"
:dense="true"
:canEdit="canEdit"
>
</CDateTime>
</div>
<div v-else :class="mycl">
<div v-if="type === tools.FieldType.binary">
<CMyChipList
:type="tools.FieldType.binary"
:value="myvalue"
:options="db_fieldsTable.getTableJoinByName(col.jointable)"
:optval="db_fieldsTable.getKeyByTable(col.jointable)"
:optlab="db_fieldsTable.getLabelByTable(col.jointable)"
:opticon="db_fieldsTable.getIconByTable(col.jointable)"></CMyChipList>
</div>
<!-- Show Value -->
<div v-else-if="type === tools.FieldType.multiselect">
<CMyChipList
:type="tools.FieldType.multiselect"
:value="myvalue"
:options="db_fieldsTable.getTableJoinByName(col.jointable)"
:optval="db_fieldsTable.getKeyByTable(col.jointable)"
:optlab="db_fieldsTable.getLabelByTable(col.jointable)"
:opticon="db_fieldsTable.getIconByTable(col.jointable)"></CMyChipList>
</div>
<div v-else-if="type === tools.FieldType.html">
<div v-html="myvalprinted">
</div>
</div>
<div v-else-if="type === tools.FieldType.boolean">
<q-toggle dark color="green" v-model="myvalue" :label="col.title"
@input="savefield"></q-toggle>
</div>
<div v-else>
{{ myvalprinted }}
</div>
<q-popup-edit
v-if="canEdit && type !== tools.FieldType.boolean"
v-model="myvalue"
:disable="col.disable"
:title="col.title"
@save="savefield"
buttons
>
<div v-if="type === tools.FieldType.boolean">
<q-checkbox v-model="myvalue" :label="col.title">
</q-checkbox>
{{ visuValByType(myvalue) }}
</div>
<div v-else-if="type === tools.FieldType.string">
<q-input v-model="myvalue"
autogrow
@keyup.enter.stop
autofocus>
</q-input>
</div>
<div v-else-if="type === tools.FieldType.password">
<q-input v-model="myvalue"
type="password"
@keyup.enter.stop
autofocus>
</q-input>
</div>
<div v-else-if="type === tools.FieldType.number">
<q-input v-model="myvalue" type="number"
autofocus>
</q-input>
</div>
<div v-else-if="type === tools.FieldType.binary">
<CMyToggleList :label="col.title"
:options="db_fieldsTable.getTableJoinByName(col.jointable)"
:value.sync="myvalue"
:optval="db_fieldsTable.getKeyByTable(col.jointable)"
:optlab="db_fieldsTable.getLabelByTable(col.jointable)">
</CMyToggleList>
</div>
<div v-else-if="type === tools.FieldType.html">
<CMyEditor :value.sync="myvalue" :title="title" @keyup.enter.stop>
</CMyEditor>
</div>
<div v-else-if="type === tools.FieldType.select">
<CMySelect :label="col.title"
:value.sync="myvalue"
:optval="db_fieldsTable.getKeyByTable(col.jointable)"
:optlab="db_fieldsTable.getLabelByTable(col.jointable)"
:options="db_fieldsTable.getTableJoinByName(col.jointable)"
:useinput="false">
</CMySelect>
</div>
<div v-else-if="type === tools.FieldType.multiselect">
<q-select
v-model="myvalue"
rounded
outlined
multiple
dense
options-dense
:display-value="db_fieldsTable.getTitleByTable(col.jointable)"
emit-value
map-options
:options="db_fieldsTable.getTableJoinByName(col.jointable)"
:option-label="db_fieldsTable.getLabelByTable(col.jointable)"
:option-value="db_fieldsTable.getKeyByTable(col.jointable)"
style="min-width: 150px"
>
</q-select>
</div>
</q-popup-edit>
</div>
</div>
</div>
</div>
</template>
<script lang="ts" src="./CMyFieldDb.ts">
</script>
<style lang="scss" scoped>
@import './CMyFieldDb.scss';
</style>

View File

@@ -0,0 +1 @@
export {default as CMyFieldDb} from './CMyFieldDb.vue'

View File

@@ -10,45 +10,35 @@ import { toolsext } from '@src/store/Modules/toolsext'
import { Screen } from 'quasar'
import { CImgTitle } from '../../components/CImgTitle/index'
import { CTitle } from '../../components/CTitle/index'
// Vue.use(VueScrollReveal, {
// class: 'v-scroll-reveal', // A CSS class applied to elements with the v-scroll-reveal directive; useful for animation overrides.
// duration: 1200,
// scale: 0.95,
// distance: '10px',
// rotate: {
// x: 0,
// y: 0,
// z: 0
// }
// // mobile: true
// })
import MixinsMetaTags from '../../mixins/mixin-metatags'
@Component({
name: 'CMyPage',
mixins: [MixinsMetaTags],
components: { Footer, CImgTitle, CTitle }
})
export default class CMyPage extends Vue {
@Prop({ required: true, default: '' }) public title: string
@Prop({ required: true, default: '' }) public keywords: string
@Prop({ required: true, default: '' }) public description: string
@Prop({ required: false, default: '' }) public img: string
@Prop({ required: false, default: '' }) public imgbackground: string
@Prop({ required: false, default: '' }) public sizes: string
@Prop({ required: false, default: '' }) public styleadd: string
@Prop({ required: false, default: false }) public nofooter: boolean
public $t
public $q
public meta() {
return {
title: this.$t('msg.myAppName'),
titleTemplate: (title) => `${this.title} - ${this.$t('msg.myAppName')}`,
meta: {
keywords: { name: 'keywords', content: this.keywords },
description: { name: 'description', content: this.description },
equiv: { 'http-equiv': 'Content-Type', 'content': 'text/html; charset=UTF-8' }
}
}
}
// public metaInfo() {
// return {
// // title: this.$t('msg.myAppName'),
// title: 'PROVA TITOLOOOOOOO!!!!!!!!!!!!!!!!!!!!**************************',
// titleTemplate: (title) => `${this.title} - ${this.$t('msg.myAppName')}`,
// meta: {
// keywords: { name: 'keywords', content: this.keywords },
// description: { name: 'description', content: this.description },
// equiv: { 'http-equiv': 'Content-Type', 'content': 'text/html; charset=UTF-8' }
// }
// }
// }
public mounted() {
// console.log('CMYPage title=', this.title)

View File

@@ -1,13 +1,15 @@
<template>
<div>
<CTitle v-if="imgbackground" :imgbackground="imgbackground"
:headtitle="title" :sizes="sizes"></CTitle>
:headtitle="title" :sizes="sizes" :styleadd="styleadd"></CTitle>
<div v-if="!imgbackground">
<CImgTitle v-if="img" :src="img" :title="title">
</CImgTitle>
</div>
<slot></slot>
<Footer></Footer>
<div v-if="!nofooter">
<Footer></Footer>
</div>
</div>
</template>

View File

@@ -9,10 +9,11 @@ import { CMyChipList } from '../CMyChipList'
import { CDateTime } from '../CDateTime'
import { CMyToggleList } from '../CMyToggleList'
import { CMySelect } from '../CMySelect'
import { CMyEditor } from '../CMyEditor'
@Component({
name: 'CMyPopupEdit',
components: {CMyChipList, CDateTime, CMyToggleList, CMySelect}
components: {CMyChipList, CDateTime, CMyToggleList, CMySelect, CMyEditor}
})
export default class CMyPopupEdit extends Vue {
@@ -21,6 +22,7 @@ export default class CMyPopupEdit extends Vue {
@Prop({ required: false, default: false }) public canEdit
@Prop({ required: false, default: '' }) public field
@Prop({ required: false, default: '' }) public subfield
@Prop({ required: false, default: false }) public showall
public myvalue = ''
@@ -52,13 +54,13 @@ export default class CMyPopupEdit extends Vue {
}
public OpenEdit() {
console.log('OpenEdit')
// console.log('OpenEdit')
this.$emit('show')
}
public SaveValueInt(newVal, valinitial) {
console.log('SaveValueInt', newVal)
// console.log('SaveValueInt', newVal)
// Update value in table memory
if (this.subfield !== '') {
@@ -75,6 +77,13 @@ export default class CMyPopupEdit extends Vue {
this.$emit('save', newVal, valinitial)
}
public Savedb(newVal, valinitial) {
// console.log('Savedb', newVal)
this.$emit('showandsave', this.row, this.col, newVal, valinitial)
}
public visuValByType(val, col: IColGridTable, row) {
if (col === undefined || row === undefined)
return
@@ -107,13 +116,23 @@ export default class CMyPopupEdit extends Vue {
return '[---]'
else
return fieldsTable.getValueByTable(col, val)
} else if (col.fieldtype === tools.FieldType.multiselect) {
if (val === undefined)
return '[---]'
else
return fieldsTable.getMultiValueByTable(col, val)
} else {
if (val === undefined)
return '[]'
else if (val === '') {
return '[]'
} else {
let mystr = tools.firstchars(val, tools.MAX_CHARACTERS)
let mystr = ''
if (this.showall) {
return val
} else {
mystr = tools.firstchars(val, tools.MAX_CHARACTERS)
}
if (val) {
if (val.length > tools.MAX_CHARACTERS)
mystr += '...'
@@ -127,7 +146,7 @@ export default class CMyPopupEdit extends Vue {
public getclassCol(col) {
if (col) {
let mycl = (col.disable || !this.canEdit) ? '' : 'colmodif'
let mycl = (col.disable) ? '' : 'colmodif'
mycl += (col.fieldtype === tools.FieldType.date) ? ' coldate flex flex-container' : ''
return mycl
@@ -135,4 +154,8 @@ export default class CMyPopupEdit extends Vue {
return ''
}
}
public changeCol() {
}
}

View File

@@ -15,6 +15,7 @@
<div v-else>
<div v-if="col.fieldtype === tools.FieldType.binary">
<CMyChipList
:type="tools.FieldType.binary"
:value="myvalue"
:options="db_fieldsTable.getTableJoinByName(col.jointable)"
:optval="db_fieldsTable.getKeyByTable(col.jointable)"
@@ -22,6 +23,24 @@
:opticon="db_fieldsTable.getIconByTable(col.jointable)"></CMyChipList>
</div>
<!-- Show Value -->
<div v-else-if="col.fieldtype === tools.FieldType.multiselect">
<CMyChipList
:type="tools.FieldType.multiselect"
:value="myvalue"
:options="db_fieldsTable.getTableJoinByName(col.jointable)"
:optval="db_fieldsTable.getKeyByTable(col.jointable)"
:optlab="db_fieldsTable.getLabelByTable(col.jointable)"
:opticon="db_fieldsTable.getIconByTable(col.jointable)"></CMyChipList>
</div>
<div v-else-if="col.fieldtype === tools.FieldType.boolean">
<q-toggle dark color="green" v-model="myvalue" :label="col.title"
@input="Savedb"></q-toggle>
</div>
<div v-else-if="col.fieldtype === tools.FieldType.html">
<div v-html="visuValByType(myvalue, col, row)">
</div>
</div>
<div v-else>
{{ visuValByType(myvalue, col, row) }}
</div>
@@ -55,6 +74,15 @@
<div v-else-if="col.fieldtype === tools.FieldType.string">
<q-input v-model="myvalue"
autogrow
@keyup.enter.stop
autofocus>
</q-input>
</div>
<div v-else-if="col.fieldtype === tools.FieldType.password">
<q-input v-model="myvalue"
type="password"
@keyup.enter.stop
autofocus>
</q-input>
@@ -74,10 +102,13 @@
</CMyToggleList>
</div>
<div v-else-if="col.fieldtype === tools.FieldType.html">
<q-input v-model="myvalue"
autofocus
@keyup.enter.stop
type="textarea"></q-input>
<CMyEditor :value.sync="myvalue" :title="col.title" @keyup.enter.stop>
</CMyEditor>
<!--<q-input v-model="myvalue"-->
<!--autofocus-->
<!--@keyup.enter.stop-->
<!--type="textarea"></q-input>-->
</div>
<div v-else-if="col.fieldtype === tools.FieldType.select">
<CMySelect :label="col.title"
@@ -88,6 +119,25 @@
:useinput="false">
</CMySelect>
</div>
<div v-else-if="col.fieldtype === tools.FieldType.multiselect">
<q-select
v-model="myvalue"
rounded
outlined
multiple
dense
options-dense
:display-value="db_fieldsTable.getTitleByTable(col.jointable)"
emit-value
map-options
:options="db_fieldsTable.getTableJoinByName(col.jointable)"
:option-label="db_fieldsTable.getLabelByTable(col.jointable)"
:option-value="db_fieldsTable.getKeyByTable(col.jointable)"
style="min-width: 150px"
@input="changeCol">
</q-select>
</div>
</q-popup-edit>
</div>

View File

@@ -1,5 +1,5 @@
<template>
<div>
<div class="text-center">
<div v-if="useinput">
<q-select
rounded
@@ -33,6 +33,7 @@
:label="label"
emit-value
map-options
input-class="text-center"
style="min-width: 170px; max-width: 400px;"
>

View File

@@ -0,0 +1,168 @@
$graytext: #555;
.listaev {
color: black;
font-size: 0.75rem;
font-weight: 400;
line-height: 1.25rem;
letter-spacing: 0.03333em;
&__date {
color: #061220;
font-size: 1rem;
}
&__title {
color: red;
font-weight: 700;
letter-spacing: 0.066em;
}
&__details {
color: black;
}
&__tdimg {
width: 150px;
height: 150px;
}
&__tdimg_small {
width: auto;
height: 50px !important;
@media (max-width: 800px) {
height: 40px !important;
}
}
&__table {
margin: 10px;
border: solid 1px #4198ef;
border-radius: 1rem;
padding: 2px;
}
&__table tr {
border: solid 1px #4198ef;
border-radius: 1rem;
}
&__align_center_mobile {
text-align: center;
display: flex;
flex-direction: column;
align-items: center;
}
&__align_chips {
text-align: center;
display: flex;
flex-direction: column-reverse;
align-items: center;
}
&__img {
padding: 0.25rem !important;
float: left;
width: 150px;
height: 150px;
border-radius: 1rem;
@media (max-width: 718px) {
// PER VERSIONE MOBILE
float: none;
text-align: center;
margin: 0 auto;
}
}
&__img:hover {
transition: transform .2s;
transform: scale(1.05);
border: inset;
border-color: blue;
border-width: 1px;
}
}
.cal {
color: black;
font-size: 0.75rem;
font-weight: 400;
line-height: 1.25rem;
letter-spacing: 0.03333em;
&__title {
color: white;
font-weight: 700;
font-size: 1rem;
padding-bottom: 10px;
}
&__details {
color: black;
}
&__hours {
color: blue;
&-title {
color: $graytext;
}
&-content {
font-weight: 400;
}
}
&__where {
margin-top: 5px;
color: blue;
&-title {
color: $graytext;
}
&-content {
color: darkblue;
}
}
&__when {
margin-top: 5px;
color: blue;
&-title {
color: $graytext;
}
&-content {
color: darkblue;
}
}
&__teacher {
margin-top: 5px;
&-title {
color: $graytext;
}
&-content {
color: darkblue;
}
}
&__quota {
margin-top: 5px;
&-title {
color: $graytext;
}
&-content {
}
}
&__img {
width: 100px;
height: 100px;
padding: 10px;
}
}

View File

@@ -0,0 +1,77 @@
import Vue from 'vue'
import { Component, Prop, Watch } from 'vue-property-decorator'
import { CalendarStore, GlobalStore, UserStore } from '@store'
import { Logo } from '../../components/logo/index'
import { Footer } from '../../components/Footer/index'
import { tools } from '../../store/Modules/tools'
import { toolsext } from '@src/store/Modules/toolsext'
import { static_data } from '@src/db/static_data'
import { Screen } from 'quasar'
import { CImgText } from '../../components/CImgText/index'
import { CCard, CMyAvatar, CMyTeacher, CMyPage } from '@components'
import MixinOperator from '@src/mixins/mixin-operator'
import MixinEvents from '../../mixins/mixin-events'
import { IEvents } from '@src/model'
import MixinBase from '@src/mixins/mixin-base'
import MixinUsers from '@src/mixins/mixin-users'
@Component({
name: 'CMySingleEvent',
mixins: [MixinOperator, MixinBase, MixinEvents, MixinUsers],
components: { Logo, Footer, CImgText, CCard, CMyPage, CMyAvatar, CMyTeacher }
})
export default class CMySingleEvent extends MixinEvents {
@Prop({ required: true }) public myevent: IEvents
public $q
public $t
public selected: boolean = false
public selectEvent(eventparam: IEvents) {
this.selected = !this.selected
}
public getTextEvent(myevent: IEvents) {
if (myevent.bodytext === '') {
return myevent.details
} else {
return myevent.bodytext
}
}
public mounted() {
// console.log('MYSINGLEEVENT: myevent', this.myevent)
}
get static_data() {
return static_data
}
public duplicateEvent(event, numgg) {
this.$emit('duplicateEvent', event, numgg)
}
public askForInfoEventMenu(event) {
this.$emit('askForInfoEventMenu', event)
}
public deleteEvent(event) {
this.$emit('deleteEvent', event)
}
public editEvent(event) {
this.$emit('editEvent', event)
}
public addBookEventMenu(event) {
this.$emit('addBookEventMenu', event)
}
public EditBookEvent(event) {
this.$emit('EditBookEvent', event)
}
}

View File

@@ -0,0 +1,173 @@
<template>
<div>
<CMyPage v-if="myevent" :imgbackground="myevent.img" :title="myevent.title" keywords="" description="" nofooter="true">
<div class="q-mx-md">
<div class="listaev__align_chips q-ma-md">
<img :src="getImgEvent(myevent)"
@click="selectEvent(myevent)"
class="text-left padding_cell listaev__tdimg listaev__img cursor-pointer"
:style="getStyleByEvent(myevent, true)"
:alt="myevent.title">
<q-chip dense v-if="isAlreadyBooked(myevent)" class="cltexth4 chipbooked shadow-5 q-mb-md"
color="green" text-color="white"
icon="event_available">{{$t('cal.booked')}}
</q-chip>
<div v-if="selected">
<q-chip v-if="editable" class="text-center shadow-5 glossy bg-blue chipmodif">
<q-btn v-if="editable" flat round color="white" icon="fas fa-copy">
<q-menu
transition-show="flip-right"
transition-hide="flip-left">
<q-list style="min-width: 100px">
<q-item clickable @click="duplicateEvent(myevent, 7)">
<q-item-section>Tra 1 Settimana</q-item-section>
</q-item>
<q-item clickable @click="duplicateEvent(myevent, 14)">
<q-item-section>Tra 2 Settimane</q-item-section>
</q-item>
<q-item clickable @click="duplicateEvent(myevent, 7, 4)">
<q-item-section>4 Eventi ogni Settimana</q-item-section>
</q-item>
</q-list>
</q-menu>
</q-btn>
<q-btn v-if="editable" flat round color="white" icon="delete" v-close-popup
@click="deleteEvent(myevent)"></q-btn>
<q-btn v-if="editable" flat round color="white" icon="edit" v-close-popup
@click="editEvent(myevent)"></q-btn>
<q-btn v-if="editable" flat round color="white" icon="cancel"
@click="selectEvent(null)"></q-btn>
</q-chip>
</div>
<q-chip v-if="myevent.news" class="cltexth4 chipnews shadow-5 glossy text-right" color="red"
text-color="white" icon-right="star" icon="star" dense
style="">
{{$t('event.news')}}
</q-chip>
</div>
<div class="listaev__date listaev__align_center_mobile">
<span v-html="tools.getstrDateTimeEvent(mythis(), myevent, true)"></span>
</div>
<div class="listaev__align_center_mobile">
<div style="margin: 10px;"></div>
<div class="">
<!-- Se c'è un link, allora -->
<q-btn v-if="myevent.linkpdf" size="md" type="a"
:href="`../../statics/` + myevent.linkpdf"
target="_blank"
ripple rounded :label="myevent.title" :icon="myevent.icon"
:color="myevent.bgcolor" text-color="white" glossy>
</q-btn>
<!-- altrimenti mostra solo Chip -->
<div v-else>
<div v-if="tools.isMobile()" class="cltexth3 text-center"
:style="`background-color: ${myevent.bgcolor} !important; color: white !important;`">
{{myevent.title}}
</div>
<q-chip v-else class="cltexth3 text-center"
:style="`background-color: ${myevent.bgcolor} !important; color: white !important;`"
text-color="white"
:icon="myevent.icon"
dense>{{myevent.title}}
</q-chip>
</div>
</div>
<div style="margin: 10px;"></div>
<p v-if="myevent.bodytext" class="listaev__details text-left q-mb-md" v-html="myevent.bodytext"></p>
<p v-else class="listaev__details" v-html="myevent.details"></p>
<div v-if="myevent.teacher" class="">
<span class="cal__teacher-title">{{$t('cal.teacher')}}: <span
class="margin_with"></span></span>
<CMyTeacher :username="myevent.teacher"></CMyTeacher>
<CMyTeacher :username="myevent.teacher2"></CMyTeacher>
<span v-if="myevent.wherecode" class="q-ma-md">
<span v-if="tools.isMobile()"><br/></span>
<span class="cal__where-title">{{$t('cal.where')}}: </span>
<q-chip>
<q-avatar v-if="getWhereIcon(myevent.wherecode)">
<img :src="`../../statics/images/avatar/` + getWhereIcon(myevent.wherecode)" alt="località">
</q-avatar>
<q-avatar v-else color="blue" font-size="20px" text-color="white"
icon="home">
</q-avatar>
<span class="cal__teacher-content">{{getWhereName(myevent.wherecode)}}</span>
</q-chip>
</span>
</div>
<div v-if="myevent.contribtype" class="q-ma-sm">
<span class="cal__quota-title">{{$t('event.price')}}:<span
class="margin_with"></span></span>
<span v-if="!isShowPrice(myevent)" class="">
<q-chip class="glossy" color="orange" text-color="white">
<span class="cal__quota-content">{{getContribtypeById(myevent.contribtype)}}</span>
</q-chip>
</span>
<q-chip v-if="myevent.price && isShowPrice(myevent)" class="glossy" color="orange"
text-color="white" icon-right="star">
<span class="cal__quota-content">{{getPrice(myevent)}}</span>
</q-chip>
</div>
<div class="row justify-start q-ma-md">
<q-btn v-if="myevent.linkpdf"
size="md" type="a" :href="`../../statics/` + myevent.linkpdf"
target="_blank" rounded outline
color="primary" icon="info"
:label="$t('cal.showpdf')">
</q-btn>
<q-btn v-if="myevent.bodytext" rounded outline class="q-mx-sm"
color="primary"
:to="`/event/${myevent.typol}/${myevent._id}`"
:label="$t('event.showpage')">
</q-btn>
</div>
<div class="row justify-end q-mb-lg">
<q-btn rounded outline class="q-mx-sm"
color="primary" @click="askForInfoEventMenu(myevent)"
:label="$t('event.askinfo')">
</q-btn>
<q-btn rounded class="q-mx-sm"
v-if="!myevent.nobookable && !isAlreadyBooked(myevent) && static_data.functionality.BOOKING_EVENTS"
color="primary" @click="addBookEventMenu(myevent)"
:label="$t('cal.booking')" :disable="!isEventEnabled(myevent)">
</q-btn>
<q-btn rounded outline class="q-mx-sm"
v-if="!myevent.nobookable && isAlreadyBooked(myevent) && static_data.functionality.BOOKING_EVENTS"
text-color="red"
@click="EditBookEvent(myevent)"
:label="$t('cal.modifybooking')">
</q-btn>
<!--
<q-btn push rounded v-if="!myevent.nobookable && isAlreadyBooked(myevent)" color="positive" @click="BookEvent(myevent)"
:label="$t('cal.booked')">
</q-btn>
-->
</div>
</div>
</div>
</CMyPage>
</div>
</template>
<script lang="ts" src="./CMySingleEvent.ts">
</script>
<style lang="scss" scoped>
@import './CMySingleEvent.scss';
</style>

View File

@@ -0,0 +1 @@
export {default as CMySingleEvent} from './CMySingleEvent.vue'

View File

@@ -0,0 +1,92 @@
$heightBtn: 100%;
$grayshadow: #555;
.text-subtitle-carica {
font-size: 1rem;
font-weight: 400;
line-height: 1.75rem;
letter-spacing: .00937em;
text-shadow: .1rem .1rem .1rem $grayshadow;
}
.text-subtitle-certificato {
font-size: 0.75rem;
line-height: 1rem;
}
@media (max-width: 718px) {
// PER VERSIONE MOBILE
.text-subtitle-carica {
font-size: 1rem;
}
}
.op {
text-align: center !important;
font-size: 1rem;
font-weight: 400;
line-height: 1.75rem;
letter-spacing: .00937em;
text-shadow: .1rem .1rem .1rem $grayshadow;
&__cell {
font-size: 1rem;
color: red;
}
&__email {
font-size: 1rem;
color: #3b5998;
}
&__email a {
text-decoration: none;
}
&__facebook a {
font-size: 1rem;
text-decoration: none;
}
&__storia {
margin-top: 1rem;
margin-bottom: 1rem;
text-align: justify;
}
}
.myimg {
border-radius: 300px !important;
}
.q-img {
&__image {
border-radius: 300px !important;
}
}
.myflex {
display: flex;
flex: 1;
}
.mybase {
color: black;
font-size: 0.75rem;
font-weight: 400;
line-height: 1.25rem;
letter-spacing: 0.03333em;
&__teacher {
margin-top: 5px;
&-content {
color: darkblue;
}
&-content:hover {
}
}
}

View File

@@ -0,0 +1,43 @@
import Vue from 'vue'
import { Component, Prop, Watch } from 'vue-property-decorator'
import { tools } from '../../store/Modules/tools'
import { GlobalStore, UserStore } from '../../store/Modules'
import { CMyAvatar } from '../CMyAvatar'
import MixinBase from '../../mixins/mixin-base'
import MixinOperator from '../../mixins/mixin-operator'
import MixinUsers from '../../mixins/mixin-users'
@Component({
name: 'CMyTeacher',
mixins: [MixinBase, MixinOperator, MixinUsers],
components: { CMyAvatar }
})
export default class CMyTeacher extends MixinOperator {
@Prop({ required: true, default: '' }) public username
public showuserdetails = false
public autoplaydiscsaved: number
public tab: string = 'one'
@Watch('showuserdetails')
public changeshowuserdetails() {
if (!this.showuserdetails) {
GlobalStore.state.autoplaydisc = this.autoplaydiscsaved
}
}
public executeclick(event) {
console.log('executeclick')
this.showuserdetails = true
this.autoplaydiscsaved = GlobalStore.state.autoplaydisc
GlobalStore.state.autoplaydisc = 0
}
get myop() {
return this.getOperatorByUsername(this.username)
}
}

View File

@@ -0,0 +1,85 @@
<template>
<span>
<q-dialog v-model="showuserdetails" v-if="myop">
<q-card :style="`min-width: `+ tools.myheight_dialog() + `px;`">
<q-toolbar class="bg-primary text-white">
<q-toolbar-title>
{{myop.name}} {{myop.surname}}
</q-toolbar-title>
<q-btn flat round color="white" icon="close" v-close-popup></q-btn>
</q-toolbar>
<q-card-section class="text-center inset-shadow">
<div style="width: 200px; float: left;">
<q-img :src="`statics/images/` + myop.img" class="myimg" :alt="`${myop.name} ${myop.surname}`">
</q-img>
</div>
<div class="text-h6 text-trans">{{myop.name}} {{myop.surname}}</div>
<div class="text-subtitle-carica text-trans">{{myop.qualification}}</div>
<div class="text-subtitle-carica">{{myop.disciplines}}</div>
<div v-if="myop.certifications" class="text-subtitle-certificato">{{myop.certifications}}</div>
<div class="op__cell">
<q-icon class="flex-icon" name="mobile_friendly" v-if="myop.cell"></q-icon>
<span class="q-mx-sm">{{myop.cell}}</span>
<div class="row justify-center margin_buttons">
<q-btn v-if="myop.email" fab-mini icon="fas fa-envelope"
color="blue-grey-6" type="a"
size="sm"
:href="tools.getemailto(myop.email)" target="__blank">
</q-btn>
<q-btn v-if="tools.getHttpForWhatsapp(myop.cell)" fab-mini icon="fab fa-whatsapp"
color="green" type="a"
size="sm"
:href="tools.getHttpForWhatsapp(myop.cell)" target="__blank">
</q-btn>
<q-btn v-if="tools.getHttpForTelegram(myop.usertelegram)" fab-mini icon="fab fa-telegram"
color="blue" type="a"
size="sm"
:href="tools.getHttpForTelegram(myop.usertelegram)" target="__blank">
</q-btn>
</div>
</div>
<div class="op__email">
<q-icon class="flex-icon" name="contact_mail"></q-icon>&nbsp;
<a :href="tools.getemailto(myop.email)" target="_blank">{{myop.email}}
</a>
</div>
<div class="op__facebook" v-if="myop.paginafb">
<a :href="myop.paginafb" target="_blank">
<i aria-hidden="true" class="q-icon fab fa-facebook-f icon_contact links"></i> Pagina
Facebook
</a>
</div>
<br>
<div class="op__storia" v-html="myop.info"></div>
<!--<q-card-section>-->
<!--<div class="text-subtitle3">{{myop.disciplines}}</div>-->
<!--{{myop.info}}-->
<!--</q-card-section>-->
</q-card-section>
<q-card-actions align="center">
<q-btn rounded dense :label="$t('dialog.close')" color="primary" v-close-popup></q-btn>
</q-card-actions>
</q-card>
</q-dialog>
<q-chip clickable
v-if="getImgTeacherByUsername(username) && isValidUsername(username)" @click="executeclick"
class="mybase__teacher-content">
<CMyAvatar :myimg="getImgTeacherByUsername(username)"></CMyAvatar>
<span>{{getTeacherByUsername(username)}}</span>
</q-chip>
</span>
</template>
<script lang="ts" src="./CMyTeacher.ts">
</script>
<style lang="scss" scoped>
@import './CMyTeacher.scss';
</style>

View File

@@ -0,0 +1 @@
export {default as CMyTeacher} from './CMyTeacher.vue'

View File

@@ -0,0 +1,4 @@
#map {
height: 400px;
width: 90%;
}

View File

@@ -0,0 +1,26 @@
import Vue from 'vue'
import { Component, Prop, Watch } from 'vue-property-decorator'
import { toolsext } from '@src/store/Modules/toolsext'
import { tools } from '../../store/Modules/tools'
@Component({
name: 'COpenStreetMap'
})
export default class COpenStreetMap extends Vue {
@Prop({required: true}) public title: string
@Prop({required: false, default: ''}) public coordinates: string
@Prop({required: false, default: '' }) public coord_big: string
@Prop({required: false, default: ''}) public urlmap: string
@Prop({required: false, default: ''}) public imgmap: string
get mywidth() {
return tools.getwidth(this) - 20
}
get myheight() {
return 450
}
}

View File

@@ -0,0 +1,34 @@
<template>
<div v-if="coordinates" class="flex flex-center column justify-center">
<div class="">
<span class="text-subtitle2" v-html="title"></span> - (<a
:href="`https://www.openstreetmap.org/?` + coord_big + `&layers=N`"
target="_blank">{{$t('showbigmap')}}</a>)
</div>
<div>
<iframe :width="mywidth" :height="myheight" frameborder="0" scrolling="no" marginheight="0" marginwidth="0"
:src="`https://www.openstreetmap.org/export/embed.html?bbox=` + coordinates"
style="border: 1px solid black"></iframe>
</div>
</div>
<div v-else>
<div class="q-my-md">
<p class="text-subtitle2 text-center">
<span v-html="title"></span>
- <a href="urlmap" target="_blank" class="text-black">Apri Mappa</a>
</p>
<a :href="urlmap" target="_blank">
<q-img :src="`statics/` + imgmap" class="imgautosize" alt="my map">
</q-img>
</a>
</div>
</div>
</template>
<script lang="ts" src="./COpenStreetMap.ts">
</script>
<style lang="scss" scoped>
@import './COpenStreetMap.scss';
</style>

View File

@@ -0,0 +1 @@
export {default as COpenStreetMap} from './COpenStreetMap.vue'

View File

@@ -26,4 +26,8 @@ export default class CPreloadImages extends Vue {
}
}
public getaltimg(recimg: IPreloadImages) {
return recimg.alt
}
}

View File

@@ -1,7 +1,7 @@
<template>
<div id="preloader">
<div v-for="(image, index) in arrimg">
<img :src="getimg(image)" width="1" height="1"/>
<img :src="getimg(image)" width="1" height="1" :alt="getaltimg(image)"/>
</div>
</div>
</template>

View File

@@ -10,10 +10,11 @@ import { Screen } from 'quasar'
name: 'CTitle'
})
export default class CTitle extends Vue {
@Prop({ required: true }) public headtitle: string
@Prop({ required: false, default: '' }) public imgbackground: string
@Prop({ required: false, default: '' }) public imghead: string
@Prop({ required: false, default: '' }) public sizes: string
@Prop({ required: true }) public headtitle: string
@Prop({ required: false, default: '' }) public styleadd: string
get tools() {
return tools
@@ -26,4 +27,9 @@ export default class CTitle extends Vue {
return tools.getimgbysize(filefull.path, filefull.file)
}
get getaltimg() {
const filefull = tools.getimgFullpathbysize(this.imgbackground)
return tools.getaltimg(filefull.path, filefull.file, this.headtitle)
}
}

View File

@@ -1,10 +1,10 @@
<template>
<div>
<q-img v-if="imgbackground" :src="getsrc"
<q-img v-if="imgbackground" :src="getsrc" :alt="getaltimg"
:style="tools.styles_imgtitle(sizes)">
<div class="absolute-bottom text-body1 text-center">
<h2 class="titletext">{{headtitle}}</h2>
<div class="absolute-bottom text-body1 text-center" :style="styleadd">
<h1 class="titletext">{{headtitle}}</h1>
</div>
</q-img>

View File

@@ -0,0 +1,31 @@
import Vue from 'vue'
import { Component, Prop } from 'vue-property-decorator'
import { GlobalStore, UserStore } from '@store'
import VueScrollReveal from 'vue-scroll-reveal'
import { tools } from '@src/store/Modules/tools'
import { toolsext } from '@src/store/Modules/toolsext'
import { Screen } from 'quasar'
// Vue.use(VueScrollReveal, {
// class: 'v-scroll-reveal', // A CSS class applied to elements with the v-scroll-reveal directive; useful for animation overrides.
// duration: 1200,
// scale: 0.95,
// distance: '10px',
// rotate: {
// x: 0,
// y: 0,
// z: 0
// }
// // mobile: true
// })
@Component({
name: 'CTitleBanner'
})
export default class CTitleBanner extends Vue {
@Prop({ required: true}) public title: string
@Prop({ required: false, default: 'bg-primary' }) public bgcolor: string
@Prop({ required: false, default: 'primary' }) public color: string
}

View File

@@ -0,0 +1,16 @@
<template>
<div>
<q-banner
class="q-my-md"
rounded dense :class="bgcolor+` text-white`"
:color="color+` q-title`" style="text-align: center;">
<span class="mybanner">{{title}}</span>
</q-banner>
</div>
</template>
<script lang="ts" src="./CTitleBanner.ts">
</script>
<style lang="scss" scoped>
@import './CTitleBanner.scss';
</style>

View File

@@ -0,0 +1 @@
export {default as CTitleBanner} from './CTitleBanner.vue'

View File

@@ -37,7 +37,7 @@ $textcol_scuro: darkblue;
.landing__footer-icons {
font-size: 1.75rem
font-size: 2rem
}
.landing__footer-icons a {
@@ -171,6 +171,7 @@ $textcol_scuro: darkblue;
}
.mycontacts_text {
font-size: 1rem;
color: #999;
letter-spacing: normal !important;
}
@@ -183,3 +184,12 @@ $textcol_scuro: darkblue;
.footer_link:hover {
color:white;
}
.margin_buttons_footer {
margin: -4px -4px;
}
.margin_buttons_footer > * {
margin: 4px 8px;
}

View File

@@ -14,11 +14,12 @@ import Quasar from 'quasar'
import { FormNewsletter } from '../FormNewsletter'
import { IUserState } from '../../model'
import MixinBase from '../../mixins/mixin-base'
import { CFacebookFrame } from '../CFacebookFrame'
@Component({
mixins: [MixinBase],
name: 'Footer',
components: { Logo, FormNewsletter }
components: { Logo, FormNewsletter, CFacebookFrame }
})
export default class Footer extends Vue {
@@ -30,26 +31,34 @@ export default class Footer extends Vue {
return tools
}
get mythis() {
get mythisfoot() {
return this
}
get TelegramSupport() {
return GlobalStore.getters.getValueSettingsByKey('TELEGRAM_SUPPORT')
return GlobalStore.getters.getValueSettingsByKey('TELEGRAM_SUPPORT', false)
}
get Whatsapp_Cell() {
return GlobalStore.getters.getValueSettingsByKey('WHATSAPP_CELL')
return GlobalStore.getters.getValueSettingsByKey('WHATSAPP_CELL', false)
}
get Telegram_UsernameHttp() {
return tools.getHttpForTelegram(GlobalStore.getters.getValueSettingsByKey('TELEGRAM_USERNAME', false))
}
get FBPage() {
const fb = GlobalStore.getters.getValueSettingsByKey('URL_FACEBOOK')
const fb = GlobalStore.getters.getValueSettingsByKey('URL_FACEBOOK', false)
return fb
}
get InstagramPage() {
const insta = GlobalStore.getters.getValueSettingsByKey('URL_INSTAGRAM')
return insta
return GlobalStore.getters.getValueSettingsByKey('URL_INSTAGRAM', false)
}
get TwitterPage() {
return GlobalStore.getters.getValueSettingsByKey('URL_TWITTER', false)
}
get static_data() {

View File

@@ -3,16 +3,52 @@
<section class="landing__footer">
<div class="row justify-between items-start q-col-gutter-xs">
<div class="col-12 col-sm-4 ">
<p style="text-align: center">
<logo></logo>
</p>
<!--<span v-html="$t('homepage.footer.description')">-->
<!--</span>-->
<FormNewsletter v-if="static_data.functionality.SHOW_NEWSLETTER" :idwebsite="tools.appid()"
:locale="tools.getLocale()">
</FormNewsletter>
<CFacebookFrame myclass="text-center" :fbimage="getValDb('FBPAGE_IMG', false)"
:urlfbpage="getValDb('FBPAGE_FRAME', false)" :title="getValDb('FBPAGE_TITLE', false)">
</CFacebookFrame>
<div class=" q-my-md">
<div class="landing__footer-icons row flex-center margin_buttons">
<a v-if="!!FBPage" :href="FBPage" target="_blank">
<i aria-hidden="true" class="q-icon fab fa-facebook-f icon_contact links"> </i></a>
<a v-if="!!InstagramPage" :href="InstagramPage" target="_blank">
<i aria-hidden="true" class="q-icon fab fa-instagram icon_contact links"> </i></a>
<a v-if="!!TwitterPage" :href="TwitterPage" target="_blank">
<i aria-hidden="true" class="q-icon fab fa-twitter icon_contact links"> </i></a>
<a v-if="!!TelegramSupport" :href="TelegramSupport" target="_blank">
<i aria-hidden="true" class="q-icon fab fa-telegram icon_contact links"></i></a>
<a v-if="!!Whatsapp_Cell" :href="ChatWhatsapp" target="_blank">
<i aria-hidden="true" class="q-icon fab fa-whatsapp icon_contact links"></i></a>
<a v-if="!!Telegram_UsernameHttp" :href="Telegram_UsernameHttp" target="_blank">
<i aria-hidden="true" class="q-icon fab fa-telegram icon_contact links"></i></a>
<!--<a href="" target="_blank"><i aria-hidden="true" class="q-icon fab fa-github"> </i></a>-->
<!--<a href="https://twitter.com/" target="_blank"><i aria-hidden="true" class="q-icon fab fa-twitter"> </i></a>-->
<!--<a href="https://discord.gg/5TDhbDg" target="_blank"><i aria-hidden="true"-->
<!--class="q-icon fab fa-discord"> </i></a><a-->
<!--href="https://forum.quasar-framework.org/" target="_blank"><i aria-hidden="true"-->
<!--class="q-icon fas fa-comments"> </i></a><a-->
<!--href="https://www.patreon.com/quasarframework" target="_blank"><i aria-hidden="true"-->
<!--class="q-icon fab fa-patreon"> </i></a>-->
</div>
</div>
<div class="text-center">
<span v-html="getValDb('MAP_TITLE', false)"></span>
<br>
<a :href="getValDb('URLMAP', false)" target="_blank" class="footer_link">Apri Mappa</a>
</div>
<!--<div class="q-mt-xs copyrights">-->
<!--<p class="mycontacts_text" v-html="$t('homepage.copyrights')"></p>-->
@@ -26,61 +62,58 @@
<p class="mycontacts_title">{{$t('homepage.titlecontatti')}}</p>
<p class="mycontacts_text">
<i v-if="getValDb('MAIN_EMAIL')" aria-hidden="true"
<div class="mycontacts_text">
<i v-if="getValDb('MAIN_EMAIL', false)" aria-hidden="true"
class="q-icon fas fa-envelope q-mx-sm"></i>
<a :href="`mailto:` + getValDb('MAIN_EMAIL')" class="links">{{ getValDb('MAIN_EMAIL')
<a :href="`mailto:` + getValDb('MAIN_EMAIL', false)" class="links">{{ getValDb('MAIN_EMAIL', false)
}}</a><br>
<br>
<span v-for="rec in getarrValDb('CONTACTS_EMAIL_CELL')">
{{ rec.name }}: {{ rec.phone }}
<a v-if="!!tools.getHttpForWhatsapp(rec.phone)" :href="tools.getHttpForWhatsapp(rec.phone)" target="_blank">
<i aria-hidden="true" class="q-icon fab fa-whatsapp icon_contact links"></i></a>
<br>
<i v-if="rec.email" aria-hidden="true"
class="q-icon fas fa-envelope q-mx-sm"></i> <a :href="`mailto:`+ rec.email "
class="links">{{rec.email}}</a>
<br>
</span>
<span v-if="getValDb('CALL_WORKING_DAYS')"><br>orari per chiamate:<br>
<span v-html="getValDb('CALL_WORKING_DAYS')"></span></span>
<!--Elisa Ghizzardi: 338-9344724 <a href="mailto:elisa.ghizzardi@yahoo.com" class="links">elisa.ghizzardi@yahoo.com</a><br>
<div style="margin-bottom: 20px;"></div>
<div v-for="rec in getarrValDb('CONTACTS_EMAIL_CELL', false)"
class="mycontacts_text margin_buttons_footer"
style="margin-bottom: 0px;">
<div>
{{ rec.name }}: {{ rec.phone }}
</div>
<div>
<i v-if="rec.email" aria-hidden="true"
class="q-icon fas fa-envelope q-ma-sm"></i> <a :href="`mailto:`+ rec.email "
class="links">{{rec.email}}</a>
</div>
Cristina Barattoni: 335-8233721 <a href="mailto:info@cristinabarattoni.it"
class="links">info@cristinabarattoni.it</a><br><br>'
+
'orari per chiamate:<br>lun-ven: 12:30-13:30; 17:00-19.30<br>sab-dom: 10-18
<div class="row justify-center margin_buttons_footer">
<q-btn v-if="rec.email" fab-mini icon="fas fa-envelope"
color="blue-grey-6" type="a"
size="sm"
:href="tools.getemailto(rec.email)" target="__blank">
</q-btn>
<q-btn v-if="tools.getHttpForWhatsapp(rec.phone)" fab-mini
icon="fab fa-whatsapp"
color="green" type="a"
size="sm"
:href="tools.getHttpForWhatsapp(rec.phone)" target="__blank">
</q-btn>
-->
<q-btn v-if="tools.getHttpForTelegram(rec.usertelegram)" fab-mini
icon="fab fa-telegram"
color="blue" type="a"
size="sm"
:href="tools.getHttpForTelegram(rec.usertelegram)" target="__blank">
</q-btn>
</div>
</p>
</div>
<div class="landing__footer-icons row flex-center">
<a v-if="!!FBPage" :href="FBPage" target="_blank">
<i aria-hidden="true" class="q-icon fab fa-facebook-f icon_contact links"> </i></a>
</div>
<span v-if="getValDb('CALL_WORKING_DAYS', false)"><br>orari per chiamate:<br>
<span v-html="getValDb('CALL_WORKING_DAYS', false)"></span></span>
<a v-if="!!InstagramPage" :href="InstagramPage" target="_blank">
<i aria-hidden="true" class="q-icon fab fa-instagram icon_contact links"> </i></a>
<a v-if="!!TelegramSupport" :href="TelegramSupport" target="_blank">
<i aria-hidden="true" class="q-icon fab fa-telegram icon_contact links"></i></a>
<a v-if="!!Whatsapp_Cell" :href="ChatWhatsapp" target="_blank">
<i aria-hidden="true" class="q-icon fab fa-whatsapp icon_contact links"></i></a>
<!--<a href="" target="_blank"><i aria-hidden="true" class="q-icon fab fa-github"> </i></a>-->
<!--<a href="https://twitter.com/" target="_blank"><i aria-hidden="true" class="q-icon fab fa-twitter"> </i></a>-->
<!--<a href="https://discord.gg/5TDhbDg" target="_blank"><i aria-hidden="true"-->
<!--class="q-icon fab fa-discord"> </i></a><a-->
<!--href="https://forum.quasar-framework.org/" target="_blank"><i aria-hidden="true"-->
<!--class="q-icon fas fa-comments"> </i></a><a-->
<!--href="https://www.patreon.com/quasarframework" target="_blank"><i aria-hidden="true"-->
<!--class="q-icon fab fa-patreon"> </i></a>-->
</div>
</div>
</div>
<FormNewsletter v-if="static_data.functionality.SHOW_NEWSLETTER" :idwebsite="tools.appid()"
:locale="tools.getLocale()">
</FormNewsletter>
<p class="text-center">
<router-link v-if="static_data.functionality.SHOW_ONLY_POLICY" to="/policy"><span
class="footer_link">{{$t('privacy_policy')}}</span></router-link>
@@ -89,20 +122,23 @@
</div>
<div class="col-12 col-sm-4 q-pa-md" v-for="">
<p style="text-align: center">
<logo></logo>
</p>
<div v-for="myitemmenu in static_data.routes">
<div v-if="myitemmenu.infooter">
<div v-if="myitemmenu.infooter && tools.visumenu(myitemmenu)">
<div v-if="myitemmenu.solotitle">
<span class="footer_link">{{tools.getLabelByItem(myitemmenu, mythis)}}</span><br/>
<span class="footer_link">{{tools.getLabelByItem(myitemmenu, mythisfoot)}}</span><br/>
</div>
<div v-else>
<router-link :to="myitemmenu.path">
<span class="footer_link"><span
v-if="myitemmenu.level_child > 0">&nbsp;&nbsp;&nbsp;</span>
{{tools.getLabelByItem(myitemmenu, mythis)}}</span><br/>
{{tools.getLabelByItem(myitemmenu, mythisfoot)}}</span><br/>
</router-link>
</div>
<!--<a :href="myitemmenu.path"><span class="footer_link">{{tools.getLabelByItem(myitemmenu, mythis)}}</span></a><br/>-->
<!--<a :href="myitemmenu.path"><span class="footer_link">{{tools.getLabelByItem(myitemmenu, mythisfoot)}}</span></a><br/>-->
</div>
</div>
</div>

View File

@@ -8,12 +8,13 @@ import Quasar, { Screen } from 'quasar'
import { Prop } from 'vue-property-decorator'
import { Api } from '../../store'
import { serv_constants } from '../../store/Modules/serv_constants'
import MixinBase from '../../mixins/mixin-base'
@Component({
name: 'FormNewsletter'
})
export default class FormNewsletter extends Vue {
export default class FormNewsletter extends MixinBase {
public $t
public $q
public name: string = null
@@ -24,10 +25,6 @@ export default class FormNewsletter extends Vue {
@Prop() public idwebsite: string
@Prop() public locale: string
get tools() {
return tools
}
public async onSubmit() {
if (this.accept !== true) {
@@ -44,14 +41,16 @@ export default class FormNewsletter extends Vue {
firstName: this.name,
lastName: this.surname,
idwebsite: this.idwebsite,
locale: this.locale
locale: this.locale,
settomailchimp: this.getValDb('MAILCHIMP_ON', true, false)
}
console.log(usertosend)
return await Api.SendReq('/signup_news', 'POST', usertosend, false)
return await Api.SendReq('/news/signup', 'POST', usertosend, false)
.then((res) => {
if (res.data.result === serv_constants.RIS_SUBSCRIBED_OK) {
console.log('res', res)
if (res.data.code === serv_constants.RIS_SUBSCRIBED_OK) {
this.$q.notify({
color: 'green-4',
textColor: 'white',
@@ -59,7 +58,7 @@ export default class FormNewsletter extends Vue {
// message: this.$t('newsletter.submitted')
message: res.data.msg
})
} else if (res.data.result === serv_constants.RIS_SUBSCRIBED_ALREADYEXIST) {
} else if (res.data.code === serv_constants.RIS_SUBSCRIBED_ALREADYEXIST) {
this.$q.notify({
color: 'orange-4',
textColor: 'white',

View File

@@ -10,6 +10,7 @@
<q-input
filled
name="firstName"
dense
dark standout
v-model="name"
:label="$t('newsletter.name') + `*`"
@@ -21,6 +22,7 @@
<q-input
filled
dense
dark standout
v-model="surname"
name="lastName"
@@ -33,6 +35,7 @@
<q-input
filled
dense
dark standout
v-model="email"
:label="$t('newsletter.email') + `*`"

View File

@@ -172,7 +172,7 @@ export default class Header extends Vue {
if (this.static_data.functionality.SHOW_IF_IS_SERVER_CONNECTION) {
if (!!oldValue) {
tools.showNotif(this.$q, this.$t('connection') + ` ${value}`, {
tools.showNotif(this.$q, this.$t('connection') + ` disc__value}`, {
color,
icon: 'wifi'
})
@@ -307,6 +307,10 @@ export default class Header extends Vue {
return '../../' + tools.getimglogo()
}
get getappname() {
return tools.getappname(this)
}
public toggleanimation() {
console.log('toggleanimation')
this.visuimg = false

View File

@@ -35,11 +35,11 @@
class="btnNewVersShow" @click="RefreshApp" :label="$t('notification.newVersionAvailable')"/>
<q-toolbar-title>
<q-toolbar-title class="row items-center">
<q-avatar>
<img :src="imglogo" height="27">
<img :src="imglogo" height="27" alt="Immagine Logo">
</q-avatar>
{{tools.getappname()}}
<div class="q-mx-sm">{{getappname}}</div>
<div slot="subtitle">{{$t('msg.myDescriz')}} {{ getAppVersion() }}</div>
</q-toolbar-title>
@@ -83,7 +83,7 @@
v-for="langrec in static_data.lang_available" :key="langrec.value"
@click="lang = langrec.value">
<q-item-section avatar>
<img :src="langrec.image" class="flagimg">
<img :src="langrec.image" class="flagimg" alt="flag">
</q-item-section>
<q-item-section>
{{langrec.label}}
@@ -128,12 +128,11 @@
</q-drawer>
<!-- USER BAR -->
<q-drawer v-if="static_data.functionality.SHOW_USER_MENU" v-model="rightDrawerOpen" side="right" elevated>
<div id="profile">
<q-img class="absolute-top" src="../../statics/images/landing_first_section.png"
style="height: 150px">
style="height: 150px" alt="section page">
</q-img>
<div class="absolute-top bg-transparent text-black center_img" style="margin-top: 10px;">

View File

@@ -3,6 +3,8 @@ export * from './todos'
export * from './logo'
export * from './CProgress'
export * from './CCard'
export * from './CCardCarousel'
export * from './CCardDiscipline'
export * from './CBook'
export * from './CMyPage'
export * from './CTitle'
@@ -12,16 +14,23 @@ export * from './CMyPopupEdit'
export * from './CMyToggleList'
export * from './CMyChipList'
export * from './CMyEditor'
export * from './CMyFieldDb'
export * from './CMyTeacher'
export * from './CImgText'
export * from './CImgTitle'
export * from './CPreloadImages'
export * from './CSignIn'
export * from './CSignUp'
export * from './CEventsCalendar'
export * from './CMySingleEvent'
export * from './CDate'
export * from './CDateTime'
export * from './BannerCookies'
export * from './PagePolicy'
export * from './FormNewsletter'
export * from './CGridTableRec'
export * from './CFacebookFrame'
export * from './Shen/CTesseraElettronica'
export * from './CGoogleMap'
export * from './COpenStreetMap'
export * from './CTitleBanner'

View File

@@ -61,6 +61,10 @@
color: red;
}
.isCalendar {
color: #fff241;
}
.isManager {
color: green;
}

View File

@@ -20,6 +20,10 @@ export default class MenuOne extends Vue {
// return this.$route.path
// }
get isfinishLoading() {
return GlobalStore.state.finishLoading
}
get tools() {
return tools
}
@@ -32,11 +36,6 @@ export default class MenuOne extends Vue {
return GlobalStore.getters.getmenu
}
public visumenu(elem) { // : IListRoutes
return (elem.onlyAdmin && UserStore.state.isAdmin) || (elem.onlyManager && UserStore.state.isManager)
|| ((!elem.onlyAdmin) && (!elem.onlyManager))
}
public setParentVisibilityBasedOnRoute(parent) {
parent.routes.forEach((item) => {
if (this.$route.path === item.path) {
@@ -74,6 +73,9 @@ export default class MenuOne extends Vue {
if (elem.onlyManager)
menu += ' isManager'
if (elem.extraclass)
menu += ' ' + elem.extraclass
return menu
}
}

View File

@@ -1,10 +1,10 @@
<template>
<div class="no-border">
<div class="no-border" v-if="isfinishLoading">
<q-list class="rounded-borders text-primary">
<template v-for="(parent, index) in getmenu">
<!--<div class="q-list-header">{{replaceUnderlineToSpace(index)}}</div>-->
<div v-for="myitemmenu in static_data.routes">
<div v-if="!!myitemmenu.routes2 && myitemmenu.inmenu && visumenu(myitemmenu)">
<div v-if="!!myitemmenu.routes2 && myitemmenu.inmenu && tools.visumenu(myitemmenu)">
<q-expansion-item
:header-inset-level="myitemmenu.level_parent"
:content-inset-level="myitemmenu.level_parent"
@@ -14,35 +14,70 @@
:header-class="getmymenuclass(myitemmenu)"
active-class="my-menu-active">
<q-expansion-item v-for="(child2, index) in myitemmenu.routes2"
:key="index"
:to="getroute(child2)"
:header-inset-level="child2.level_child"
:duration="300"
:icon="child2.materialIcon"
active-class="my-menu-active"
expand-icon-class="my-menu-icon-none"
class="item item-link drawer-closer cursor-pointer my-menu"
:label="tools.getLabelByItem(child2, mythis)">
<q-expansion-item v-if="!!child2.routes2" v-for="(child3, index) in child2.routes2"
:key="index"
:to="getroute(child3)"
:header-inset-level="child3.level_child"
:duration="300"
:icon="child3.materialIcon"
:expand-icon="child3.icon"
expand-icon-class="my-menu-separat"
active-class="my-menu-active"
class="item item-link drawer-closer cursor-pointer my-menu"
:label="tools.getLabelByItem(child3, mythis)">
<div v-for="(child2, index) in myitemmenu.routes2" :key="index">
<q-expansion-item
v-if="!child2.routes2"
:to="getroute(child2)"
:header-inset-level="child2.level_child"
:duration="300"
:icon="child2.materialIcon"
active-class="my-menu-active"
expand-icon-class="my-menu-icon-none"
class="item item-link drawer-closer cursor-pointer my-menu"
:label="tools.getLabelByItem(child2, mythis)">
<q-expansion-item v-if="!!child2.routes2" v-for="(child3, index) in child2.routes2"
:key="index"
:to="getroute(child3)"
:header-inset-level="child3.level_child"
:duration="300"
:icon="child3.materialIcon"
:expand-icon="child3.icon"
expand-icon-class="my-menu-separat"
active-class="my-menu-active"
class="item item-link drawer-closer cursor-pointer my-menu"
:label="tools.getLabelByItem(child3, mythis)">
</q-expansion-item>
</q-expansion-item>
</q-expansion-item>
<q-expansion-item
v-else
:header-inset-level="child2.level_parent"
:content-inset-level="child2.level_parent"
:label="tools.getLabelByItem(child2, mythis)"
:icon="child2.materialIcon"
expand-icon-class="my-menu-separat"
:header-class="getmymenuclass(child2)"
active-class="my-menu-active">
<div v-for="(child3, index) in child2.routes2" :key="index">
<q-expansion-item
:to="getroute(child3)"
:header-inset-level="child3.level_child"
:duration="300"
:icon="child3.materialIcon"
active-class="my-menu-active"
expand-icon-class="my-menu-icon-none"
class="item item-link drawer-closer cursor-pointer my-menu"
:label="tools.getLabelByItem(child3, mythis)">
<q-expansion-item v-if="!!child3.routes2" v-for="(child3, index) in child3.routes2"
:key="index"
:to="getroute(child3)"
:header-inset-level="child3.level_child"
:duration="300"
:icon="child3.materialIcon"
:expand-icon="child3.icon"
expand-icon-class="my-menu-separat"
active-class="my-menu-active"
class="item item-link drawer-closer cursor-pointer my-menu"
:label="tools.getLabelByItem(child3, mythis)">
</q-expansion-item>
</q-expansion-item>
</div>
</q-expansion-item>
</div>
</q-expansion-item>
</div>
<div v-else>
<div v-if="myitemmenu.inmenu && !myitemmenu.submenu && visumenu(myitemmenu)">
<div v-if="myitemmenu.inmenu && !myitemmenu.submenu && tools.visumenu(myitemmenu)">
<q-slide-transition :duration=200>
<div v-show="true">
<q-expansion-item
@@ -55,24 +90,6 @@
header-class="my-menu"
active-class="my-menu-active">
</q-expansion-item>
<!--
<q-item
clickable
v-ripple
exact
:to="myitemmenu.route"
active-class="my-menu-active">
<q-item-section avatar class="my-menu-icon">
<q-icon :name="myitemmenu.materialIcon"/>
</q-item-section>
<q-item-section class="my-menu">
{{$t(myitemmenu.name)}}
</q-item-section>
</q-item>
-->
</div>
</q-slide-transition>
</div>

View File

@@ -19,7 +19,7 @@
<q-item-section avatar>
<q-avatar>
<img :src="getImgByMsg(msg)">
<img :src="getImgByMsg(msg)" :alt="getUsernameChatByMsg(msg)">
</q-avatar>
</q-item-section>

View File

@@ -5,6 +5,8 @@ import { func_tools } from '../store/Modules/toolsext'
import { tools } from '../store/Modules/tools'
import { toolsext } from '@src/store/Modules/toolsext'
import { GlobalStore } from '../store/Modules'
import { fieldsTable } from '@src/store/Modules/fieldsTable'
import { CalendarStore } from '@store'
// You can declare a mixin as the same style as components.
@Component
@@ -17,6 +19,10 @@ export default class MixinBase extends Vue {
return toolsext
}
get db_fieldsTable() {
return fieldsTable
}
get func_tools() {
return func_tools
}
@@ -25,19 +31,87 @@ export default class MixinBase extends Vue {
return tools
}
public getValDb(keystr) {
return GlobalStore.getters.getValueSettingsByKey(keystr)
public getValDb(keystr, serv, def?) {
const ris = GlobalStore.getters.getValueSettingsByKey(keystr, serv)
if (ris === '')
if (def !== undefined)
return def
else
return ''
else
return ris
}
public getarrValDb(keystr) {
const myval = GlobalStore.getters.getValueSettingsByKey(keystr)
public async setValDb(key, value, type, serv: boolean) {
console.log('setValDb', key, value, serv)
GlobalStore.mutations.setValueSettingsByKey({ key, value, serv })
let myrec = GlobalStore.getters.getrecSettingsByKey(key, serv)
if (myrec === undefined) {
myrec = {
idapp: process.env.APP_ID,
key,
type
}
myrec.serv = serv
if (myrec.type === tools.FieldType.date)
myrec.value_date = value
else if (myrec.type === tools.FieldType.number)
myrec.value_num = value
else if (myrec.type === tools.FieldType.boolean)
myrec.value_bool = value
else
myrec.value_str = value
myrec = await tools.createNewRecord(this, 'settings', myrec).then((myrecris) => {
// console.log('myrec')
let recsett = null
if (serv)
recsett = GlobalStore.state.serv_settings
else
recsett = GlobalStore.state.settings
recsett.push(myrecris)
return recsett.find((rec) => rec.key === key)
})
}
console.log('myrec', myrec)
const mydatatosave = {
id: myrec._id,
table: 'settings',
fieldsvalue: myrec
}
console.log('mydatatosave', mydatatosave)
GlobalStore.actions.saveFieldValue(mydatatosave).then((esito) => {
if (esito) {
tools.showPositiveNotif(this.$q, this.$t('db.recupdated'))
} else {
tools.showNegativeNotif(this.$q, this.$t('db.recfailed'))
// Undo...
}
})
}
public getarrValDb(keystr, serv) {
const myval = GlobalStore.getters.getValueSettingsByKey(keystr, serv)
// console.log('myval', myval)
if (myval) {
const myrec = JSON.parse(myval)
// console.log('*************** getarrValDb')
// console.table(myrec)
return myrec
} else {
try {
if (myval) {
const myrec = JSON.parse(myval)
// console.log('*************** getarrValDb')
// console.table(myrec)
return myrec
} else {
return []
}
} catch (e) {
return []
}
}
}

119
src/mixins/mixin-events.ts Normal file
View File

@@ -0,0 +1,119 @@
import Vue from 'vue'
import Component from 'vue-class-component'
import { func_tools } from '../store/Modules/toolsext'
import { tools } from '../store/Modules/tools'
import { IMessage } from '@src/model'
import { IEvents } from '../model'
import { CalendarStore, GlobalStore } from '@store'
import translate from '@src/globalroutines/util'
// You can declare a mixin as the same style as components.
@Component
export default class MixinEvents extends Vue {
public getImgEvent(event: IEvents) {
if (!!event.img)
return 'statics/' + event.img
else
return 'statics/images/noimg.png'
}
public getStyleByEvent(event: IEvents, visu: boolean) {
let myst = 'border: inset; border-color: darkblue; border-width: 3px; padding: 5px !important; '
if (!this.isEventEnabled(event)) {
myst += ' opacity: 0.5'
}
return myst
}
public isAlreadyBooked(eventparam: IEvents) {
return CalendarStore.getters.findEventBooked(eventparam, true)
}
public getWhereIcon(where) {
const whererec = CalendarStore.getters.getWhereRec(where)
return (whererec) ? whererec.whereicon : ''
}
public getWhereName(where) {
const whererec = CalendarStore.getters.getWhereRec(where)
return (whererec) ? whererec.placename : ''
}
get editable() {
return CalendarStore.state.editable
}
public getContribtypeById(id) {
return CalendarStore.getters.getContribtypeById(id)
}
public getPrice(event: IEvents) {
let myprice = (event.price > 0) ? event.price + ' €' : ''
myprice = (event.price === -1) ? translate('event.askinfo') : myprice
if (event.infoafterprice)
myprice += ' ' + event.infoafterprice
return myprice
}
public isShowPrice(event: IEvents) {
const rec = CalendarStore.getters.getContribtypeRec(event.contribtype)
return (rec) ? rec.showprice : true
}
public isEventEnabled(myevent) {
// check if event is in the past
const datenow = tools.addDays(tools.getDateNow(), -1)
// console.log('datenow', datenow, 'end', myevent.dateTimeEnd)
return (new Date(myevent.dateTimeEnd) >= datenow)
}
public findEventIndex(eventparam) {
for (let i = 0; i < CalendarStore.state.eventlist.length; ++i) {
if (eventparam) {
if (eventparam.title === CalendarStore.state.eventlist[i].title &&
eventparam.details === CalendarStore.state.eventlist[i].details &&
eventparam.dateTimeStart === CalendarStore.state.eventlist[i].dateTimeStart &&
eventparam.dateTimeEnd === CalendarStore.state.eventlist[i].dateTimeEnd) {
return i
}
}
}
}
public UpdateDbByFields(self, myrec, undo?) {
const mydatatosave = {
id: myrec._id,
table: tools.TABEVENTS,
fieldsvalue: myrec
}
GlobalStore.actions.saveFieldValue(mydatatosave).then((esito) => {
if (esito) {
tools.showPositiveNotif(this.$q, this.$t('db.recupdated'))
} else {
tools.showNegativeNotif(this.$q, this.$t('db.recfailed'))
// Undo...
if (undo) {
const index = self.findEventIndex(self.contextDay)
if (index >= 0) {
// @ts-ignore
CalendarStore.state.eventlist.splice(index, 1, { ...self.contextDay })
}
}
}
})
}
}

View File

@@ -0,0 +1,22 @@
import Vue from 'vue'
import Component from 'vue-class-component'
import { IMetaTags } from '@src/model'
import { tools } from '@src/store/Modules/tools'
// You can declare a mixin as the same style as components.
@Component
export default class MixinMetaTags extends Vue {
public mymeta: IMetaTags = {title: '', description: '', keywords: ''}
public setmeta(mymeta: IMetaTags) {
this.mymeta = mymeta
}
public getsrcbyimg(myimg) {
// return this.src
const filefull = tools.getimgFullpathbysize(myimg)
return tools.getimgbysize(filefull.path, filefull.file)
}
}

View File

@@ -6,6 +6,7 @@ export interface IEvents {
short_tit?: string
title?: string
details?: string
bodytext?: string
dateTimeStart?: Date
dateTimeEnd?: Date
side?: string

View File

@@ -26,12 +26,82 @@ export interface ICfgData {
userId?: string
}
export interface ITemplEmail {
_id?: string
subject?: string
content?: string
options?: ISettings[]
}
export interface ISettings {
_id?: string
idapp?: string
key?: string
type?: number
value_str?: string
value_date?: Date,
value_num?: number
value_bool?: boolean
serv?: boolean
}
export interface ITeachUname {
username?: string
}
export interface IMyPage {
_id?: string
author_username?: string
title?: string
icon?: string
path?: string
keywords?: string
description?: string
content?: string
active?: boolean
inmenu?: boolean
submenu?: boolean
l_par?: number,
l_child?: number,
infooter?: boolean
}
export interface INewsToSent {
_id: string
idapp?: string
label?: string
templemail_str?: string
numemail_tot?: number
numemail_sent?: number
datetoSent?: Date
datestartJob?: Date
datefinishJob?: Date
lastemailsent_Job?: Date
starting_job?: boolean
finish_job?: boolean
error_job?: string
}
export interface IMailinglist {
name?: string
surname?: string
email: string
lastid_newstosent?: string
}
export interface IDiscipline {
typol_code?: string
order?: number
label?: string
description?: string
linkpage?: string
color?: string
icon?: string
img_small?: string
showinhome?: boolean
showinnewsletter?: boolean
img?: string
teachers?: ITeachUname[]
}
export interface ITestp1 {
@@ -47,6 +117,12 @@ export interface IConfig {
value: string
}
export interface IMetaTags {
title?: string
keywords?: string
description?: string
}
export interface IGlobalState {
finishLoading: boolean
conta: number
@@ -69,7 +145,15 @@ export interface IGlobalState {
listatodo: IMenuList[]
arrConfig: IConfig[]
lastaction: IAction
serv_settings: ISettings[],
settings: ISettings[],
disciplines: IDiscipline[],
newstosent: INewsToSent[],
mypage: IMyPage[],
templemail: ITemplEmail[],
opzemail: ISettings[],
mailinglist: IMailinglist[],
autoplaydisc: number
}
export interface IMenuList {
@@ -96,6 +180,7 @@ export interface IListRoutes {
submenu?: boolean
onlyAdmin?: boolean
onlyManager?: boolean
extraclass?: string
meta?: any
idelem?: string
urlroute?: string
@@ -118,6 +203,7 @@ export interface IOperators {
certifications?: string
img?: string
cell?: string
usertelegram?: string
paginaweb?: string
paginafb?: string
intro?: string
@@ -128,6 +214,7 @@ export interface IOperators {
export interface IPreloadImages {
imgname: string
alt: string
mobile: boolean
}
@@ -254,6 +341,8 @@ export interface ITableRec {
colkey: string
collabel: string
colicon?: string
onlyAdmin?: boolean
noshow: boolean
}
export interface IDataPass {
@@ -261,3 +350,21 @@ export interface IDataPass {
table: string
fieldsvalue: object
}
export interface INewsState {
lastnewstosent: INewsToSent
nextnewstosent: INewsToSent
totemail: number
totsubscribed: number
totunsubscribed: number
totsentlastid: number
}
export const DefaultNewsState: INewsState = {
lastnewstosent: null,
nextnewstosent: null,
totemail: 0,
totsubscribed: 0,
totunsubscribed: 0,
totsentlastid: 0,
}

View File

@@ -10,12 +10,17 @@ const msgglobal = {
tableslist: 'Tabelle',
},
otherpages: {
error404: 'error404',
error404def: 'error404def',
admin : {
menu: 'Amministrazione',
eventlist: 'Le tue Prenotazioni',
usereventlist: 'Prenotazioni Utenti',
userlist: 'Lista Utenti',
tableslist: 'Lista Tabelle',
newsletter: 'Newsletter',
pages: 'Pagine',
media: 'Media',
},
manage: {
menu: 'Gestione',
@@ -30,6 +35,7 @@ const msgglobal = {
write: 'scrive'
},
dialog: {
close: 'Chiudi',
ok: 'Ok',
yes: 'Si',
no: 'No',
@@ -73,7 +79,9 @@ const msgglobal = {
verify_email: 'Verifica la tua email',
go_login: 'Torna al Login',
incorrect_input: 'Inserimento incorretto.',
link_sent: 'Ora leggi la tua email e conferma la registrazione'
link_sent: 'Ora leggi la tua email e conferma la registrazione',
title_unsubscribe: 'Disiscrizione alla newsletter',
title_unsubscribe_done: 'Disiscrizione completata correttamente',
}
}
},
@@ -86,6 +94,15 @@ const msgglobal = {
notregistered: 'Devi registrarti al servizio prima di porter memorizzare i dati',
loggati: 'Utente non loggato'
},
templemail: {
subject: 'Oggetto Email',
testoheadermail: 'Intestazione Email',
content: 'Contenuto',
img: 'Immagine 1',
img2: 'Immagine 2',
content2: 'Contenuto 2',
options: 'Opzioni',
},
reg: {
page_title: 'Registrazione',
incorso: 'Registrazione in corso...',
@@ -130,6 +147,7 @@ const msgglobal = {
},
op: {
qualification: 'Qualifica',
usertelegram: 'Username Telegram',
disciplines: 'Discipline',
certifications: 'Certificazioni',
intro: 'Introduzione',
@@ -163,6 +181,7 @@ const msgglobal = {
undefined: 'non definito'
}
},
showbigmap: 'Mostra la mappa più grande',
todo: {
titleprioritymenu: 'Priorità:',
inserttop: 'Inserisci il Task in cima',
@@ -214,7 +233,13 @@ const msgglobal = {
code: 'Id',
whereicon: 'Icona',
},
col: {
label: 'Etichetta',
value: 'Valore',
type: 'Tipo'
},
cal: {
num: 'Numero',
booked: 'Prenotato',
booked_error: 'Prenotazione non avvenuta. Riprovare più tardi',
sendmsg_error: 'Messaggio non inviato. Riprovare più tardi',
@@ -230,6 +255,8 @@ const msgglobal = {
cancelederrorevent: 'Cancellazione Evento non effettuata, Riprovare',
event: 'Evento',
starttime: 'Dalle',
nextevent: 'Prossimo Evento',
readall: 'Leggi tutto',
enddate: 'al',
endtime: 'alle',
duration: 'Durata',
@@ -246,12 +273,13 @@ const msgglobal = {
selnumpeople: 'Partecipanti',
selnumpeople_short: 'Num',
msgbooking: 'Messaggio da inviare',
showinfo: 'Vedi Info',
bookingtextdefault: 'Mi prenoto all\'evento',
showpdf: 'Vedi PDF',
bookingtextdefault: 'Prenoto per',
bookingtextdefault_of: 'di',
data: 'Data',
teachertitle: 'Insegnante',
peoplebooked: 'Prenotaz.',
showlastschedule: 'Vedi tutto il Calendario',
},
msgs: {
message: 'Messaggio',
@@ -264,6 +292,7 @@ const msgglobal = {
short_tit: 'Titolo Breve',
title: 'Titolo',
details: 'Dettagli',
bodytext: 'Testo Evento',
dateTimeStart: 'Data Inizio',
dateTimeEnd: 'Data Fine',
bgcolor: 'Colore Sfondo',
@@ -275,6 +304,7 @@ const msgglobal = {
contribtype: 'Tipo Contributo',
price: 'Contributo',
askinfo: 'Chiedi Info',
showpage: 'Vedi Pagina',
infoafterprice: 'Note dopo la Quota',
teacher: 'Insegnante', // teacherid
teacher2: 'Insegnante2', // teacherid2
@@ -288,7 +318,14 @@ const msgglobal = {
deleted: 'Eliminato',
duplicate: 'Duplica',
notempty: 'Il campo non può essere vuoto',
modified: 'Modificato'
modified: 'Modificato',
showinhome: 'Mostra nella Home',
showinnewsletter: 'Mostra nella Newsletter',
color: 'Colore del titolo',
},
disc: {
typol_code: 'Codice Tipologia',
order: 'Ordinamento',
},
newsletter: {
title: 'Desideri ricevere la nostra Newsletter?',
@@ -303,6 +340,27 @@ const msgglobal = {
acceptlicense: 'Accetto la licenza e i termini',
license: 'Devi prima accettare la licenza e i termini',
submitted: 'Iscritto',
menu: 'Newsletter1',
template: 'Modelli Email',
sendemail: 'Invia',
check: 'Controlla',
sent: 'Già Inviate',
mailinglist: 'Lista Contatti',
settings: 'Impostazioni',
serversettings: 'Server',
others: 'Altro',
templemail: 'Modello Email',
datetoSent: 'DataOra Invio',
activate: 'Attivato',
numemail_tot: 'Email Totali',
numemail_sent: 'Email Inviate',
datestartJob: 'Inizio Invio',
datefinishJob: 'Fine Invio',
lastemailsent_Job: 'Ultima Inviata',
starting_job: 'Invio Iniziato',
finish_job: 'Invio Terminato',
error_job: 'Info Errori',
statesub: 'Sottoscritto',
},
privacy_policy:'Privacy Policy',
cookies: 'Usiamo i Cookie per una migliore prestazione web.'
@@ -322,6 +380,9 @@ const msgglobal = {
usereventlist: 'Reserva Usuarios',
userlist: 'Lista de usuarios',
tableslist: 'Listado de tablas',
newsletter: 'Newsletter',
pages: 'Páginas',
media: 'Medios',
},
manage: {
menu: 'Gestionar',
@@ -336,6 +397,7 @@ const msgglobal = {
write: 'escribe'
},
dialog: {
close: 'Cerrar',
ok: 'Vale',
yes: 'Sí',
no: 'No',
@@ -379,7 +441,9 @@ const msgglobal = {
verify_email: 'Revisa tu email',
go_login: 'Vuelve al Login',
incorrect_input: 'Entrada correcta.',
link_sent: 'Ahora lea su correo electrónico y confirme el registro'
link_sent: 'Ahora lea su correo electrónico y confirme el registro',
title_unsubscribe: 'Anular suscripción al boletín',
title_unsubscribe_done: 'Suscripción completada con éxito',
}
}
},
@@ -392,6 +456,15 @@ const msgglobal = {
notregistered: 'Debe registrarse en el servicio antes de poder almacenar los datos',
loggati: 'Usuario no ha iniciado sesión'
},
templemail: {
subject: 'Objecto Email',
testoheadermail: 'Encabezamiento Email',
content: 'Contenido',
img: 'Imagen 1',
img2: 'Imagen 2',
content2: 'Contenuto 2',
options: 'Opciones',
},
reg: {
page_title: 'Registro',
incorso: 'Registro en curso...',
@@ -429,6 +502,7 @@ const msgglobal = {
},
op: {
qualification: 'Calificación',
usertelegram: 'Username Telegram',
disciplines: 'Disciplinas',
certifications: 'Certificaciones',
intro: 'Introducción',
@@ -462,6 +536,7 @@ const msgglobal = {
undefined: 'no definido'
}
},
showbigmap: 'Mostrar el mapa más grande',
todo: {
titleprioritymenu: 'Prioridad:',
inserttop: 'Ingrese una nueva Tarea arriba',
@@ -514,7 +589,13 @@ const msgglobal = {
code: 'Id',
whereicon: 'Icono',
},
col: {
label: 'Etichetta',
value: 'Valore',
type: 'Tipo'
},
cal: {
num: 'Número',
booked: 'Reservado',
booked_error: 'Reserva fallida. Intenta nuevamente más tarde',
sendmsg_error: 'Mensaje no enviado Intenta nuevamente más tarde',
@@ -527,6 +608,8 @@ const msgglobal = {
cancelederrorbooking: 'Cancelación no realizada, intente nuevamente más tarde',
event: 'Evento',
starttime: 'Inicio',
nextevent: 'Próximo evento',
readall: 'Lee todo',
enddate: 'a',
endtime: 'fin',
duration: 'Duración',
@@ -543,12 +626,13 @@ const msgglobal = {
selnumpeople: 'Partecipantes',
selnumpeople_short: 'Num',
msgbooking: 'Mensaje para enviar',
showinfo: 'Ver Info',
bookingtextdefault: 'Reservo el evento',
showpdf: 'Ver PDF',
bookingtextdefault: 'Reservo para',
bookingtextdefault_of: 'de',
data: 'Fecha',
teachertitle: 'Maestro',
peoplebooked: 'Reserv.',
showlastschedule: 'Ver todo el calendario',
},
msgs: {
message: 'Mensaje',
@@ -561,6 +645,7 @@ const msgglobal = {
short_tit: 'Título Corto',
title: 'Título',
details: 'Detalles',
bodytext: 'Texto del evento',
dateTimeStart: 'Fecha de Inicio',
dateTimeEnd: 'Fecha Final',
bgcolor: 'Color de fondo',
@@ -572,6 +657,7 @@ const msgglobal = {
contribtype: 'Tipo de Contribución',
price: 'Precio',
askinfo: 'Solicitar información',
showpage: 'Ver página',
infoafterprice: 'notas después del precio',
teacher: 'Profesor', // teacherid
teacher2: 'Profesor2', // teacherid2
@@ -585,7 +671,14 @@ const msgglobal = {
deleted: 'Eliminado',
duplicate: 'Duplica',
notempty: 'El campo no puede estar vacío.',
modified: 'Modificado'
modified: 'Modificado',
showinhome: 'Mostrar en la Home',
showinnewsletter: 'Mostrar en el boletín',
color: 'Titulo Color',
},
disc: {
typol_code: 'Código Tipologìa',
order: 'Clasificación',
},
newsletter: {
title: '¿Desea recibir nuestro boletín informativo?',
@@ -599,7 +692,28 @@ const msgglobal = {
typesomething: 'Llenar el campo',
acceptlicense: 'Acepto la licencia y los términos',
license: 'Necesitas aceptar la licencia y los términos primero',
submitted: 'Subscrito'
submitted: 'Subscrito',
menu: 'Newsletter1',
template: 'Plantillas de Email',
sendemail: 'Enviar',
check: 'Verificar',
sent: 'Ya eniado',
mailinglist: 'Lista de contactos',
settings: 'Configuración',
serversettings: 'Servidor',
others: 'Otro',
templemail: 'Plantilla de Email',
datetoSent: 'Fecha y Ora de Envio',
activate: 'Activado',
numemail_tot: 'Email Total',
numemail_sent: 'Email Enviados',
datestartJob: 'Inicio Envio',
datefinishJob: 'Fin Envio',
lastemailsent_Job: 'Ùltimo enviado',
starting_job: 'Comenzó a enviar',
finish_job: 'Envio terminado',
error_job: 'Info Error',
statesub: 'Subscribir',
},
privacy_policy:'Política de privacidad',
cookies: 'Utilizamos cookies para un mejor rendimiento web.'
@@ -619,6 +733,9 @@ const msgglobal = {
usereventlist: 'Réservation Utilisateur',
userlist: 'Liste d\'utilisateurs',
tableslist: 'Liste des tables',
newsletter: 'Newsletter',
pages: 'Pages',
media: 'Médias',
},
manage: {
menu: 'Gérer',
@@ -633,6 +750,7 @@ const msgglobal = {
write: 'écrit'
},
dialog: {
close: 'Fermer',
ok: 'Bien',
yes: 'Oui',
no: 'Non',
@@ -676,7 +794,9 @@ const msgglobal = {
verify_email: 'Vérifiez votre email',
go_login: 'Retour à la connexion',
incorrect_input: 'Entrée correcte.',
link_sent: 'Maintenant, lisez votre email et confirmez votre inscription'
link_sent: 'Maintenant, lisez votre email et confirmez votre inscription',
title_unsubscribe: 'Se désabonner de la newsletter',
title_unsubscribe_done: 'Abonnement terminé avec succès',
}
}
},
@@ -689,6 +809,15 @@ const msgglobal = {
notregistered: 'Vous devez vous inscrire auprès du service avant de pouvoir stocker les données.',
loggati: 'L\'utilisateur n\'est pas connecté'
},
templemail: {
subject: 'Objet Email',
testoheadermail: 'en-tête de courrier électronique',
content: 'Contenu',
img: 'Image 1',
img2: 'Image 2',
content2: 'Contenu 2',
options: 'Options',
},
reg: {
incorso: 'Inscription en cours...',
richiesto: 'Champ obligatoire',
@@ -725,6 +854,7 @@ const msgglobal = {
},
op: {
qualification: 'Qualification',
usertelegram: 'Username Telegram',
disciplines: 'Disciplines',
certifications: 'Certifications',
intro: 'Introduction',
@@ -758,6 +888,7 @@ const msgglobal = {
undefined: 'non défini'
}
},
showbigmap: 'Montrer la plus grande carte',
todo: {
titleprioritymenu: 'Prioridad:',
inserttop: 'Ingrese una nueva Tarea arriba',
@@ -810,7 +941,13 @@ const msgglobal = {
code: 'Id',
whereicon: 'icône',
},
col: {
label: 'Etichetta',
value: 'Valore',
type: 'Tipo'
},
cal: {
num: 'Nombre',
booked: 'Réservé',
booked_error: 'La réservation a échoué. Réessayez plus tard',
sendmsg_error: 'Message non envoyé. Réessayez plus tard',
@@ -823,6 +960,8 @@ const msgglobal = {
cancelederrorbooking: 'Annulation non effectuée, réessayez plus tard',
event: 'événement',
starttime: 'Accueil',
nextevent: 'Prochain événement',
readall: 'Tout lire',
enddate: 'au',
endtime: 'fin',
duration: 'Durée',
@@ -839,12 +978,13 @@ const msgglobal = {
selnumpeople: 'Participants',
selnumpeople_short: 'Num',
msgbooking: 'Message à envoyer',
showinfo: 'Voir Info',
bookingtextdefault: 'Je réserve l\'événement',
showpdf: 'Voir PDF',
bookingtextdefault: 'Je réserve',
bookingtextdefault_of: 'du',
data: 'Date',
teachertitle: 'Professeur',
peoplebooked: 'Réserv.',
showlastschedule: 'Voir tout le calendrier',
},
msgs: {
message: 'Message',
@@ -857,6 +997,7 @@ const msgglobal = {
short_tit: 'Titre abrégé\'',
title: 'Titre',
details: 'Détails',
bodytext: 'texte de l\'événement',
dateTimeStart: 'Data Initiale',
dateTimeEnd: 'Date de fin',
bgcolor: 'Couleur de fond',
@@ -868,6 +1009,7 @@ const msgglobal = {
contribtype: 'Type de contribution',
price: 'Prix',
askinfo: 'Demander des infos',
showpage: 'Voir la page',
infoafterprice: 'Notes après le prix',
teacher: 'Enseignant', // teacherid
teacher2: 'Enseignant2', // teacherid2
@@ -881,7 +1023,14 @@ const msgglobal = {
deleted: 'Supprimé',
duplicate: 'Duplique',
notempty: 'Le champ ne peut pas être vide',
modified: 'modifié'
modified: 'modifié',
showinhome: 'Montrer à la Home',
showinnewsletter: 'Afficher dans la Newsletter',
color: 'Couleur du titre',
},
disc: {
typol_code: 'Type de code',
order: 'Ordre',
},
newsletter: {
title: 'Souhaitez-vous recevoir notre newsletter?',
@@ -895,7 +1044,28 @@ const msgglobal = {
typesomething: 'Remplir le champ',
acceptlicense: 'J\'accepte la licence et les termes',
license: 'Vous devez d\'abord accepter la licence et les termes',
submitted: 'Abonné'
submitted: 'Abonné',
menu: 'Newsletter1',
template: 'Modeles Email',
sendemail: 'Envoyer',
check: 'Chèque',
sent: 'Dèjà envoyé',
mailinglist: 'Leste de contacts',
settings: 'Paramèters',
serversettings: 'Serveur',
others: 'Autres',
templemail: 'Model Email',
datetoSent: 'Date et heure d\'envoi',
activate: 'Activé',
numemail_tot: 'Total Email',
numemail_sent: 'Emails envoyés',
datestartJob: 'Inizio Invio',
datefinishJob: 'Fin envoi',
lastemailsent_Job: 'Dernier envoyé',
starting_job: 'Envoyé',
finish_job: 'Envoy Terminé',
error_job: 'info d\'erreur',
statesub: 'Abonné',
},
privacy_policy:'Politique de confidentialité',
cookies: 'Nous utilisons des cookies pour améliorer les performances Web.'
@@ -915,6 +1085,9 @@ const msgglobal = {
usereventlist: 'Users Booking',
userlist: 'Users List',
tableslist: 'List of tables',
newsletter: 'Newsletter',
pages: 'Pages',
media: 'Medias',
},
manage: {
menu: 'Manage',
@@ -929,6 +1102,7 @@ const msgglobal = {
write: 'write'
},
dialog: {
close: 'Close',
ok: 'Ok',
yes: 'Yes',
no: 'No',
@@ -972,7 +1146,9 @@ const msgglobal = {
verify_email: 'Verify your email',
go_login: 'Back to Login',
incorrect_input: 'Incorrect input.',
link_sent: 'Now read your email and confirm registration'
link_sent: 'Now read your email and confirm registration',
title_unsubscribe: 'Unsubscribe to the newsletter',
title_unsubscribe_done: 'Subscription completed successfully',
}
}
},
@@ -985,6 +1161,15 @@ const msgglobal = {
notregistered: 'You need first to SignUp before storing data',
loggati: 'User not logged in'
},
templemail: {
subject: 'Subject Email',
testoheadermail: 'Header Email',
content: 'Content',
img: 'Image 1',
img2: 'Image 2',
content2: 'Content 2',
options: 'Options',
},
reg: {
incorso: 'Registration please wait...',
richiesto: 'Field Required',
@@ -1021,6 +1206,7 @@ const msgglobal = {
},
op: {
qualification: 'Qualification',
usertelegram: 'Username Telegram',
disciplines: 'Disciplines',
certifications: 'Certifications',
intro: 'Introduction',
@@ -1053,6 +1239,7 @@ const msgglobal = {
undefined: 'undefined'
}
},
showbigmap: 'Show the largest map',
todo: {
titleprioritymenu: 'Priority:',
inserttop: 'Insert Task at the top',
@@ -1105,7 +1292,13 @@ const msgglobal = {
code: 'Id',
whereicon: 'Icon',
},
col: {
label: 'Etichetta',
value: 'Valore',
type: 'Tipo'
},
cal: {
num: 'Number',
booked: 'Booked',
booked_error: 'Reservation failed. Try again later',
sendmsg_error: 'Message not sent. Try again later',
@@ -1118,6 +1311,8 @@ const msgglobal = {
cancelederrorbooking: 'Cancellation unsuccessfully, try again later',
event: 'Event',
starttime: 'From',
nextevent: 'Next Event',
readall: 'Read All',
enddate: 'to',
endtime: 'to',
duration: 'Duration',
@@ -1134,12 +1329,13 @@ const msgglobal = {
selnumpeople: 'Participants',
selnumpeople_short: 'Num',
msgbooking: 'Message to send',
showinfo: 'Show Info',
bookingtextdefault: 'I book the event',
showpdf: 'Show PDF',
bookingtextdefault: 'I book for',
bookingtextdefault_of: 'of',
data: 'Date',
teachertitle: 'Teacher',
peoplebooked: 'Booked',
showlastschedule: 'See Full Schedule',
},
msgs: {
message: 'Messaggio',
@@ -1152,6 +1348,7 @@ const msgglobal = {
short_tit: 'Short Title',
title: 'Title',
details: 'Details',
bodytext: 'Event Text',
dateTimeStart: 'Date Start',
dateTimeEnd: 'Date End',
bgcolor: 'Background color',
@@ -1163,6 +1360,7 @@ const msgglobal = {
contribtype: 'Contribute Type',
price: 'Price',
askinfo: 'Ask for Info',
showpage: 'Show Page',
infoafterprice: 'Info after Price',
teacher: 'Teacher', // teacherid
teacher2: 'Teacher2', // teacherid2
@@ -1176,7 +1374,14 @@ const msgglobal = {
deleted: 'Deleted',
duplicate: 'Duplicate',
notempty: 'Field cannot be empty',
modified: 'Modified'
modified: 'Modified',
showinhome: 'Show in Home',
showinnewsletter: 'Show in the Newsletter',
color: 'Title Color',
},
disc: {
typol_code: 'Tipology Code',
order: 'Order',
},
newsletter: {
title: 'Would you like to receive our Newsletter?',
@@ -1190,7 +1395,28 @@ const msgglobal = {
typesomething: 'Please type something',
acceptlicense: 'I accept the license and terms',
license: 'You need to accept the license and terms first',
submitted: 'Subscribed'
submitted: 'Subscribed',
menu: 'Newsletter1',
template: 'Template Email',
sendemail: 'Send',
check: 'Check',
sent: 'Already Sent',
mailinglist: 'Mailing List',
settings: 'Settings',
serversettings: 'Server',
others: 'Others',
templemail: 'Templates Email',
datetoSent: 'DateTime Send',
activate: 'Activate',
numemail_tot: 'Email Total',
numemail_sent: 'Email Sent',
datestartJob: 'Start Job',
datefinishJob: 'End Job',
lastemailsent_Job: 'Last Sent',
starting_job: 'Job started',
finish_job: 'Sent terminated',
error_job: 'Info Error',
statesub: 'Subscribed',
},
privacy_policy:'Privacy Policy',
cookies: 'We use cookies for better web performance.'
@@ -1210,6 +1436,9 @@ const msgglobal = {
usereventlist: 'Users Booking',
userlist: 'Users List',
tableslist: 'List of tables',
newsletter: 'Newsletter',
pages: 'Pages',
media: 'Medias',
},
manage: {
menu: 'Manage',
@@ -1224,6 +1453,7 @@ const msgglobal = {
write: 'write'
},
dialog: {
close: 'Close',
ok: 'Ok',
yes: 'Yes',
no: 'No',
@@ -1267,7 +1497,9 @@ const msgglobal = {
verify_email: 'Verify your email',
go_login: 'Back to Login',
incorrect_input: 'Incorrect input.',
link_sent: 'Now read your email and confirm registration'
link_sent: 'Now read your email and confirm registration',
title_unsubscribe: 'Disiscrizione alla newsletter',
title_unsubscribe_done: 'Disiscrizione completata correttamente',
}
}
},
@@ -1280,6 +1512,15 @@ const msgglobal = {
notregistered: 'You need first to SignUp before storing data',
loggati: 'User not logged in'
},
templemail: {
subject: 'Subject Email',
testoheadermail: 'Header Email',
content: 'Content',
img: 'Image 1',
img2: 'Image 2',
content2: 'Content 2',
options: 'Options',
},
reg: {
page_title: 'Registration',
incorso: 'Registration please wait...',
@@ -1317,6 +1558,7 @@ const msgglobal = {
},
op: {
qualification: 'Qualification',
usertelegram: 'Username Telegram',
disciplines: 'Disciplines',
certifications: 'Certifications',
intro: 'Introduction',
@@ -1350,6 +1592,7 @@ const msgglobal = {
undefined: 'undefined'
}
},
showbigmap: 'Show the largest map',
todo: {
titleprioritymenu: 'Priority:',
inserttop: 'Insert Task at the top',
@@ -1402,7 +1645,13 @@ const msgglobal = {
code: 'Id',
whereicon: 'Icon',
},
col: {
label: 'Etichetta',
value: 'Valore',
type: 'Tipo'
},
cal: {
num: 'Number',
booked: 'Booked',
booked_error: 'Reservation failed. Try again later',
sendmsg_error: 'Message not sent. Try again later',
@@ -1415,6 +1664,8 @@ const msgglobal = {
cancelederrorbooking: 'Cancellation unsuccessfully, try again later',
event: 'Event',
starttime: 'From',
nextevent: 'Next Event',
readall: 'Read All',
enddate: 'to',
endtime: 'to',
duration: 'Duration',
@@ -1431,12 +1682,13 @@ const msgglobal = {
selnumpeople: 'Participants',
selnumpeople_short: 'Num',
msgbooking: 'Message to send',
showinfo: 'Show Info',
bookingtextdefault: 'I book the event',
showpdf: 'Show PDF',
bookingtextdefault: 'I book for',
bookingtextdefault_of: 'of',
data: 'Date',
teachertitle: 'Teacher',
peoplebooked: 'Booked',
showlastschedule: 'See Full Schedule',
},
msgs: {
message: 'Messaggio',
@@ -1449,6 +1701,7 @@ const msgglobal = {
short_tit: 'Short Title',
title: 'Title',
details: 'Details',
bodytext: 'Event Text',
dateTimeStart: 'Date Start',
dateTimeEnd: 'Date End',
bgcolor: 'Background color',
@@ -1460,6 +1713,7 @@ const msgglobal = {
contribtype: 'Contribute Type',
price: 'Price',
askinfo: 'Ask for Info',
showpage: 'Show Page',
infoafterprice: 'Info after Price',
teacher: 'Teacher', // teacherid
teacher2: 'Teacher2', // teacherid2
@@ -1473,7 +1727,14 @@ const msgglobal = {
deleted: 'Deleted',
duplicate: 'Duplicate',
notempty: 'Field cannot be empty',
modified: 'Modified'
modified: 'Modified',
showinhome: 'Show in Home',
showinnewsletter: 'Show in the Newsletter',
color: 'Title Color',
},
disc: {
typol_code: 'Tipology Code',
order: 'Order',
},
newsletter: {
title: 'Would you like to receive our Newsletter?',
@@ -1487,7 +1748,28 @@ const msgglobal = {
typesomething: 'Please type something',
acceptlicense: 'I accept the license and terms',
license: 'You need to accept the license and terms first',
submitted: 'Subscribed'
submitted: 'Subscribed',
menu: 'Newsletter1',
template: 'Template Email',
sendemail: 'Send',
check: 'Check',
sent: 'Already Sent',
mailinglist: 'Mailing List',
settings: 'Settings',
serversettings: 'Server',
others: 'Others',
templemail: 'Templates Email',
datetoSent: 'DateTime Send',
activate: 'Activate',
numemail_tot: 'Email Total',
numemail_sent: 'Email Sent',
datestartJob: 'Start Job',
datefinishJob: 'End Job',
lastemailsent_Job: 'Last Sent',
starting_job: 'Job started',
finish_job: 'Sent terminated',
error_job: 'Info Error',
statesub: 'Subscribed',
},
privacy_policy:'Privacy Policy',
cookies: 'Wir verwenden Cookies für eine bessere Webleistung.'

View File

@@ -2,12 +2,12 @@ function geturl() {
const miaurl = document.location.href
if (miaurl.includes('test.')) {
return 'https://test.freeplanet.app/'
return 'https://test.associazioneshen.it/'
} else {
if (miaurl.includes('localhost')) {
return 'http://localhost:8080/'
} else {
return 'https://freeplanet.app/'
return 'https://associazioneshen.it/'
}
}
}
@@ -18,12 +18,12 @@ function getidtrack() {
if (miaurl.includes('test.') || miaurl.includes('localhost')) {
return '4c40a07bc88a9c50c9b70dc9c5cd8e2e'
} else {
return '9853abef079fc8330ab188a9cbf07a0c'
return 'ccfd6c90e17b6809f9717675764c3f5d' // Associazione Shen
}
}
var owa_baseUrl = geturl() + 'owa/';
let owa_baseUrl = geturl() + 'owa/';
if (owa_cmds)
var owa_cmds = [];
else
@@ -33,11 +33,11 @@ owa_cmds.push(['trackPageView']);
// owa_cmds.push(['trackClicks']);
(function () {
var _owa = document.createElement('script');
const _owa = document.createElement('script');
_owa.type = 'text/javascript';
_owa.async = true;
owa_baseUrl = ('https:' == document.location.protocol ? window.owa_baseSecUrl || owa_baseUrl.replace(/http:/, 'https:') : owa_baseUrl);
_owa.src = owa_baseUrl + 'modules/base/js/owa.tracker-combined-min.js';
var _owa_s = document.getElementsByTagName('script')[0];
const _owa_s = document.getElementsByTagName('script')[0];
_owa_s.parentNode.insertBefore(_owa, _owa_s);
}());

View File

@@ -51,7 +51,8 @@ export const removeAuthHeaders = () => {
async function Request(type: string, path: string, payload: any): Promise<Types.AxiosSuccess | Types.AxiosError> {
let ricevuto = false
try {
console.log('Axios Request', path, type, tools.notshowPwd(payload))
if (tools.isDebug())
console.log('Axios Request', path, type, tools.notshowPwd(payload))
let response: AxiosResponse
if (type === 'post' || type === 'put' || type === 'patch') {
response = await axiosInstance[type](path, payload, {

View File

@@ -1,4 +1,4 @@
import { ICfgServer, IConfig, IGlobalState, IListRoutes, IMenuList, StateConnection } from 'model'
import { ICfgServer, IConfig, IGlobalState, IListRoutes, IMenuList, ISettings, StateConnection } from 'model'
import { storeBuilder } from './Store/Store'
import Vue from 'vue'
@@ -24,6 +24,7 @@ import { serv_constants } from '@src/store/Modules/serv_constants'
import { IUserState } from '@src/model'
import { Calendar } from 'element-ui'
import { fieldsTable } from '@src/store/Modules/fieldsTable'
import router from '@router'
// import { static_data } from '@src/db/static_data'
let stateConnDefault = 'online'
@@ -68,7 +69,15 @@ const state: IGlobalState = {
type: 0,
_id: 0
},
settings: []
serv_settings: [],
templemail: [],
opzemail: [],
settings: [],
disciplines: [],
autoplaydisc: 8000,
newstosent: [],
mailinglist: [],
mypage: []
}
async function getConfig(id) {
@@ -124,6 +133,12 @@ namespace Getters {
}, 'showtype')
const getPage = b.read((mystate: IGlobalState) => (path) => {
// const config = state.arrConfig.find(item => item._id === cat + costanti.CONFIG_ID_SHOW_TYPE_TODOS)
return mystate.mypage.find((page) => (`/` + page.path) === path)
}, 'getPage')
const getmenu = b.read((state) => {
// console.log('getmenu', cfgrouter.getmenu())
@@ -163,6 +178,18 @@ namespace Getters {
return CalendarStore.state.wheres
else if (table === 'contribtype')
return CalendarStore.state.contribtype
else if (table === 'disciplines')
return GlobalStore.state.disciplines
else if (table === tools.TABNEWSLETTER)
return GlobalStore.state.newstosent
else if (table === tools.TABTEMPLEMAIL)
return GlobalStore.state.templemail
else if (table === tools.TABOPZEMAIL)
return GlobalStore.state.opzemail
else if (table === tools.TABMAILINGLIST)
return GlobalStore.state.mailinglist
else if (table === tools.TABMYPAGE)
return GlobalStore.state.mypage
else if (table === 'bookings')
return CalendarStore.state.bookedevent
else if (table === 'users')
@@ -178,13 +205,24 @@ namespace Getters {
}, 'getListByTable')
const getValueSettingsByKey = b.read((mystate: IGlobalState) => (key): any => {
const myrec = mystate.settings.find((rec) => rec.key === key)
const getrecSettingsByKey = b.read((mystate: IGlobalState) => (key, serv): ISettings => {
if (serv)
return mystate.serv_settings.find((rec) => rec.key === key)
else
return mystate.settings.find((rec) => rec.key === key)
}, 'getrecSettingsByKey')
const getValueSettingsByKey = b.read((mystate: IGlobalState) => (key, serv): any => {
const myrec = getters.getrecSettingsByKey(key, serv)
if (!!myrec) {
if (myrec.type === tools.FieldType.date)
return myrec.value_date
if (myrec.type === tools.FieldType.number)
else if (myrec.type === tools.FieldType.number)
return myrec.value_num
else if (myrec.type === tools.FieldType.boolean)
return myrec.value_bool
else
return myrec.value_str
} else {
@@ -193,6 +231,11 @@ namespace Getters {
}, 'getValueSettingsByKey')
const gettemplemailbyId = b.read((mystate: IGlobalState) => (templid): string => {
const myrec = mystate.templemail.find((rec) => rec._id === templid)
return (!!myrec) ? myrec.subject : ''
}, 'gettemplemailbyId')
export const getters = {
get testpao1_getter_contatore() {
return testpao1_getter_contatore()
@@ -236,6 +279,18 @@ namespace Getters {
return getValueSettingsByKey()
},
get getrecSettingsByKey() {
return getrecSettingsByKey()
},
get gettemplemailbyId() {
return gettemplemailbyId()
},
get getPage() {
return getPage()
},
get t() {
return t()
},
@@ -343,6 +398,31 @@ namespace Mutations {
}
}
function setValueSettingsByKey(mystate: IGlobalState, { key, value, serv }) {
// Update the Server
// Update in Memory
let myrec = null
if (serv)
myrec = mystate.serv_settings.find((rec) => rec.key === key)
else
myrec = mystate.settings.find((rec) => rec.key === key)
if (!!myrec) {
if (myrec.type === tools.FieldType.date)
myrec.value_date = value
else if (myrec.type === tools.FieldType.number)
myrec.value_num = value
else if (myrec.type === tools.FieldType.boolean)
myrec.value_bool = value
else
myrec.value_str = value
console.log('setValueSettingsByKey value', value, 'myrec', myrec)
}
}
export const mutations = {
setConta: b.commit(setConta),
setleftDrawerOpen: b.commit(setleftDrawerOpen),
@@ -354,7 +434,8 @@ namespace Mutations {
setPaoArray_Delete: b.commit(setPaoArray_Delete),
NewArray: b.commit(NewArray),
setShowType: b.commit(setShowType),
UpdateValuesInMemory: b.commit(UpdateValuesInMemory)
UpdateValuesInMemory: b.commit(UpdateValuesInMemory),
setValueSettingsByKey: b.commit(setValueSettingsByKey)
}
}
@@ -365,7 +446,6 @@ namespace Actions {
}
function createPushSubscription(context) {
console.log('createPushSubscription')
// If Already subscribed, don't send to the Server DB
// if (state.wasAlreadySubOnDb) {
@@ -384,7 +464,7 @@ namespace Actions {
return
}
// console.log('createPushSubscription')
console.log('createPushSubscription')
let reg
const mykey = process.env.PUBLICKEY_PUSH
@@ -676,12 +756,12 @@ namespace Actions {
async function loadSite(context) {
// console.log('CalendarStore: loadAfterLogin')
// Load local data
CalendarStore.state.editable = UserStore.state.isAdmin || UserStore.state.isManager
const showall = UserStore.state.isAdmin || UserStore.state.isManager ? '1' : '0'
const myuserid = (UserStore.state.my._id) ? UserStore.state.my._id : '0'
CalendarStore.state.editable = false
return await Api.SendReq('/loadsite/' + myuserid + '/' + process.env.APP_ID + '/' + showall, 'GET', null)
.then((res) => {
CalendarStore.state.bookedevent = (res.data.bookedevent) ? res.data.bookedevent : []
@@ -690,6 +770,15 @@ namespace Actions {
CalendarStore.state.wheres = (res.data.wheres) ? res.data.wheres : []
CalendarStore.state.contribtype = (res.data.contribtype) ? res.data.contribtype : []
GlobalStore.state.settings = (res.data.settings) ? [...res.data.settings] : []
GlobalStore.state.disciplines = (res.data.disciplines) ? [...res.data.disciplines] : []
if (showall) {
GlobalStore.state.newstosent = (res.data.newstosent) ? [...res.data.newstosent] : []
GlobalStore.state.mailinglist = (res.data.mailinglist) ? [...res.data.mailinglist] : []
GlobalStore.state.mypage = (res.data.mypage) ? [...res.data.mypage] : []
}
CalendarStore.state.editable = UserStore.state.isAdmin || UserStore.state.isManager
})
.catch((error) => {
@@ -700,6 +789,60 @@ namespace Actions {
}
async function sendEmailTest(context, { previewonly }) {
const usertosend = {
locale: tools.getLocale(),
previewonly
}
console.log(usertosend)
return await Api.SendReq('/news/testemail', 'POST', usertosend)
.then((res) => {
return res
})
}
async function addDynamicPages(context) {
const arrpagesroute: IListRoutes[] = []
for (const page of state.mypage) {
arrpagesroute.push({
path: '/' + page.path,
name: undefined,
text: page.title,
materialIcon: page.icon,
component: () => import('@/root/mypage/mypage.vue'),
inmenu: page.inmenu,
infooter: page.infooter,
level_child: page.l_child,
level_parent: page.l_par,
})
}
const last = {
path: '*',
materialIcon: 'fas fa-calendar-plus',
name: 'otherpages.error404def',
component: () => import('@/root/My404page/My404page.vue'),
inmenu: false,
infooter: false
}
static_data.routes = [...static_data.routes, ...arrpagesroute, last]
router.addRoutes([...arrpagesroute, last])
}
async function sendFile(context, formdata) {
try {
const { data } = await Api.postFormData('/upload', formdata)
console.log(data)
} catch (e) {
console.log('Error sendFile: ', e)
}
}
export const actions = {
setConta: b.dispatch(setConta),
createPushSubscription: b.dispatch(createPushSubscription),
@@ -714,7 +857,9 @@ namespace Actions {
loadTable: b.dispatch(loadTable),
saveTable: b.dispatch(saveTable),
DeleteRec: b.dispatch(DeleteRec),
DuplicateRec: b.dispatch(DuplicateRec)
sendEmailTest: b.dispatch(sendEmailTest),
DuplicateRec: b.dispatch(DuplicateRec),
addDynamicPages: b.dispatch(addDynamicPages)
}
}

View File

@@ -419,6 +419,57 @@ namespace Actions {
})
}
async function unsubscribe(context, paramquery) {
return await Api.SendReq('/news/unsubscribe', 'POST', paramquery)
.then((res) => {
// console.log("RITORNO 2 ");
// mutations.setServerCode(myres);
if (res.data.code === serv_constants.RIS_UNSUBSCRIBED_OK) {
console.log('DESOTTOSCRITTO ALLA NEWSLETTER !!')
} else {
console.log('Risultato di unsubscribe: ', res.data.code)
}
return { code: res.data.code, msg: res.data.msg }
}).catch((error) => {
return UserStore.getters.getServerCode
})
}
async function importemail(context, paramquery) {
return await Api.SendReq('/news/import', 'POST', paramquery)
.then((res) => {
// console.log("RITORNO 2 ");
// mutations.setServerCode(myres);
return res
}).catch((error) => {
return { numtot: 0, numadded: 0, numalreadyexisted: 0}
})
}
async function newsletterload(context, paramquery) {
return await Api.SendReq('/news/load', 'POST', paramquery)
.then((res) => {
console.log('res', res)
return res.data
}).catch((error) => {
return null
})
}
async function newsletter_setactivate(context, paramquery) {
return await Api.SendReq('/news/setactivate', 'POST', paramquery)
.then((res) => {
console.log('res', res)
return res.data
}).catch((error) => {
return null
})
}
async function signup(context, authData: ISignupOptions) {
console.log('SIGNUP')
@@ -637,28 +688,42 @@ namespace Actions {
async function setGlobal(isLogged: boolean) {
console.log('setGlobal')
// state.isLogged = true
if (isLogged) {
// console.log('state.isLogged', state.isLogged)
try {
// state.isLogged = true
if (isLogged) {
// console.log('state.isLogged', state.isLogged)
GlobalStore.mutations.setleftDrawerOpen(localStorage.getItem(tools.localStorage.leftDrawerOpen) === 'true')
GlobalStore.mutations.setCategorySel(localStorage.getItem(tools.localStorage.categorySel))
GlobalStore.mutations.setleftDrawerOpen(localStorage.getItem(tools.localStorage.leftDrawerOpen) === 'true')
GlobalStore.mutations.setCategorySel(localStorage.getItem(tools.localStorage.categorySel))
GlobalStore.actions.checkUpdates()
GlobalStore.actions.checkUpdates()
}
const p3 = await GlobalStore.actions.loadAfterLogin()
state.isLogged = isLogged
if (static_data.functionality.ENABLE_TODOS_LOADING)
await Todos.actions.dbLoad({ checkPending: true })
if (static_data.functionality.ENABLE_PROJECTS_LOADING)
await Projects.actions.dbLoad({ checkPending: true, onlyiffirsttime: true })
console.log('add routes')
GlobalStore.actions.addDynamicPages()
GlobalStore.state.finishLoading = true
if (tools.isDebug())
console.log('finishLoading', GlobalStore.state.finishLoading)
// document.dispatchEvent(new Event('custom-post-render-event'))
} catch (e) {
console.error('Error', e)
GlobalStore.state.finishLoading = true
}
const p3 = await GlobalStore.actions.loadAfterLogin()
state.isLogged = isLogged
if (static_data.functionality.ENABLE_TODOS_LOADING)
await Todos.actions.dbLoad({ checkPending: true })
if (static_data.functionality.ENABLE_PROJECTS_LOADING)
await Projects.actions.dbLoad({ checkPending: true, onlyiffirsttime: true })
GlobalStore.state.finishLoading = true
return true
// console.log('setGlobal: END')
}
@@ -740,7 +805,11 @@ namespace Actions {
resetpwd: b.dispatch(resetpwd),
signin: b.dispatch(signin),
signup: b.dispatch(signup),
vreg: b.dispatch(vreg)
vreg: b.dispatch(vreg),
unsubscribe: b.dispatch(unsubscribe),
importemail: b.dispatch(importemail),
newsletterload: b.dispatch(newsletterload),
newsletter_setactivate: b.dispatch(newsletter_setactivate),
}
}

View File

@@ -2,7 +2,7 @@ import { IColGridTable } from '../../model'
import { lists } from './lists'
import { tools } from '@src/store/Modules/tools'
import { shared_consts } from '@src/common/shared_vuejs'
import { GlobalStore } from '@store'
import { GlobalStore, UserStore } from '@store'
const DeleteRec = {
name: 'deleterec',
@@ -17,6 +17,19 @@ const DeleteRec = {
visuonlyEditVal: true
}
const DuplicateRec = {
name: 'copyrec',
label_trans: 'event.duplicate',
align: 'right',
field: tools.NOFIELD,
sortable: false,
icon: 'fas fa-copy',
action: lists.MenuAction.DUPLICATE_RECTABLE,
askaction: 'db.duplicatedrecord',
visuonlyEditVal: true,
visible: true
}
function AddCol(params: IColGridTable) {
return {
name: params.name,
@@ -40,9 +53,78 @@ function AddCol(params: IColGridTable) {
}
}
export const colmailinglist = [
AddCol({ name: 'name', label_trans: 'reg.name' }),
AddCol({ name: 'surname', label_trans: 'reg.surname' }),
AddCol({ name: 'email', label_trans: 'reg.email' }),
AddCol({ name: 'statesub', label_trans: 'newsletter.statesub', fieldtype: tools.FieldType.boolean }),
AddCol({ name: 'lastid_newstosent', label_trans: 'reg.lastid_newstosent', fieldtype: tools.FieldType.string }),
AddCol(DeleteRec)
]
export const colmypage = [
AddCol({ name: 'title', label_trans: 'pages.title' }),
AddCol({ name: 'path', label_trans: 'pages.path' }),
AddCol({ name: 'icon', label_trans: 'pages.icon' }),
AddCol({ name: 'keywords', label_trans: 'pages.keywords' }),
AddCol({ name: 'description', label_trans: 'pages.description' }),
AddCol({ name: 'heightimg', label_trans: 'pages.heightimg', fieldtype: tools.FieldType.number }),
AddCol({ name: 'imgback', label_trans: 'pages.imgback', fieldtype: tools.FieldType.string }),
AddCol({ name: 'content', label_trans: 'pages.content', fieldtype: tools.FieldType.html }),
AddCol({ name: 'active', label_trans: 'pages.active', fieldtype: tools.FieldType.boolean }),
AddCol({ name: 'inmenu', label_trans: 'pages.inmenu', fieldtype: tools.FieldType.boolean }),
AddCol({ name: 'submenu', label_trans: 'pages.submenu', fieldtype: tools.FieldType.boolean }),
AddCol({ name: 'l_par', label_trans: 'pages.l_par', fieldtype: tools.FieldType.number }),
AddCol({ name: 'l_child', label_trans: 'pages.l_child', fieldtype: tools.FieldType.number }),
AddCol({ name: 'infooter', label_trans: 'pages.infooter', fieldtype: tools.FieldType.boolean }),
AddCol(DeleteRec),
AddCol(DuplicateRec)
]
export const colopzemail = [
AddCol({ name: 'key', label_trans: 'col.key' }),
AddCol({ name: 'label_it', label_trans: 'col.label' }),
AddCol(DeleteRec),
AddCol(DuplicateRec)
]
export const coltemplemail = [
AddCol({ name: 'subject', label_trans: 'templemail.subject' }),
AddCol({ name: 'testoheadermail', label_trans: 'templemail.testoheadermail', fieldtype: tools.FieldType.html }),
AddCol({ name: 'content', label_trans: 'templemail.content', fieldtype: tools.FieldType.html }),
AddCol({ name: 'img', label_trans: 'templemail.img' }),
AddCol({ name: 'content2', label_trans: 'templemail.content2', fieldtype: tools.FieldType.html }),
AddCol({ name: 'img2', label_trans: 'templemail.img2' }),
AddCol({
name: 'options',
label_trans: 'templemail.options',
fieldtype: tools.FieldType.multiselect,
jointable: 'opzemail'
}),
AddCol(DeleteRec),
AddCol(DuplicateRec)
]
// SHOW_LAST_N_EV
export const colnewstosent = [
AddCol({ name: 'label', label_trans: 'event.title' }),
AddCol({ name: 'templemail_str', label_trans: 'newsletter.templemail' }),
AddCol({ name: 'datetoSent', label_trans: 'newsletter.datetoSent', fieldtype: tools.FieldType.date }),
AddCol({ name: 'activate', label_trans: 'newsletter.activate', fieldtype: tools.FieldType.boolean }),
AddCol({ name: 'numemail_tot', label_trans: 'newsletter.numemail_tot', fieldtype: tools.FieldType.number }),
AddCol({ name: 'numemail_sent', label_trans: 'newsletter.numemail_sent', fieldtype: tools.FieldType.number }),
AddCol({ name: 'datestartJob', label_trans: 'newsletter.datestartJob', fieldtype: tools.FieldType.date }),
AddCol({ name: 'datefinishJob', label_trans: 'newsletter.datefinishJob', fieldtype: tools.FieldType.date }),
AddCol({ name: 'lastemailsent_Job', label_trans: 'newsletter.lastemailsent_Job', fieldtype: tools.FieldType.date }),
AddCol({ name: 'starting_job', label_trans: 'newsletter.starting_job', fieldtype: tools.FieldType.boolean }),
AddCol({ name: 'finish_job', label_trans: 'newsletter.finish_job', fieldtype: tools.FieldType.boolean }),
AddCol({ name: 'error_job', label_trans: 'newsletter.error_job', fieldtype: tools.FieldType.string }),
AddCol(DeleteRec),
AddCol(DuplicateRec)
]
const colTableWhere = [
AddCol({ name: 'code', label_trans: 'where.code' }),
AddCol({ name: 'placename', label_trans: 'cal.where'} ),
AddCol({ name: 'placename', label_trans: 'cal.where' }),
AddCol({ name: 'whereicon', label_trans: 'where.whereicon' }),
AddCol(DeleteRec)
]
@@ -53,13 +135,26 @@ const colcontribtype = [
AddCol(DeleteRec)
]
const colsettings = [
AddCol({ name: 'key', label_trans: 'col.label' }),
AddCol({ name: 'type', label_trans: 'col.type', fieldtype: tools.FieldType.select, jointable: 'fieldstype' }),
AddCol({ name: 'value_str', label_trans: 'col.value', fieldtype: tools.FieldType.string }),
AddCol({ name: 'value_date', label_trans: 'cal.data', fieldtype: tools.FieldType.date }),
AddCol({ name: 'value_num', label_trans: 'cal.num', fieldtype: tools.FieldType.number }),
AddCol(DeleteRec)
const coldisciplines = [
AddCol({ name: 'typol_code', label_trans: 'disc.typol_code' }),
AddCol({ name: 'order', label_trans: 'disc.order', fieldtype: tools.FieldType.number }),
AddCol({ name: 'label', label_trans: 'event.title' }),
AddCol({ name: 'description', label_trans: 'proj.longdescr' }),
AddCol({ name: 'linkpage', label_trans: 'event.linkpage' }),
AddCol({ name: 'color', label_trans: 'event.color' }),
AddCol({ name: 'icon', label_trans: 'event.icon' }),
AddCol({ name: 'img', label_trans: 'event.img' }),
AddCol({ name: 'img_small', label_trans: 'event.img_small' }),
AddCol({ name: 'showinhome', label_trans: 'event.showinhome', fieldtype: tools.FieldType.boolean }),
AddCol({ name: 'showinnewsletter', label_trans: 'event.showinnewsletter', fieldtype: tools.FieldType.boolean }),
AddCol({
name: 'teachers',
label_trans: 'event.teacher',
fieldtype: tools.FieldType.multiselect,
jointable: 'operators'
}),
AddCol(DeleteRec),
AddCol(DuplicateRec)
]
const colTablePermission = [
@@ -68,6 +163,7 @@ const colTablePermission = [
AddCol(DeleteRec)
]
const colTableOperator = [
AddCol({ name: 'username', label_trans: 'reg.username' }),
AddCol({ name: 'name', label_trans: 'reg.name' }),
@@ -75,22 +171,26 @@ const colTableOperator = [
AddCol({ name: 'email', label_trans: 'reg.email' }),
AddCol({ name: 'img', label_trans: 'event.img' }),
AddCol({ name: 'cell', label_trans: 'reg.cell' }),
AddCol({ name: 'usertelegram', label_trans: 'op.usertelegram' }),
AddCol({ name: 'qualification', label_trans: 'op.qualification' }),
AddCol({ name: 'disciplines', label_trans: 'op.disciplines' }),
AddCol({ name: 'certifications', label_trans: 'op.certifications' }),
AddCol({ name: 'intro', label_trans: 'op.intro' , fieldtype: tools.FieldType.html }),
AddCol({ name: 'intro', label_trans: 'op.intro', fieldtype: tools.FieldType.html }),
AddCol({ name: 'info', label_trans: 'op.info', fieldtype: tools.FieldType.html }),
AddCol({ name: 'webpage', label_trans: 'op.webpage' }),
AddCol({ name: 'days_working', label_trans: 'op.days_working' }),
AddCol({ name: 'facebook', label_trans: 'op.facebook' }),
AddCol(DeleteRec)]
AddCol(DeleteRec),
AddCol(DuplicateRec)
]
const colTableEvents = [
AddCol({ name: '_id', label_trans: 'event._id' }),
AddCol({ name: 'typol', label_trans: 'event.typol' }),
AddCol({ name: 'typol', label_trans: 'event.typol', fieldtype: tools.FieldType.select, jointable: 'disciplines' }),
AddCol({ name: 'short_tit', label_trans: 'event.short_tit' }),
AddCol({ name: 'title', label_trans: 'event.title' }),
AddCol({ name: 'details', label_trans: 'event.details' }),
AddCol({ name: 'details', label_trans: 'event.details', fieldtype: tools.FieldType.html }),
AddCol({ name: 'bodytext', label_trans: 'event.bodytext', fieldtype: tools.FieldType.html }),
AddCol({ name: 'dateTimeStart', label_trans: 'event.dateTimeStart', fieldtype: tools.FieldType.date }),
AddCol({ name: 'dateTimeEnd', label_trans: 'event.dateTimeEnd', fieldtype: tools.FieldType.date }),
AddCol({ name: 'bgcolor', label_trans: 'event.bgcolor' }),
@@ -98,11 +198,21 @@ const colTableEvents = [
AddCol({ name: 'img_small', label_trans: 'event.img_small' }),
AddCol({ name: 'img', label_trans: 'event.img' }),
AddCol({ name: 'wherecode', label_trans: 'event.where', fieldtype: tools.FieldType.select, jointable: 'wheres' }),
AddCol({ name: 'contribtype', label_trans: 'event.contribtype', fieldtype: tools.FieldType.select, jointable: 'contribtype' }),
AddCol({
name: 'contribtype',
label_trans: 'event.contribtype',
fieldtype: tools.FieldType.select,
jointable: 'contribtype'
}),
AddCol({ name: 'price', label_trans: 'event.price' }),
AddCol({ name: 'infoafterprice', label_trans: 'event.infoafterprice' }),
AddCol({ name: 'teacher', label_trans: 'event.teacher', fieldtype: tools.FieldType.select, jointable: 'operators' }),
AddCol({ name: 'teacher2', label_trans: 'event.teacher2', fieldtype: tools.FieldType.select, jointable: 'operators' }),
AddCol({
name: 'teacher2',
label_trans: 'event.teacher2',
fieldtype: tools.FieldType.select,
jointable: 'operators'
}),
AddCol({ name: 'infoextra', label_trans: 'event.infoextra' }),
AddCol({ name: 'linkpage', label_trans: 'event.linkpage' }),
AddCol({ name: 'linkpdf', label_trans: 'event.linkpdf' }),
@@ -113,21 +223,24 @@ const colTableEvents = [
AddCol({ name: 'dupId', label_trans: 'event.dupId' }),
AddCol({ name: 'modified', label_trans: 'event.modified', fieldtype: tools.FieldType.boolean }),
AddCol(DeleteRec),
AddCol({
name: 'copyrec',
label_trans: 'event.duplicate',
align: 'right',
field: tools.NOFIELD,
sortable: false,
icon: 'fas fa-copy',
action: lists.MenuAction.DUPLICATE_RECTABLE,
askaction: 'db.duplicatedrecord',
visuonlyEditVal: true,
required: true,
visible: true
})
AddCol(DuplicateRec)
]
export const fields = {
colSettings: [
AddCol({ name: 'key', label_trans: 'col.label' }),
AddCol({ name: 'type', label_trans: 'col.type', fieldtype: tools.FieldType.select, jointable: 'fieldstype' }),
AddCol({ name: 'value_str', label_trans: 'col.value', fieldtype: tools.FieldType.string }),
AddCol({ name: 'value_date', label_trans: 'cal.data', fieldtype: tools.FieldType.date }),
AddCol({ name: 'value_num', label_trans: 'cal.num', fieldtype: tools.FieldType.number }),
AddCol({ name: 'value_bool', label_trans: 'cal.bool', fieldtype: tools.FieldType.boolean }),
AddCol({ name: 'serv', label_trans: 'cal.serv', fieldtype: tools.FieldType.boolean }),
AddCol(DeleteRec),
AddCol(DuplicateRec)
]
}
export const fieldsTable = {
getArrStrByValueBinary(mythis, col: IColGridTable, val) {
const arr = this.getArrByValueBinary(mythis, col, val)
@@ -175,6 +288,32 @@ export const fieldsTable = {
}
},
getMultiValueByTable(col: IColGridTable, arrval) {
if (col.jointable) {
const mylist = this.getTableJoinByName(col.jointable)
const key = this.getKeyByTable(col.jointable)
const collab = this.getLabelByTable(col.jointable)
// console.table(mylist)
// console.log('key=', key, 'collab', collab, 'val', val)
const myris = mylist.filter((myrec) => arrval.includes(myrec[key]))
// console.log('myris', myris)
if (myris) {
console.log('collab', collab)
if (tools.isObject(collab))
return myris.map(collab)
else
return myris.map((rec) => rec[collab])
} else {
return ''
}
} else {
return ''
}
},
getColByTable(table) {
if (table === 'permissions') {
return ['value', 'label']
@@ -206,6 +345,10 @@ export const fieldsTable = {
else
return 'label'
},
getTitleByTable(mytable): string {
const myrec = this.getrecTableList(mytable)
return myrec.label
},
getIconByTable(mytable): string {
const myrec = this.getrecTableList(mytable)
if (myrec)
@@ -213,13 +356,30 @@ export const fieldsTable = {
else
return ''
},
// IColGridTable
colTableUsers: [
AddCol({ name: 'username', label_trans: 'reg.username' }),
AddCol({ name: 'name', label_trans: 'reg.name' }),
AddCol({ name: 'surname', label_trans: 'reg.surname' }),
AddCol({ name: 'email', label_trans: 'reg.email' }),
AddCol({ name: 'cell', label_trans: 'reg.cell' }),
AddCol({ name: 'profile.img', field: 'profile', subfield: 'img', label_trans: 'reg.img', sortable: false }),
AddCol({ name: 'date_reg', label_trans: 'reg.date_reg', fieldtype: tools.FieldType.date }),
AddCol({ name: 'perm', label_trans: 'reg.perm', fieldtype: tools.FieldType.binary, jointable: 'permissions' }),
AddCol(DeleteRec)
],
tablesList: [
{
value: 'operators',
label: 'Insegnanti',
columns: colTableOperator,
colkey: 'username',
collabel: 'username'
collabel: (rec) => rec.name + ' ' + rec.surname
},
{
value: 'wheres',
@@ -242,51 +402,73 @@ export const fieldsTable = {
colkey: '_id',
collabel: 'label'
},
{
value: 'disciplines',
label: 'Discipline',
columns: coldisciplines,
colkey: 'typol_code',
collabel: 'label'
},
{
value: 'newstosent',
label: 'Newsletter da Inviare',
columns: colnewstosent,
colkey: '_id',
collabel: 'label',
onlyAdmin: true
},
{
value: 'templemail',
label: 'Template Email',
columns: coltemplemail,
colkey: '_id',
collabel: 'subject',
onlyAdmin: true
},
{
value: 'opzemail',
label: 'Opzioni Email',
columns: colopzemail,
colkey: 'key',
collabel: (rec) => rec.label_it,
onlyAdmin: true
},
{
value: 'mailinglist',
label: 'MailingList',
columns: colmailinglist,
colkey: '_id',
collabel: (rec) => rec.name + ' ' + rec.surname
},
{
value: 'permissions',
label: 'Permessi',
columns: colTablePermission,
colkey: 'value',
collabel: 'label',
colicon: 'icon'
colicon: 'icon',
noshow: true,
},
{
value: 'fieldstype',
label: 'Tipi di Campi',
colkey: 'value',
collabel: 'label'
collabel: 'label',
noshow: true,
},
{
value: 'settings',
label: 'Impostazioni',
columns: colsettings,
columns: fields.colSettings,
colkey: 'key',
collabel: 'key'
},
],
// IColGridTable
colTableUsers: [
AddCol({ name: 'username', label_trans: 'reg.username' }),
AddCol({ name: 'name', label_trans: 'reg.name' }),
AddCol({ name: 'surname', label_trans: 'reg.surname' }),
AddCol({ name: 'email', label_trans: 'reg.email' }),
AddCol({ name: 'cell', label_trans: 'reg.cell' }),
AddCol({ name: 'profile.img', field: 'profile', subfield: 'img', label_trans: 'reg.img', sortable: false }),
AddCol({ name: 'date_reg', label_trans: 'reg.date_reg', fieldtype: tools.FieldType.date }),
AddCol({ name: 'perm', label_trans: 'reg.perm', fieldtype: tools.FieldType.binary, jointable: 'permissions' }),
AddCol(DeleteRec),
AddCol({
name: 'copyrec',
label_trans: 'event.duplicate',
align: 'right',
field: tools.NOFIELD,
sortable: false,
icon: 'fas fa-copy',
action: lists.MenuAction.DUPLICATE_RECTABLE,
askaction: 'db.duplicatedrecord',
visuonlyEditVal: true,
visible: true
})
}
]
}
export const func = {
gettablesList() {
return fieldsTable.tablesList.filter((rec) => (rec.onlyAdmin === UserStore.state.isAdmin) || (!rec.onlyAdmin) && (!rec.noshow))
}
}

View File

@@ -5,18 +5,22 @@ export const serv_constants = {
RIS_CODE_ERR: -99,
RIS_CODE_EMAIL_ALREADY_VERIFIED: -5,
RIS_CODE_EMAIL_VERIFIED: 1,
RIS_CODE_ERR_UNAUTHORIZED: -30,
RIS_CODE_LOGIN_ERR_GENERIC: -20,
RIS_CODE_LOGIN_ERR_GENERIC: -20,
RIS_CODE_LOGIN_ERR: -10,
RIS_CODE_OK: 1,
RIS_CODE_LOGIN_OK: 1,
RIS_CODE__HTTP_FORBIDDEN_INVALID_TOKEN: 403,
RIS_SUBSCRIBED_OK: 1,
RIS_SUBSCRIBED_ALREADYEXIST: 2,
RIS_SUBSCRIBED_ERR: -1
RIS_SUBSCRIBED_ERR: -1,
RIS_SUBSCRIBED_STR: 'subscribed',
RIS_UNSUBSCRIBED_OK: 5,
RIS_UNSUBSCRIBED_STR: 'unsubscribed',
RIS_UNSUBSCRIBED_NOT_EXIST: -5,
}

View File

@@ -5,6 +5,7 @@ import { toolsext } from './toolsext'
import { translation } from './translation'
import Quasar, { colors, date, Screen } from 'quasar'
import { scroll } from 'quasar'
const { getScrollTarget, setScrollPosition } = scroll
import {
@@ -64,6 +65,11 @@ export const tools = {
],
TABEVENTS: 'myevents',
TABNEWSLETTER: 'newstosent',
TABMAILINGLIST: 'mailinglist',
TABMYPAGE: 'mypage',
TABTEMPLEMAIL: 'templemail',
TABOPZEMAIL: 'opzemail',
MAX_CHARACTERS: 60,
projects: 'projects',
@@ -131,6 +137,8 @@ export const tools = {
select: 32,
number: 64,
typeinrec: 128,
multiselect: 256,
password: 512,
},
FieldTypeArr: [
@@ -1371,6 +1379,11 @@ export const tools = {
return result
},
visumenu(elem) { // : IListRoutes
return (elem.onlyAdmin && UserStore.state.isAdmin) || (elem.onlyManager && UserStore.state.isManager)
|| ((!elem.onlyAdmin) && (!elem.onlyManager))
},
executefunc(myself: any, table, func: number, par: IParamDialog) {
if (func === lists.MenuAction.DELETE) {
console.log('param1', par.param1)
@@ -1724,6 +1737,62 @@ export const tools = {
return ''
},
getstrShortDate(mydate) {
const DateFormatter = new Intl.DateTimeFormat(func_tools.getLocale() || void 0, {
weekday: 'long',
day: 'numeric',
month: 'short',
year: 'numeric'
// timeZone: 'UTC'
})
try {
if (DateFormatter) {
const date1 = new Date(mydate)
return DateFormatter.format(date1)
}
return mydate
} catch (e) {
return ''
}
},
getstrVeryShortDate(mydate) {
const DateFormatter = new Intl.DateTimeFormat(func_tools.getLocale() || void 0, {
weekday: 'short',
day: 'numeric',
month: 'short',
// timeZone: 'UTC'
})
try {
if (DateFormatter) {
const date1 = new Date(mydate)
return DateFormatter.format(date1)
}
return mydate
} catch (e) {
return ''
}
},
getstrVeryVeryShortDate(mydate) {
const DateFormatter = new Intl.DateTimeFormat(func_tools.getLocale() || void 0, {
weekday: 'long',
day: 'numeric',
// timeZone: 'UTC'
})
try {
if (DateFormatter) {
const date1 = new Date(mydate)
return DateFormatter.format(date1)
}
return mydate
} catch (e) {
return ''
}
},
getstrDateTimeEvent(mythis, myevent, withhtml) {
let mystr = ''
// is same day?
@@ -1741,7 +1810,7 @@ export const tools = {
mystr = `<span class="cal__where-content">${tools.getstrDate(myevent.dateTimeStart)}</span>
<span class="cal__hours-content">${mythis.$t('cal.starttime')} ${ tools.getstrTime(myevent.dateTimeStart) } </span>
${ mythis.$t('cal.enddate')} ${tools.getstrDate(myevent.dateTimeEnd)}
<span class="cal__hours-content">${ mythis.$t('cal.endtime')}: ${ tools.getstrTime(myevent.dateTimeEnd) } </span>`
<span class="cal__hours-content">${ mythis.$t('cal.endtime')} ${ tools.getstrTime(myevent.dateTimeEnd) } </span>`
}
if (myevent.infoextra) {
@@ -1754,6 +1823,34 @@ export const tools = {
return mystr
},
getstrDateTimeEventSimple(mythis, myevent) {
let mystr = ''
// is same day?
if (tools.getstrShortDate(myevent.dateTimeStart) === tools.getstrShortDate(myevent.dateTimeEnd)) {
mystr = `${tools.getstrShortDate(myevent.dateTimeStart)}
- ${ tools.getstrTime(myevent.dateTimeStart) }`
} else {
mystr = `${tools.getstrVeryVeryShortDate(myevent.dateTimeStart)} - ${ tools.getstrShortDate(myevent.dateTimeEnd) }`
}
return mystr
},
getstrDateTimeEventShort(mythis, myevent) {
let mystr = ''
// is same day?
if (tools.getstrShortDate(myevent.dateTimeStart) === tools.getstrShortDate(myevent.dateTimeEnd)) {
mystr = `${tools.getstrVeryShortDate(myevent.dateTimeStart)}
h. ${ tools.getstrTime(myevent.dateTimeStart) }`
} else {
mystr = `${tools.getstrVeryShortDate(myevent.dateTimeStart)} - ${ tools.getstrVeryShortDate(myevent.dateTimeEnd) }`
}
return mystr
},
getstrDateTime(mytimestamp) {
// console.log('getstrDate', mytimestamp)
if (!!mytimestamp)
@@ -1762,6 +1859,22 @@ export const tools = {
return ''
},
getstrDateTimeAll(mytimestamp) {
// console.log('getstrDate', mytimestamp)
if (!!mytimestamp)
return date.formatDate(mytimestamp, 'DD/MM/YYYY HH:mm:ss')
else
return ''
},
getstrTimeAll(mytimestamp) {
// console.log('getstrDate', mytimestamp)
if (!!mytimestamp)
return date.formatDate(mytimestamp, 'HH:mm:ss')
else
return ''
},
getstrDateTimeShort(mytimestamp) {
// console.log('getstrDate', mytimestamp)
if (!!mytimestamp)
@@ -1812,7 +1925,7 @@ export const tools = {
} else {
return null
}
console.log('mystrdate', mystrdate, strdate, mydate)
// console.log('mystrdate', mystrdate, strdate, mydate)
return mydate
}
,
@@ -1844,8 +1957,10 @@ export const tools = {
getDateNow() {
const mydate = new Date()
return mydate
}
,
},
getDateNowEvent() {
return tools.addDays(tools.getDateNow(), -1)
},
getDateNull() {
return new Date(0)
}
@@ -2078,8 +2193,7 @@ export const tools = {
} else {
return '500'
}
}
,
},
styles_imgtitle(sized ?: string) {
if (!!sized) {
@@ -2277,6 +2391,15 @@ export const tools = {
},
getimgev(ev) {
if (!!ev.img_small)
return `statics/` + ev.img_small
else if (!!ev.img)
return `statics/` + ev.img
else
return ''
},
getimgbysize(dir: string, file: string) {
const myimage = dir + file
// console.log('includes = ', static_data.preLoadImages.map((a) => a.imgname).includes(myimage), myimage)
@@ -2292,6 +2415,15 @@ export const tools = {
return ris
},
getaltimg(dir: string, file: string, alt?: string) {
const myimage = dir + file
const myrec = static_data.preLoadImages.find((rec) => rec.imgname === myimage)
if (myrec)
return (myrec) ? myrec.alt : 'my image'
else
return alt
},
getimgFullpathbysize(fileimg: string) {
const ind = fileimg.lastIndexOf('/')
if (ind > 0) {
@@ -2502,7 +2634,7 @@ export const tools = {
const mydata = {
table,
data
data,
}
return await
@@ -2522,7 +2654,38 @@ export const tools = {
},
getwidth(mythis) {
// return height()
return mythis.$q.screen.width
let myw = mythis.$q.screen.width
if (GlobalStore.state.leftDrawerOpen)
myw -= 300
// if (GlobalStore.state.RightDrawerOpen)
// myw -= 300
return myw
},
getwidthscale(mythis, mywidth, maxwidth) {
if (this.isMobile()) {
if (mywidth > this.getwidth(mythis) - 20)
mywidth = this.getwidth(mythis) - 20
return mywidth
} else {
// console.log('this.getwidth(mythis) = ', this.getwidth(mythis))
let myw = mywidth + ((this.getwidth(mythis) - mywidth) * 0.6)
// console.log('myw1 = ', myw)
if (myw > maxwidth)
myw = maxwidth
if (myw > this.getwidth(mythis) - 20)
myw = this.getwidth(mythis) - 20
// console.log('myw = ', myw)
return myw
}
},
getheightbywidth(mythis, mywidth, myheight, maxwidth) {
const myw = this.getwidthscale(mythis, mywidth, maxwidth)
return myw * (myheight / mywidth)
},
isIsoDate(str) {
@@ -2566,13 +2729,13 @@ export const tools = {
else
return 'primary'
},
getCookie(mytok, oldval?) {
getCookie(mytok, def?) {
const ris = Cookies.get(mytok)
console.log('getCookie', ris)
if (!!ris) {
return ris
} else {
return oldval
return def
}
},
@@ -2610,8 +2773,10 @@ export const tools = {
setScrollPosition(target, offset, duration)
},
getCellForWhatsapp(numbercell) {
if (!numbercell)
return ''
let mynum = numbercell.replace(/\-/g, '')
const intcode = GlobalStore.getters.getValueSettingsByKey('INT_CODE')
const intcode = GlobalStore.getters.getValueSettingsByKey('INT_CODE', false)
if (numbercell.substring(0, 1) !== '+')
mynum = intcode + mynum
else
@@ -2621,12 +2786,46 @@ export const tools = {
},
getHttpForWhatsapp(numbercell) {
if (!numbercell)
return ''
const mynum = this.getCellForWhatsapp(numbercell)
if (mynum)
return 'https://wa.me/' + mynum
else
return ''
}
},
getHttpForTelegram(usertelegram) {
if (usertelegram)
return 'https://t.me/' + usertelegram
else
return ''
},
metafunc(mythis) {
return {
title: mythis.$t('msg.myAppName'),
titleTemplate: (title) => `${mythis.mymeta.title} - ${mythis.$t('msg.myAppName')}`,
meta: {
keywords: {
name: 'keywords',
content: mythis.mymeta.keywords
},
description: {
name: 'description',
content: mythis.mymeta.description
},
equiv: { 'http-equiv': 'Content-Type', 'content': 'text/html; charset=UTF-8' }
}
}
},
isObject(anything) {
//Object.create(null) instanceof Object → false
return Object(anything) === anything
},
isDebug() {
return process.env.DEV
},
// getLocale() {
// if (navigator.languages && navigator.languages.length > 0) {

View File

@@ -5,4 +5,3 @@ declare module 'vue/types/vue' {
$axios: axios
}
}

View File

@@ -5,4 +5,3 @@ declare module 'vue/types/vue' {
$globalroutines: globalroutines
}
}

View File

@@ -3,7 +3,6 @@ import { Component } from 'vue-property-decorator'
import { GlobalStore, UserStore } from '@store'
@Component({})
export default class TableOnlyView extends Vue {
public loading: boolean = false
@@ -28,8 +27,7 @@ export default class TableOnlyView extends Vue {
public filter: string = ''
public selected: any[] = []
request(props) {
public request(props) {
this.loading = true
setTimeout(() => {
this.serverPagination = props.pagination
@@ -53,7 +51,7 @@ export default class TableOnlyView extends Vue {
}, 1500)
}
mounted() {
public mounted() {
this.request({
pagination: this.serverPagination,
filter: this.filter

View File

@@ -52,7 +52,7 @@ export default class CfgServer extends Vue {
}
public SaveValue(newVal, valinitial) {
console.log('SaveValue', newVal, 'selected', this.selected)
// console.log('SaveValue', newVal, 'selected', this.selected)
const mydata = {
chiave: this.keysel,

Some files were not shown because too many files have changed in this diff Show More