First Committ

This commit is contained in:
Paolo Arena
2021-08-31 18:09:59 +02:00
commit 1d6c55807c
299 changed files with 55382 additions and 0 deletions

4
src/components/.directory Executable file
View File

@@ -0,0 +1,4 @@
[Dolphin]
Timestamp=2019,10,10,16,45,34
Version=4
ViewMode=1

View File

@@ -0,0 +1,34 @@
// Animations
// slideFromBottom
.slideFromBottom-enter, .slideFromBottom-leave-to {
transform: translate(0px, 10em);
}
.slideFromBottom-enter-to, .slideFromBottom-leave {
transform: translate(0px, 0px);
}
.slideFromBottom-enter-active {
transition: transform .2s ease-out;
}
.slideFromBottom-leave-active {
transition: transform .2s ease-in;
}
.tothebottomfixed {
position: fixed;
left: 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

@@ -0,0 +1,141 @@
import { useQuasar } from 'quasar'
import {
defineComponent, onBeforeMount, onBeforeUnmount, onMounted, ref, toRefs, watch,
} from 'vue'
import { useI18n } from '@src/boot/i18n'
// PropType,
export default defineComponent({
name: 'BannerCookies',
components: {},
props: {
urlInfo: {
type: String,
required: true,
},
},
setup(props, context) {
const $q = useQuasar()
const { t } = useI18n();
const elementId = ref<string>('id');
const disableDecline = ref<boolean>(true);
const debug = ref<boolean>(false);
const status = ref<string | null>(null);
const supportsLocalStorage = ref<boolean>(true);
const isOpen = ref<boolean>(false);
const getCookieStatus = (): string | null => {
if (supportsLocalStorage.value) {
return localStorage.getItem(`cookie-${elementId.value}`)
}
return null
// return tinyCookie.get(`cookie-${this.elementId}`)
}
const init = (): void => {
const visitedType = getCookieStatus()
if (visitedType && (visitedType === 'accept' || visitedType === 'decline' || visitedType === 'postpone')) {
isOpen.value = false
}
if (!visitedType) {
isOpen.value = true
}
if (!supportsLocalStorage.value) isOpen.value = false
status.value = visitedType
context.emit('status', visitedType)
}
const checkLocalStorageFunctionality = (): void => {
// Check for availability of localStorage
try {
const test = '__cookie-check-localStorage'
window.localStorage.setItem(test, test)
window.localStorage.removeItem(test)
} catch (e) {
console.error('Local storage is not supported, falling back to cookie use')
supportsLocalStorage.value = false
}
}
const setCookieStatus = (type: string): void => {
if (supportsLocalStorage.value) {
if (type === 'accept') {
localStorage.setItem(`cookie-${elementId.value}`, 'accept')
}
if (type === 'decline') {
localStorage.setItem(`cookie-${elementId.value}`, 'decline')
}
if (type === 'postpone') {
localStorage.setItem(`cookie-${elementId.value}`, 'postpone')
}
} else {
/* if (type === 'accept') {
tinyCookie.set(`cookie-${elementId}`, 'accept')
}
if (type === 'decline') {
tinyCookie.set(`cookie-${elementId}`, 'decline')
}
if (type === 'postpone') {
tinyCookie.set(`cookie-${elementId}`, 'postpone')
} */
}
}
const accept = (): void => {
if (!debug.value) {
setCookieStatus('accept')
}
status.value = 'accept'
isOpen.value = false
context.emit('clicked-accept')
}
const decline = (): void => {
if (!debug.value) {
setCookieStatus('decline')
}
status.value = 'decline'
isOpen.value = false
context.emit('clicked-decline')
}
const clickInfo = (): void => {
isOpen.value = false
}
const postpone = (): void => {
if (!debug.value) {
setCookieStatus('postpone')
}
status.value = 'postpone'
isOpen.value = false
context.emit('clicked-postpone')
}
const removeCookie = (): void => {
localStorage.removeItem(`cookie-${elementId.value}`)
status.value = null
context.emit('removed-cookie')
}
onMounted(init)
return {
disableDecline,
decline,
accept,
postpone,
checkLocalStorageFunctionality,
clickInfo,
removeCookie,
isOpen,
t,
}
},
})

View File

@@ -0,0 +1,27 @@
<template>
<div v-if="isOpen" class="tothebottomfixed" role="dialog">
<div class="q-pa-md q-gutter-sm">
<transition appear name="slide-up" mode="out-in" :duration="2000">
<q-banner class="bg-primary text-white" transition-show="jump-down">
{{t('cookies')}}
<template v-slot:action>
<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>
</div>
</div>
</template>
<script lang="ts" src="./BannerCookies.ts">
</script>
<style lang="scss" scoped>
@import './BannerCookies.scss';
</style>

View File

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

View File

@@ -0,0 +1,56 @@
.imgtext {
display: flex;
justify-content: space-between;
/* flex-flow: row nowrap; */
padding: 1rem 0 1rem 0;
margin: .125rem;
* {
width: 100%;
flex: 1;
margin-left: auto;
margin-right: auto;
}
&__img {
min-width: 250px;
}
&__imgh100 {
max-height: 100px;
}
&__imgh150 {
max-height: 150px;
}
&__imgw150 {
max-width: 150px;
}
&__imgw100 {
max-width: 100px;
}
}
@media (max-width: 400px) {
// PER VERSIONE MOBILE
.landing > section.padding_testo {
padding-top: 0.5rem;
padding-bottom: 0.1rem;
}
.imgtext {
padding: 0.25rem 0 0.25rem 0;
}
}
.landing > section.padding_testo {
padding-top: 1rem;
padding-bottom: 0.25rem;
}
.section_text {
padding: 10px;
}

View File

@@ -0,0 +1,53 @@
import {
defineComponent, onBeforeMount, onBeforeUnmount, onMounted, ref, toRef, toRefs, watch,
} from 'vue'
import { tools } from '@src/store/Modules/tools'
export default defineComponent({
name: 'CImgText',
props: {
src: {
type: String,
default: '',
},
src2: {
type: String,
default: '',
},
class1: {
type: String,
default: 'myclimg',
},
style1: {
type: String,
default: '',
},
alt1: {
type: String,
default: 'image',
},
alt2: {
type: String,
default: 'image',
},
},
setup() {
function clrowcol() {
let mycl = 'row'
if (tools.isMobile()) mycl = 'column'
return mycl
}
function myclass() {
return `${clrowcol()} items-start q-col-gutter-xs imgtext `
}
return {
clrowcol,
myclass,
}
},
})

View File

@@ -0,0 +1,21 @@
<template>
<div>
<section class="padding_testo bg-white text-grey-10 text-justify"> <!-- v-scroll-reveal.reset -->
<div :class="myclass">
<div :class="clrowcol + ` q-px-xs`">
<q-img v-if="src" :src="src" class="" :style="style1" :alt="alt1"></q-img>
<q-img v-if="src2" :src="src2" class="" :style="style1" :alt="alt2"></q-img>
<div class="section_text">
<slot></slot>
</div>
</div>
</div>
</section>
</div>
</template>
<script lang="ts" src="./CImgText.ts">
</script>
<style lang="scss" scoped>
@import './CImgText.scss';
</style>

View File

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

View File

@@ -0,0 +1,90 @@
.imgtitle {
display: flex;
justify-content: space-between;
/* flex-flow: row nowrap; */
padding: 1rem 0 1rem 0;
margin: .125rem;
* {
width: 100%;
flex: 1;
margin-left: auto;
margin-right: auto;
}
&__img {
min-width: 250px;
}
&__imgh100 {
max-height: 100px;
}
&__imgh150 {
max-height: 150px;
}
&__imgw150 {
max-width: 150px;
}
&__imgw100 {
max-width: 100px;
}
}
@media (max-width: 718px) {
// PER VERSIONE MOBILE
.landing > section.padding_testo {
padding-top: 0.5rem;
padding-bottom: 0.1rem;
}
.imgtitle {
padding: 0.25rem 0 0.25rem 0;
}
}
.landing > section.padding_testo {
padding-top: 1rem;
padding-bottom: 0.25rem;
}
.section_text {
padding: 10px;
}
.title{
font-size: 3rem;
padding: 10px;
text-shadow: .2rem .2rem .2rem #3d3d3d;
}
@media (max-width: 400px) {
.title{
padding: 5px;
font-size: 2.5rem;
}
}
.mylegendinside{
font-size: 1rem;
margin-bottom: 50px;
opacity: .8;
@media (max-width: 400px) {
margin-bottom: -10px;
}
}
.mylegend{
text-align: center;
color: black;
font-size: 1rem;
font-style: italic;
opacity: .8;
text-shadow: .05rem .05rem .05rem #aeaeae;
z-index: 1000;
@media (max-width: 400px) {
}
}

View File

@@ -0,0 +1,58 @@
import { defineComponent, ref } from 'vue'
import { tools } from '@src/store/Modules/tools'
export default defineComponent({
name: 'CImgTitle',
props: {
src: {
type: String,
required: false,
default: '',
},
title: {
type: String,
required: false,
default: '',
},
myheight: {
type: Number,
required: false,
default: 0,
},
myheightmobile: {
type: Number,
required: false,
default: 0,
},
legendinside: {
type: String,
required: false,
default: '',
},
legend: {
type: String,
required: false,
default: '',
},
},
setup(props) {
function getsrc(): string {
const filefull = tools.getimgFullpathbysize(props.src)
return tools.getimgbysize(filefull.path, filefull.file)
}
function getaltimg(): string {
const filefull = tools.getimgFullpathbysize(props.src)
return tools.getaltimg(filefull.path, filefull.file, props.title)
}
return {
getsrc,
getaltimg,
}
},
})

View File

@@ -0,0 +1,15 @@
<template>
<div>
<q-parallax :src="getsrc" :height="tools.myheight_imgtitle(myheight, myheightmobile)">
<h1 class="text-white title" style="text-align: center" >{{title}}</h1>
<div v-if="legendinside" class="mylegendinside absolute-bottom custom-caption" style="text-align: center" v-html="legendinside"></div>
</q-parallax>
<div v-if="legend" class="mylegend" v-html="legend"></div>
</div>
</template>
<script lang="ts" src="./CImgTitle.ts">
</script>
<style lang="scss" scoped>
@import './CImgTitle.scss';
</style>

View File

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

View File

View File

@@ -0,0 +1,67 @@
import {
defineComponent, onMounted, ref, toRef,
} from 'vue'
import { IMyPage } from '@src/model'
import { useQuasar } from 'quasar'
import { useGlobalStore } from '@store/globalStore'
import { Footer } from '../Footer'
import { CImgTitle } from '../CImgTitle/index'
import { CTitle } from '../CTitle/index'
import MixinsMetaTags from '../../mixins/mixin-metatags'
export default defineComponent({
name: 'CMyPage',
components: { Footer, CImgTitle, CTitle },
mixins: [MixinsMetaTags],
props: {
title: String,
mypath: {
type: String,
required: false,
default: '',
},
img: {
type: String,
required: false,
default: '',
},
imgbackground: {
type: String,
required: false,
default: '',
},
sizes: {
type: String,
required: false,
default: '',
},
styleadd: {
type: String,
required: false,
default: '',
},
nofooter: {
type: Boolean,
required: false,
default: false,
},
},
setup(props) {
const $q = useQuasar()
const rec = ref<IMyPage | null>(null)
const mypath = toRef(props, 'mypath')
const globalStore = useGlobalStore()
const load = async (): Promise<void> => {
if (mypath.value !== '') rec.value = await globalStore.loadPage(mypath.value)
}
onMounted(load)
return { rec }
},
})

View File

@@ -0,0 +1,53 @@
<template>
<div>
<div v-if="mypath && !!rec">
<div class="q-ma-sm q-gutter-sm q-pa-xs">
<div v-if="!!rec.img1" class="text-center">
<q-img :src="`public/`+ rec.img1" class="img"></q-img>
</div>
<div v-if="!!rec.content" v-html="rec.content"></div>
<q-video v-if="!!rec.video1" :src="rec.video1" :ratio="rec.ratio1">
</q-video>
<div v-if="!!rec.img2" class="text-center">
<q-img :src="`public/`+ rec.img2" class="img"></q-img>
</div>
<div v-if="!!rec.content2" v-html="rec.content2"></div>
<q-video v-if="!!rec.video2" :src="rec.video2" :ratio="rec.ratio2"></q-video>
<div v-if="!!rec.img3" class="text-center">
<q-img :src="`public/`+ rec.img2" class="img"></q-img>
</div>
<div v-if="!!rec.content3" v-html="rec.content3"></div>
<q-video v-if="!!rec.video3" :src="rec.video3" :ratio="rec.ratio3"></q-video>
<div v-if="!!rec.content4" v-html="rec.content4"></div>
</div>
</div>
<div v-else>
<div v-if="!!title">
<CTitle
v-if="imgbackground" :imgbackground="imgbackground"
:headtitle="title" :sizes="sizes" :styleadd="styleadd"></CTitle>
<div v-if="!imgbackground">
<CImgTitle v-if="img" :src="img" :title="title">
</CImgTitle>
</div>
<slot></slot>
<div v-if="!nofooter">
<Footer></Footer>
</div>
</div>
</div>
</div>
</template>
<script lang="ts" src="./CMyPage.ts">
</script>
<style lang="scss" scoped>
@import './CMyPage.scss';
</style>

View File

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

View File

@@ -0,0 +1,29 @@
.cltitlebg{
}
.titletext {
color: white;
font-size: 3rem;
font-weight: 500;
line-height: 3rem;
text-shadow: .25rem .25rem .5rem black;
letter-spacing: .00937em;
opacity: 0.9;
}
@media (max-width: 718px) {
// PER VERSIONE MOBILE
.titletext {
color: white;
font-size: 2rem;
font-weight: 500;
line-height: 2rem;
text-shadow: .25rem .25rem .5rem black;
}
}
.q-img__content > div{
background: rgba(0,0,0,0.17) !important;
}

56
src/components/CTitle/CTitle.ts Executable file
View File

@@ -0,0 +1,56 @@
import {
defineComponent, onBeforeMount, onBeforeUnmount, onMounted, ref, toRef, toRefs, watch,
} from 'vue'
import { tools } from '@store/Modules/tools'
export default defineComponent({
name: 'CTitle',
props: {
headtitle: {
type: String,
required: true,
default: '',
},
imgbackground: {
type: String,
default: '',
},
imghead: {
type: String,
default: '',
},
sizes: {
type: String,
default: '',
},
styleadd: {
type: String,
default: '',
},
},
setup(props, { attrs, slots, emit }) {
const { headtitle } = toRefs(props) // REQUIRED PROP !
const imgbackground = toRef(props, 'imgbackground') // OPTIONAL PROP
function getsrc(): string {
const filefull = tools.getimgFullpathbysize(imgbackground.value)
return tools.getimgbysize(filefull.path, filefull.file)
}
function getaltimg(): string {
if (headtitle.value) {
return headtitle.value
}
const filefull = tools.getimgFullpathbysize(imgbackground.value)
return tools.getaltimg(filefull.path, filefull.file, headtitle.value)
}
return {
getsrc,
getaltimg,
}
},
})

View File

@@ -0,0 +1,28 @@
<template>
<div>
<q-img
v-if="imgbackground" :src="getsrc" :alt="getaltimg"
:style="tools.styles_imgtitle(sizes)">
<div class="absolute-bottom text-body1 text-center" :style="styleadd">
<h1 class="titletext" v-html="headtitle"></h1>
</div>
</q-img>
<!--
<q-parallax :height="tools.myheight_imgtitle()" :width="tools.mywidth_imgtitle()">
<template v-slot:media>
<img :src="imgbackground" class="cltitlebg">
</template>
<h2 class="titletext">{{headtitle}}</h2>
</q-parallax>
-->
</div>
</template>
<script lang="ts" src="./CTitle.ts">
</script>
<style lang="scss" scoped>
@import './CTitle.scss';
</style>

1
src/components/CTitle/index.ts Executable file
View File

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

View File

@@ -0,0 +1,40 @@
<template>
<div>
<p>{{ title }}</p>
<ul>
<li v-for="todo in todos" :key="todo.id" @click="increment">
{{ todo.id }} - {{ todo.content }}
</li>
</ul>
<p>Count: {{ todoCount }} / {{ meta.totalCount }}</p>
<p>Active: {{ active ? 'yes' : 'no' }}</p>
<p>Clicks on todos: {{ clickCount }}</p>
</div>
</template>
<script lang="ts">
import { Vue, prop } from 'vue-class-component'
import { Todo, Meta } from './models'
class Props {
readonly title!: string;
readonly todos = prop<Todo[]>({ default: () => [] });
readonly meta!: Meta;
readonly active!: boolean;
}
export default class ClassComponent extends Vue.with(Props) {
clickCount = 0;
increment() {
this.clickCount += 1
}
get todoCount() {
return this.todos.length
}
}
</script>

View File

@@ -0,0 +1,39 @@
<template>
<q-item
clickable
tag="a"
target="_blank"
:href="link"
>
<q-item-section
v-if="icon"
avatar
>
<q-icon :name="icon" />
</q-item-section>
c
<q-item-section>
<q-item-label>{{ title }}</q-item-label>
<q-item-label caption>
{{ caption }}
</q-item-label>
</q-item-section>
</q-item>
</template>
<script lang="ts">
import { Vue, prop, Options } from 'vue-class-component'
class Props {
readonly title!: string;
readonly caption = prop({ default: '' });
readonly link = prop({ default: '#' });
readonly icon = prop({ default: '' });
}
@Options({})
export default class EssentialLink extends Vue.with(Props) {}
</script>

188
src/components/Footer/Footer.scss Executable file
View File

@@ -0,0 +1,188 @@
$grayshadow: #555;
$textcol: blue;
$textcol_scuro: darkblue;
.landing__footer {
//background: -webkit-gradient(linear, left top, left bottom, color-stop(65%, rgba(0, 0, 0, .1)), to(#000));
background: linear-gradient(180deg, rgba(0, 0, 0, .8) 95%, #FFF);
padding-top: 4.5rem !important;
padding-bottom: 4.5rem !important;
padding-left: 1.25rem;
padding-right: 1.25rem;
color: #9f9f9f;
}
.icon_contact:hover {
color: blue;
border-color: white;
border-width: .0625rem;
}
.landing__footer .doc-link {
color: $textcol;
}
.landing__footer .doc-link:hover {
opacity: .8
}
.landing__swirl-bg {
background-repeat: no-repeat !important;
background-position: top;
background-size: contain !important;
background-image: url(../../../public/images/landing_first_section.png) !important
}
.landing__footer-icons {
font-size: 2rem
}
.landing__footer-icons a {
margin: 0 .5rem .5rem;
text-decoration: none;
outline: 0;
color: $textcol;
transition: color .28s
}
.landing__footer-icons a:hover {
color: $textcol_scuro;
}
.doc-img {
max-width: 100%;
}
.mylist {
background: #3fdaff;
padding-left: 1.25rem;
}
.clgutter {
margin-top: 1.25rem;
padding: .62rem;
}
.carousel_img_3 {
//background-image: url(../../public/images/cibo_sano.jpg);
background-size: cover !important;
background-position: 50% center !important;
background-repeat: no-repeat !important;
}
@media (max-width: 718px) {
// PER VERSIONE MOBILE
.landing__hero {
text-align: center
}
.landing__header {
height: 7vh
}
.clgutter {
margin-top: 0;
padding: 0;
}
.landing__hero .text-h1 {
font-size: 3rem;
line-height: 3.05rem;
margin-bottom: 1.5rem
}
.landing > section.padding {
padding: 2.5rem 1rem;
}
.landing > section.padding_testo {
padding-top: 1.25rem;
padding-bottom: 1rem;
}
.landing > section.padding_gallery {
padding-top: 3.125rem;
padding-bottom: 5.625rem;
}
.landing__features h4, .landing__features h6 {
margin: 1.25rem 0
}
h4 {
line-height: 1.4;
text-shadow: 0.25rem 0.25rem 0.5rem $grayshadow;
}
.landing .feature-item {
text-align: center;
margin-top: 1.25rem;
}
.landing__hero-content {
padding-bottom: 11.25rem;
}
.landing__hero-btns {
-webkit-box-pack: center;
-ms-flex-pack: center;
justify-content: center
}
.q-col-gutter-sm {
padding: .625rem .315rem;
}
.text-vers{
font-size: 0.6rem;
}
}
.custom-caption {
text-align: center;
padding: .75rem;
color: $textcol;
background-color: rgba(0, 0, 0, .3);
}
.mycontacts {
color: gray;
letter-spacing: 0.078rem;
}
.copyrights {
color: gray;
letter-spacing: 0.078rem;
}
.mycontacts_title {
text-shadow: 0.125rem 0.125rem 0.125rem #555;
font-weight: bold;
color: #999;
letter-spacing: 0.125rem;
}
.mycontacts_text {
font-size: 1rem;
color: #999;
letter-spacing: normal !important;
}
.footer_link {
font-size: 1rem;
color:gray;
}
.footer_link:hover {
color:white;
}
.margin_buttons_footer {
margin: -4px -4px;
}
.margin_buttons_footer > * {
margin: 4px 8px;
}

69
src/components/Footer/Footer.ts Executable file
View File

@@ -0,0 +1,69 @@
import {
defineComponent,
} from 'vue'
import { tools } from '@src/store/Modules/tools'
import { static_data } from '@src/db/static_data'
import { useQuasar } from 'quasar'
import { useGlobalStore } from '@store/globalStore'
import { FormNewsletter } from '../FormNewsletter'
import { MixinBase } from '../../mixins/mixin-base'
import { Logo } from '../logo'
import { useI18n } from '@src/boot/i18n'
export default defineComponent({
name: 'Footer',
mixins: [MixinBase],
components: { Logo, FormNewsletter },
setup() {
const $q = useQuasar()
const { t } = useI18n()
const globalStore = useGlobalStore()
console.log('Footer - INIT')
function TelegramSupport() {
return globalStore.getValueSettingsByKey('TELEGRAM_SUPPORT', false)
}
function Whatsapp_Cell() {
return globalStore.getValueSettingsByKey('WHATSAPP_CELL', false)
}
function Telegram_UsernameHttp() {
return tools.getHttpForTelegram(globalStore.getValueSettingsByKey('TELEGRAM_USERNAME', false))
}
function FBPage() {
const fb = globalStore.getValueSettingsByKey('URL_FACEBOOK', false)
return fb
}
function InstagramPage() {
return globalStore.getValueSettingsByKey('URL_INSTAGRAM', false)
}
function TwitterPage() {
return globalStore.getValueSettingsByKey('URL_TWITTER', false)
}
function ChatWhatsapp() {
// @ts-ignore
return tools.getHttpForWhatsapp(this.Whatsapp_Cell)
}
return {
TelegramSupport,
InstagramPage,
Whatsapp_Cell,
TwitterPage,
ChatWhatsapp,
FBPage,
Telegram_UsernameHttp,
static_data,
t,
}
},
})

171
src/components/Footer/Footer.vue Executable file
View File

@@ -0,0 +1,171 @@
<template>
<div>
<section class="landing__footer">
<div class="row justify-between items-start q-col-gutter-xs">
<div class="col-12 col-sm-4 ">
<!--<span v-html="t('homepage.footer.description')">-->
<!--</span>-->
<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 v-if="getValDb('URLMAP', false)" 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>-->
<!--</div>-->
</div>
<div class="col-12 col-sm-4">
<div class="text-center">
<div class="q-mt-xs mycontacts">
<p class="mycontacts_title">{{t('homepage.titlecontatti')}}</p>
<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', false)" class="links">{{ getValDb('MAIN_EMAIL', false)
}}</a><br>
<div style="margin-bottom: 20px;"></div>
<div
v-for="(rec, index) in getarrValDb('CONTACTS_EMAIL_CELL', false)"
:key="index"
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>
<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>
</div>
<span v-if="getValDb('CALL_WORKING_DAYS', false)"><br>orari per chiamate:<br>
<span v-html="getValDb('CALL_WORKING_DAYS', false)"></span></span>
</div>
</div>
</div>
<FormNewsletter
v-if="static_data.functionality.SHOW_NEWSLETTER"
:idwebsite="tools.appid()"
:locale="toolsext.getLocale()">
</FormNewsletter>
<p class="text-center">
<router-link v-if="static_data.functionality.SHOW_ONLY_POLICY" to="/policy" custom v-slot="{ navigate }">
<span class="footer_link" @click="navigate" @keypress.enter="navigate" role="link">{{t('privacy_policy')}}</span></router-link>
</p>
</div>
<div class="col-12 col-sm-4 q-pa-md">
<p style="text-align: center">
<logo></logo>
</p>
<div v-for="(myitemmenu, ind) in static_data.routes" :key="ind">
<div v-if="myitemmenu.infooter && tools.visumenu(myitemmenu)">
<div v-if="myitemmenu.solotitle">
<span class="footer_link">{{tools.getLabelByItem(myitemmenu, mythisfoot)}}</span><br/>
</div>
<div v-else>
<router-link :to="myitemmenu.path" custom v-slot="{ navigate }">
<span class="footer_link" @click="navigate" @keypress.enter="navigate" role="link"><span
v-if="myitemmenu.level_child > 0">&nbsp;&nbsp;&nbsp;</span>
{{tools.getLabelByItem(myitemmenu, mythisfoot)}}</span><br/>
</router-link>
</div>
<!--<a :href="myitemmenu.path"><span class="footer_link">{{tools.getLabelByItem(myitemmenu, mythisfoot)}}</span></a><br/>-->
</div>
</div>
</div>
</div>
</section>
<q-page-scroller position="bottom-right" :scroll-offset="850" :offset="[18, 78]" style="opacity: 0.3">
<q-btn fab icon="keyboard_arrow_up" color="accent"/>
</q-page-scroller>
<q-page-sticky v-if="ChatWhatsapp()" position="bottom-right" :offset="[18, 18]">
<q-btn
fab icon="fab fa-whatsapp" color="green" type="a" :href="ChatWhatsapp()" target="__blank"
class="mybtn_sticky"/>
</q-page-sticky>
</div>
</template>
<script lang="ts" src="./Footer.ts">
</script>
<style lang="scss" scoped>
@import './Footer.scss';
</style>

1
src/components/Footer/index.ts Executable file
View File

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

View File

@@ -0,0 +1,30 @@
// Animations
// slideFromBottom
.slideFromBottom-enter, .slideFromBottom-leave-to {
transform: translate(0px, 10em);
}
.slideFromBottom-enter-to, .slideFromBottom-leave {
transform: translate(0px, 0px);
}
.slideFromBottom-enter-active {
transition: transform .2s ease-out;
}
.slideFromBottom-leave-active {
transition: transform .2s ease-in;
}
.news_title {
color: white;
font-size: 1rem;
}
.news_link {
color: gray;
}
.news_link:hover {
color: white;
}

View File

@@ -0,0 +1,125 @@
import {
defineComponent, toRef,
} from 'vue'
import { useQuasar } from 'quasar'
import { useI18n } from '@src/boot/i18n'
import Api from '@api'
import { serv_constants } from '@store/Modules/serv_constants'
import { MixinBase } from '../../mixins/mixin-base'
import { toolsext } from '@src/store/Modules/toolsext'
export default defineComponent({
name: 'FormNewsletter',
mixins: [MixinBase],
props: {
name: {
required: false,
type: String,
default: '',
},
surname: {
required: false,
type: String,
default: '',
},
email: {
required: false,
type: String,
default: '',
},
accept: {
required: false,
type: Boolean,
default: false,
},
idwebsite: {
required: false,
type: String,
default: '',
},
locale: {
required: false,
type: String,
default: '',
},
},
setup(props) {
const $q = useQuasar()
const { t } = useI18n();
const accept = toRef(props, 'accept')
const name = toRef(props, 'name')
const surname = toRef(props, 'surname')
const email = toRef(props, 'email')
const idwebsite = toRef(props, 'idwebsite')
const locale = toRef(props, 'locale')
const onSubmit = async function a2() {
if (accept.value !== true) {
$q.notify({
color: 'red-5',
textColor: 'white',
icon: 'fas fa-exclamation-triangle',
message: t('newsletter.license'),
})
return null
}
const usertosend = {
email: email.value,
firstName: name.value,
lastName: surname.value,
idwebsite: idwebsite.value,
locale: locale.value,
settomailchimp: toolsext.getValDb('MAILCHIMP_ON', true, false),
}
console.log(usertosend)
return Api.SendReq('/news/signup', 'POST', usertosend, false)
.then((res) => {
// console.log('res', res)
if (res.data.code === serv_constants.RIS_SUBSCRIBED_OK) {
$q.notify({
color: 'green-4',
textColor: 'white',
icon: 'fas fa-check-circle',
// message: t('newsletter.submitted')
message: res.data.msg,
})
} else if (res.data.code === serv_constants.RIS_SUBSCRIBED_ALREADYEXIST) {
$q.notify({
color: 'orange-4',
textColor: 'white',
icon: 'fas fa-check-circle',
// message: t('newsletter.submitted')
message: res.data.msg,
})
} else {
$q.notify({
color: 'red-5',
textColor: 'white',
icon: 'fas fa-exclamation-triangle',
message: res.data.msg,
})
}
})
.catch((error) => {
console.error(error)
// UserStore.mutations.setErrorCatch(error)
return false
})
}
function onReset() {
name.value = ''
surname.value = ''
email.value = ''
accept.value = false
}
return {
onSubmit,
onReset,
}
},
})

View File

@@ -0,0 +1,66 @@
<template>
<div>
<div class="q-pa-md q-gutter-sm text-white">
<p class="news_title">{{t('newsletter.title')}}</p>
<q-form
@submit="onSubmit"
@reset="onReset"
class="q-gutter-md"
>
<q-input
filled
name="firstName"
dense
dark standout
v-model="name"
:label="t('newsletter.name') + `*`"
:hint="t('newsletter.namehint')"
lazy-rules
:rules="[ val => val && val.length > 0 || t('newsletter.typesomething')]">
</q-input>
<q-input
filled
dense
dark standout
v-model="surname"
name="lastName"
:label="t('newsletter.surname') + `*`"
:hint="t('newsletter.surnamehint')"
lazy-rules
:rules="[ val => val && val.length > 0 || t('newsletter.typesomething')]">
</q-input>
<q-input
filled
dense
dark standout
v-model="email"
:label="t('newsletter.email') + `*`"
lazy-rules
:rules="[ val => val && val.length > 6 || t('newsletter.typesomething')]">
</q-input>
<router-link to="/policy" custom v-slot="{ navigate }">
<span class="news_link" @click="navigate" @keypress.enter="navigate" role="link">{{t('privacy_policy')}}</span></router-link>
<q-toggle dark v-model="accept" :label="t('newsletter.acceptlicense')"/>
<div>
<q-btn :label="t('newsletter.submit')" type="submit" color="primary"/>
<q-btn :label="t('newsletter.reset')" type="reset" color="primary" flat class="q-ml-sm"/>
</div>
</q-form>
</div>
</div>
</template>
<script lang="ts" src="./FormNewsletter.ts">
</script>
<style lang="scss" scoped>
@import './FormNewsletter.scss';
</style>

View File

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

317
src/components/Header/Header.scss Executable file
View File

@@ -0,0 +1,317 @@
.layout-padding {
padding: 1em 4em;
}
.item-content {
font-size: 0.8rem;
font-weight: 350;
}
.q-toolbar__title{
padding: 0 12px;
}
@media screen and (max-width: 600px) {
.q-toolbar__title{
padding: 0;
}
.layout-padding {
padding: 1.5em .5em;
}
}
.fixed-left:hover {
cursor: ew-resize;
}
/*
@-webkit-keyframes moveFromLeftFade {
from {
opacity: 0.3;
-webkit-transform: translateX(-100%);
}
}
@keyframes moveFromLeftFade {
from {
opacity: 0.3;
-webkit-transform: translateX(-100%);
transform: translateX(-100%);
}
}
@-webkit-keyframes moveFromTopFade {
from {
opacity: 0.3;
-webkit-transform: translateY(0%);
}
}
@keyframes moveFromTopFade {
from {
opacity: 0.3;
-webkit-transform: translateY(0%);
transform: translateY(-50%);
}
}
@-webkit-keyframes moveToRight {
from {
}
to {
-webkit-transform: translateX(100%);
}
}
@keyframes cartOut {
from {
transform: translate(0px, 0px);
}
to {
transform: translate(1200px, 0px);
animation-timing-function: ease-out;
}
}
@-webkit-keyframes moveToLeft {
from {
}
to {
opacity: .5;
-webkit-transform: translateX(-100%);
}
}
@keyframes moveToLeft {
from {
}
to {
opacity: .5;
-webkit-transform: translateX(-100%);
transform: translateX(-100%);
}
}
@-webkit-keyframes moveToBottom {
from {
}
to {
opacity: .5;
-webkit-transform: translateY(-100%);
}
}
@keyframes moveToBottom {
from {
}
to {
opacity: .5;
-webkit-transform: translateY(-100%);
transform: translateY(-100%);
}
}
@-webkit-keyframes moveFromRight {
from {
opacity: .7;
-webkit-transform: translateX(100%);
}
}
@keyframes moveFromRight {
from {
opacity: .7;
-webkit-transform: translateX(100%);
transform: translateX(100%);
}
}
*/
.drawer-closer .item-content {
margin-left: 20px !important;
}
.drawer-content .list-label {
line-height: 25px;
}
.drawer-content .item {
height: 25px;
}
.router-link-active .item-primary {
color: #027be3;
}
.q-picker-textfield .q-picker-textfield-label {
color: inherit !important;
}
.label-success .q-picker-textfield-label {
color: #4caf50 !important;
}
.label-error .q-picker-textfield-label {
color: #f44336 !important;
}
select {
-webkit-appearance: none;
-moz-appearance: none;
text-indent: 1px;
text-overflow: '';
}
.label-success .q-picker-textfield:after, .label-error .q-picker-textfield:after {
content: "" !important;
}
#android-preview iframe {
margin-top: 64px;
width: 357px;
height: 590px;
background: #fff;
}
#ios-preview iframe {
margin-top: 64px;
width: 320px;
height: 590px;
background: #fff;
}
canvas {
width: 270px !important;
}
@media only screen and (min-width: 601px) {
.adv-form-one .timeline-badge {
right: auto !important;
left: auto !important;
}
.adv-form-one .timeline-content {
margin-left: 3.9rem;
}
.adv-form-one .timeline-item {
width: 100% !important;
}
.adv-form-one .timeline-title {
text-align: inherit !important;
margin-left: 3.9rem;
}
.timeline:before {
left: 1.6rem;
}
}
.adv-form-one .timeline-content .group .primary {
display: none !important;
}
.toolbar {
min-height: 43px;
}
.right-itens a, .right-itens button {
margin-right: 10px;
}
.sel_lang {
padding: 5px;
color: white;
}
.fa-facebook:before {
content: url('../../../public/icons/flag_it.svg');
}
.clIconOnline {
color: white;
}
.clIconOffline {
color: red;
}
.flagimg {
width: 30px;
height: 24px;
}
.clCloudUpload {
transition: all 1s ease-out;
color: initial;
&.send {
transition: all 1s ease-in;
background-color: lightgreen;
}
&.receive {
transition: all 1s ease-in;
background-color: yellow;
}
&.error {
transition: all 1s ease-in;
background-color: red;
}
}
.clIndexeddb {
transition: all 1s ease-out;
color: initial;
&.receive {
transition: all 1s ease-in;
background-color: yellow;
}
&.send {
transition: all 1s ease-in;
background-color: lightgreen;
}
&.error {
transition: all 1s ease-in;
background-color: red;
}
}
.btnNewVersHide {
display: none;
}
.btnNewVersShow {
display: inline-block;
padding: 4px 2px;
}
.text-user {
text-shadow: .05rem .05rem .15rem #fff;
background-color: limegreen;
border-radius: 1rem !important;
text-align: center;
margin: 1px;
margin-bottom: 5px;
}
.text-cart {
font-size: 1.15rem;
text-shadow: .05rem .05rem .15rem #fff;
background-color: limegreen;
border-radius: 1rem !important;
text-align: center;
margin: 1px;
margin-bottom: 5px;
}
.roundimg {
border-radius: 50% !important;
color: red;
background-color: red;
}
.titlesite {
font-size: 1rem;
}

459
src/components/Header/Header.ts Executable file
View File

@@ -0,0 +1,459 @@
import { useQuasar } from 'quasar'
import {
defineComponent, onBeforeMount, onBeforeUnmount, onMounted, ref, toRefs, watch, inject, computed,
} from 'vue'
import { tools } from '@store/Modules/tools'
import { shared_consts } from '@src/common/shared_vuejs'
import { useI18n } from '@src/boot/i18n'
import { boot } from 'quasar/wrappers'
import { useRouter } from 'vue-router'
import MixinUsers from '../../mixins/mixin-users'
import { static_data } from '../../db/static_data'
import messagePopover from '../../layouts/toolbar/messagePopover/messagePopover.vue'
import drawer from '../../layouts/drawer/drawer.vue'
import { toolsext } from '@store/Modules/toolsext'
import { useGlobalStore } from '@store/globalStore'
import { useTestStore } from '@store/testStore'
import { useUserStore } from '@store/UserStore'
export default defineComponent({
name: 'Header',
mixins: [MixinUsers],
components: {
drawer, messagePopover, // CSigninNoreg, CMyAvatar, CMyCart
},
props: {
extraContent: {
required: false,
default: '',
},
clBase: {
required: false,
default: '',
},
},
setup() {
const store = inject('store')
const $q = useQuasar()
const { t } = useI18n()
const isUserNotAuth = ref(false)
const iconConn = ref('wifi')
const clIconConn = ref('clIconOnline')
const strConn = ref('')
const langshort = ref('')
const clCloudUpload = ref('')
const clCloudDownload = ref('')
const clCloudUp_Indexeddb = ref('')
const tabcmd = ref('')
const clCloudDown_Indexeddb = ref('clIndexeddbsend')
const photo = ref('')
const visuimg = ref(true)
const userStore = useUserStore()
const globalStore = useGlobalStore()
const testStore = useTestStore()
const stateconn = ref(globalStore.stateConnection)
function isonline() {
return globalStore.stateConnection === 'online'
}
function isAdmin() {
return userStore.isAdmin
}
function isManager() {
return userStore.isManager
}
const isSocio = computed(() => userStore.my.profile.socio)
function isSocioResidente() {
return userStore.my.profile.socioresidente
}
function isConsiglio() {
return userStore.my.profile.consiglio
}
function getcolormenu() {
// @ts-ignore
return this.isSocio ? 'green-7' : 'white'
}
function isTutor() {
return userStore.isTutor
}
function isZoomeri() {
return userStore.isZoomeri
}
function isTratuttrici() {
return userStore.isTratuttrici
}
function conndata_changed() {
return globalStore.connData
}
function snakeToCamel(str: string) {
return str.replace(/(-\w)/g, (m) => m[1].toUpperCase())
}
function setLangAtt(mylang: string) {
console.log('LANG =', mylang)
// console.log('PRIMA $q.lang.isoName', $q.lang.isoName)
// dynamic import, so loading on demand only
import(`quasar/lang/${mylang}`).then((lang) => {
$q.lang.set(lang.default)
import('../../statics/i18n').then(() => {
// console.log('MY LANG DOPO=', $q.lang.isoName)
})
})
globalStore.addDynamicPages()
}
function setshortlang(lang: string) {
for (const indrec in static_data.lang_available) {
if (static_data.lang_available[indrec].value === lang) {
// console.log('static_data.lang_available[indrec].short', static_data.lang_available[indrec].short, static_data.lang_available[indrec].value)
langshort.value = static_data.lang_available[indrec].short
return
}
}
}
function isNewVersionAvailable() {
return globalStore.isNewVersionAvailable
}
// -------------------------------------------------------------------------
// QUASAR Example using myevent to open drawer from another component or page
// -------------------------------------------------------------------------
// (1) This code is inside layout file that have a drawer
// if leftDrawerOpen is true, drawer is displayed
// (2) Listen for an myevent in created
/* created(){
$root.$on("openLeftDrawer", openLeftDrawercb);
},
methods: {
openURL,
// (3) Define the callback in methods
openLeftDrawercb() {
leftDrawerOpen = !leftDrawerOpen;
}
}
// (4) In another component or page, emit the myevent!
// Call the method when clicking button etc.
methods: {
openLeftDrawer() {
$root.$emit("openLeftDrawer");
}
}
// -------------------------------------------------------------------------
*/
const leftDrawerOpen = computed({
get: () => globalStore.leftDrawerOpen,
set: val => {
globalStore.leftDrawerOpen = val
},
})
const rightDrawerOpen = computed({
get: () => globalStore.rightDrawerOpen,
set: val => {
globalStore.rightDrawerOpen = val
if (globalStore.rightDrawerOpen) globalStore.rightCartOpen = false
},
})
const rightCartOpen = computed({
get: () => globalStore.rightCartOpen,
set: val => {
globalStore.rightCartOpen = val
if (globalStore.rightCartOpen) globalStore.rightDrawerOpen = false
},
})
const lang = computed({
get: () => $q.lang.isoName,
set: mylang => {
console.log('set lang', $q.lang.getLocale())
$q.lang.set(snakeToCamel(mylang))
// tools.showNotif($q, 'IMPOSTA LANG= ' + $i18n.locale)
// console.log('IMPOSTA LANG= ' + $i18n.locale)
userStore.setlang($q.lang.getLocale())
let mylangtopass = mylang
mylangtopass = toolsext.checkLangPassed(mylangtopass)
setshortlang(mylangtopass)
setLangAtt(mylangtopass)
userStore.setLangServer()
},
})
watch(
stateconn,
// @ts-ignore
(value: string, oldValue: string) => {
globalStore.stateConnection = value
},
)
watch(
conndata_changed,
(value, oldValue) => {
clCloudUpload.value = (value.uploading_server === 1) ? 'clCloudUpload send' : 'clCloudUpload'
clCloudUpload.value = (value.downloading_server === 1) ? 'clCloudUpload receive' : 'clCloudUpload'
clCloudUp_Indexeddb.value = (value.uploading_indexeddb === 1) ? 'clIndexeddb send' : 'clIndexeddb'
clCloudUp_Indexeddb.value = (value.downloading_indexeddb === 1) ? 'clIndexeddb receive' : 'clIndexeddb'
/* clCloudUpload.value = (value.uploading_server === -1) ? 'clCloudUpload error' : clCloudUpload
clCloudUpload.value = (value.downloading_server === -1) ? 'clCloudUpload error' : clCloudDownload
clCloudUp_Indexeddb.value = (value.uploading_indexeddb === -1) ? 'clIndexeddb error' : clCloudUp_Indexeddb
clCloudUp_Indexeddb.value = (value.downloading_indexeddb === -1) ? 'clIndexeddb error' : clCloudDown_Indexeddb
*/
},
)
/*
@Watch('conn_changed', { immediate: true, deep: true })
function changeconn_changed(value: string, oldValue: string) {
if (value !== oldValue) {
// console.log('SSSSSSSS: ', value, oldValue)
const color = (value === 'online') ? 'positive' : 'warning'
const statoconn = t('connection.conn') + ' ' + ((value === 'online') ? t('connection.online') : t('connection.offline'))
if (static_data.functionality.SHOW_IF_IS_SERVER_CONNECTION) {
if (!!oldValue) {
tools.showNotif($q, statoconn, {
color,
icon: 'wifi'
})
}
changeIconConn()
}
}
}
*/
function RefreshApp() {
// Unregister Service Worker
navigator.serviceWorker.getRegistrations().then((registrations) => {
for (const registration of registrations) {
registration.unregister()
}
})
window.location.reload(true)
}
function changeIconConn() {
iconConn.value = globalStore.stateConnection === 'online' ? 'wifi' : 'wifi_off'
clIconConn.value = globalStore.stateConnection === 'online' ? 'clIconOnline' : 'clIconOffline'
}
function getAppVersion() {
// return "AA"
let strv = ''
if (process.env.DEV) {
strv = 'DEV '
} else if (process.env.TEST) {
strv = 'TEST '
}
return `[${strv}${process.env.APP_VERSION}]`
}
function getLangAtt() {
return $q.lang.isoName
}
function BeforeMount() {
// Estrai la Lang dal Localstorage
// console.log('$q.i18n=', $q.i18n, '$q.getLocale()=', $q.lang.isoName)
const mybrowserLang = getLangAtt()
// tools.showNotif($q, 'prima: ' + String(my))
let mylang = tools.getItemLS(toolsext.localStorage.lang)
if (mylang === '') {
if (navigator) {
mylang = navigator.language
// console.log(`LANG2 NAVIGATOR ${mylang}`)
} else {
mylang = $q.lang.isoName
}
// console.log('IMPOSTA LANGMY', mylang)
}
mylang = toolsext.checkLangPassed(mylang)
setLangAtt(mylang)
setshortlang(mylang)
}
function mounted() {
// Test this by running the code snippet below and then
// use the "TableOnlyView" checkbox in DevTools Network panel
// console.log('Event LOAD')
if (window) {
window.addEventListener('load', () => {
// console.log('2) ENTERING Event LOAD')
function updateOnlineStatus(event: any) {
if (navigator.onLine) {
console.log('EVENT ONLINE!')
// handle online status
globalStore.setStateConnection('online')
// mychangeIconConn()
} else {
console.log('EVENT OFFLINE!')
// handle offline status
globalStore.setStateConnection('offline')
// mychangeIconConn()
}
}
window.addEventListener('online', updateOnlineStatus)
window.addEventListener('offline', updateOnlineStatus)
})
}
}
function imglogo() {
return `../../${tools.getimglogo()}`
}
function getappname() {
return tools.getsuffisso() + tools.getappname(tools.isMobile())
}
function toggleanimation() {
console.log('toggleanimation')
visuimg.value = false
setTimeout(() => {
visuimg.value = true
}, 100)
}
function logoutHandler() {
userStore.logout()
.then(() => {
// $router.replace('/logout')
//
// setTimeout(() => {
// $router.replace('/')
// }, 1000)
tools.showNotif($q, t('logout.uscito'), { icon: 'exit_to_app' })
})
}
function isLogged() {
return userStore.isLogged
}
function isEmailVerified() {
return userStore.my.verified_email
}
function clickregister() {
rightDrawerOpen.value = false
const $router = useRouter()
$router.replace('/signup')
}
function getnumItemsCart() {
/* const arrcart = Products.cart
if (!!arrcart) {
if (!!arrcart.items) {
const total = arrcart.items.reduce((sum, item) => sum + item.order.quantity, 0)
return total
}
}
*/
return 0
}
function getnumOrdersCart() {
/* const arrorderscart = Products.orders.filter((rec) => rec.status < shared_consts.OrderStatus.RECEIVED)
// const arrorderscart = Products.orders
if (!!arrorderscart) {
return arrorderscart.length
}
*/
return 0
}
function getcart() {
// return Products.cart
return null
}
function getClassColorHeader() {
if (tools.isTest()) return 'bg-warning'
if (tools.isDebug()) return 'bg-info'
return 'bg-primary'
}
function changecmd(value: any) {
console.log('changecmd', value)
globalStore.changeCmdClick(value)
}
onBeforeMount(BeforeMount)
onMounted(mounted)
return {
store,
static_data,
globalStore,
leftDrawerOpen,
rightDrawerOpen,
rightCartOpen,
lang,
isLogged,
isEmailVerified,
getnumOrdersCart,
t,
isonline,
isAdmin,
isManager, isSocio, isSocioResidente, isConsiglio, getcolormenu,
isNewVersionAvailable,
getAppVersion,
RefreshApp,
changecmd,
imglogo,
getappname,
toggleanimation,
}
},
})

237
src/components/Header/Header.vue Executable file
View File

@@ -0,0 +1,237 @@
<template>
<div>
<q-header reveal elevated :class="getClassColorHeader">
<q-toolbar
color="primary"
:glossy="$q.theme === 'mat'"
:inverted="$q.theme === 'ios'"
class="toolbar">
<q-btn
flat
dense
round
@click="leftDrawerOpen = !leftDrawerOpen"
aria-label="Menu">
<q-icon name="menu"/>
</q-btn>
<div v-if="$q.platform.is.desktop">
<!--I'm only rendered on desktop!-->
</div>
<div v-if="$q.platform.is.mobile">
<!--I'm only rendered on mobile!-->
</div>
<div v-if="$q.platform.is.electron">
<!--I'm only rendered on Electron!-->
</div>
<q-btn
ripple
size="md"
id="newvers" v-if="isNewVersionAvailable" color="secondary" rounded icon="refresh"
class="btnNewVersShow" @click="RefreshApp()" :label="t('notification.newVersionAvailable')">
</q-btn>
<q-toolbar-title class="row items-center">
<q-avatar>
<img :src="imglogo()" height="27" alt="Immagine Logo">
</q-avatar>
<div class="q-mx-sm titlesite">{{ getappname() }}</div>
<template v-slot:subtitle>
<div>{{ t('msg.myDescriz') }} {{ getAppVersion() }}</div>
</template>
</q-toolbar-title>
<!--
<div v-if="isAdmin">
<q-btn flat dense round aria-label="">
<q-icon :class="clCloudUpload" nametranslate="cloud_upload"></q-icon>
</q-btn>
<q-btn flat dense round aria-label="">
<q-icon :class="clCloudUp_Indexeddb" nametranslate="arrow_upward"></q-icon>
</q-btn>
</div>
-->
<q-btn
v-if="!isonline && static_data.functionality.SHOW_IF_IS_SERVER_CONNECTION"
flat
dense
round
aria-label="Connection"
>
<q-icon :name="iconConn" :class="clIconConn"></q-icon>
<q-icon v-if="isUserNotAuth" name="device_unknown"></q-icon>
</q-btn>
<q-btn-dropdown
stretch
v-if="static_data.lang_available.length > 1"
flat
:label="langshort"
auto-close
>
<q-list bordered>
<q-item
clickable v-ripple
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" alt="flag">
</q-item-section>
<q-item-section>
{{ langrec.label }}
</q-item-section>
</q-item>
</q-list>
</q-btn-dropdown>
<div v-if="static_data.functionality.SHOW_MESSAGES">
<message-popover></message-popover>
</div>
<!--
<div class="right-itens">
<label>{{ t('msg.hello') }}</label> <span v-model="prova"></span> !
</div>-->
<!-- BUTTON USER BAR -->
<q-btn
class="q-mx-xs" v-if="static_data.functionality.SHOW_USER_MENU && !isLogged" dense flat round
icon="menu"
@click="rightDrawerOpen = !rightDrawerOpen">
</q-btn>
<q-btn
class="q-mx-xs" v-if="static_data.functionality.ENABLE_ECOMMERCE && isLogged" round dense flat
@click="rightCartOpen = !rightCartOpen" icon="fas fa-shopping-cart">
<q-badge v-if="getnumItemsCart > 0" color="red" floating transparent>
{{ getnumItemsCart }}
</q-badge>
</q-btn>
<q-btn
class="q-mx-xs" v-if="static_data.functionality.ENABLE_ECOMMERCE && isLogged && getnumOrdersCart > 0"
round dense flat
to="/orderinfo" icon="fas fa-list-ol">
<q-badge v-if="getnumOrdersCart > 0" color="blue" floating transparent>
{{ getnumOrdersCart }}
</q-badge>
</q-btn>
<q-btn
class="q-mx-xs" v-if="static_data.functionality.SHOW_USER_MENU && isLogged" round dense flat
@click="rightDrawerOpen = !rightDrawerOpen" :icon="getMyImgforIcon" :color="getcolormenu">
<!--<q-badge v-if="isSocio" color="green" floating transparent>
s
</q-badge>-->
</q-btn>
</q-toolbar>
</q-header>
<q-drawer
side="left"
bordered
show-if-above
:breakpoint="500"
v-model="leftDrawerOpen"
:content-class="['bg-grey-1', 'q-pa-sm']"
:content-style="{padding: '0px'}"
>
<drawer :clBase="clBase"></drawer>
</q-drawer>
<!-- USER BAR -->
<q-drawer v-if="static_data.functionality.ENABLE_ECOMMERCE" v-model="rightCartOpen" side="right" elevated>
<q-btn
class="absolute-top-right" style="margin-right: 10px; color: white;"
dense flat round icon="close" @click="rightCartOpen = !rightCartOpen">
</q-btn>
<div v-if="isLogged" class="text-weight-bold text-cart">Carrello
</div>
<CMyCart></CMyCart>
</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="images/landing_first_section.png"
style="height: 150px" alt="section page">
</q-img>
<div class="absolute-top bg-transparent text-black center_img" style="margin-top: 10px;">
<div class="text-center q-ma-xs boldhigh text-white text-h7">Area Personale</div>
<CMyAvatar :myimg="getMyImg"></CMyAvatar>
<q-btn
class="absolute-top-right" style="margin-right: 10px; color: white;"
dense flat round icon="close" @click="rightDrawerOpen = !rightDrawerOpen">
</q-btn>
<div v-if="isLogged" class="text-weight-bold text-user">{{ Username }} - {{ myName }}
</div>
<div class="row justify-evenly q-pa-xs-sm">
<div v-if="isLogged && isAdmin" class="text-weight-bold text-user bg-red q-px-xs">Admin</div>
<div v-if="isSocio" class="text-weight-bold text-user q-px-xs">Socio</div>
<div v-if="isSocioResidente" class="text-weight-bold text-user q-px-xs bg-amber">Residente</div>
<div v-if="isConsiglio" class="text-weight-bold text-user q-px-xs bg-deep-orange-10">Consiglio</div>
<div v-if="isManager" class="text-weight-bold text-user bg-blue q-px-xs">Segreteria</div>
<div v-if="isTutor" class="text-weight-bold text-user q-px-xs">Tutor</div>
<div v-if="isTratuttrici" class="text-weight-bold text-user q-px-xs">Editor</div>
</div>
<div v-if="!isLogged" class="text-user text-italic bg-red">
{{ t('user.loggati') }}
</div>
<div v-if="isLogged && !isEmailVerified" class="text-verified">{{
t('components.authentication.email_verification.verify_email')
}}
</div>
<!--<span class="text-white" v-if="Verificato"> {{t('reg.verificato')}} </span>-->
<!--<span class="text-white background-red" v-else> {{t('reg.non_verificato')}} </span>-->
<div v-if="isLogged" id="user-actions" class="column justify-center q-gutter-sm q-ma-sm center-150">
<q-btn rounded color="primary" icon="person" to="/profile">{{ t('pages.profile') }}</q-btn>
<!--<q-btn round color="warning" icon="lock"></q-btn>-->
<q-btn rounded color="negative" icon="exit_to_app" @click='logoutHandler'>{{ t('login.esci') }}</q-btn>
</div>
</div>
<div style="margin-top:120px;"></div>
<div v-show="!isLogged">
<div class="q-ma-md" style="">
<CSigninNoreg :showregbutt="true">
</CSigninNoreg>
</div>
</div>
</div>
<div v-if="isLogged" class="q-mt-lg"></div>
<slot></slot>
</q-drawer>
</div>
</template>
<script lang="ts" src="./Header.ts">
</script>
<style lang="scss" scoped>
@import './Header.scss';
</style>

1
src/components/Header/index.ts Executable file
View File

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

11
src/components/index.ts Executable file
View File

@@ -0,0 +1,11 @@
export * from './logo'
export * from './CMyPage'
export * from './CTitle'
export * from './CImgTitle'
export * from './BannerCookies'
export * from './testpao'
export * from './Footer'
export * from './FormNewsletter'
// export * from './PagePolicy'
// export * from './CFacebookFrame'
// export * from './CPreloadImages'

1
src/components/logo/index.ts Executable file
View File

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

39
src/components/logo/logo.scss Executable file
View File

@@ -0,0 +1,39 @@
.svgclass {
color: white;
transform: translateY(0px);
}
.svgclass_animate {
transform: translateY(-70px);
color: red;
}
#sun {
animation: gravity 5s infinite;
}
#logoimg {
height: 50px;
width: auto;
@media screen and (max-width: 600px) {
}
}
@keyframes gravity {
0% {
transform: rotateY(0deg);
}
100% {
transform: rotateY(360deg);
}
}
#smile {
opacity: 0.1 !important;
fill: red;
}

33
src/components/logo/logo.ts Executable file
View File

@@ -0,0 +1,33 @@
import {
defineComponent,
} from 'vue'
import { tools } from '@src/store/Modules/tools'
import { useQuasar } from 'quasar'
import { useI18n } from '@src/boot/i18n'
export default defineComponent({
name: 'Logo',
props: {
mystyle: {
type: Boolean,
required: false,
default: false,
},
},
setup() {
function logoimg() {
return `${tools.getimglogo()}`
}
function logoalt() {
const { t } = useI18n();
return t('ws.sitename')
}
return {
logoimg,
logoalt,
}
},
})

11
src/components/logo/logo.vue Executable file
View File

@@ -0,0 +1,11 @@
<template>
<div id="logo">
<img id="logoimg" :alt="logoalt()" :src=logoimg() :style="mystyle">
</div>
</template>
<script lang="ts" src="./logo.ts">
</script>
<style lang="scss" scoped>
@import './logo.scss';
</style>

8
src/components/models.ts Executable file
View File

@@ -0,0 +1,8 @@
export interface Todo {
id: number;
content: string;
}
export interface Meta {
totalCount: number;
}

View File

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

View File

@@ -0,0 +1,39 @@
.svgclass {
color: white;
transform: translateY(0px);
}
.svgclass_animate {
transform: translateY(-70px);
color: red;
}
#sun {
animation: gravity 5s infinite;
}
#logoimg {
height: 50px;
width: auto;
@media screen and (max-width: 600px) {
}
}
@keyframes gravity {
0% {
transform: rotateY(0deg);
}
100% {
transform: rotateY(360deg);
}
}
#smile {
opacity: 0.1 !important;
fill: red;
}

View File

@@ -0,0 +1,41 @@
import {
defineComponent,
} from 'vue'
import { tools } from '@src/store/Modules/tools'
import { static_data } from '@src/db/static_data'
import { useQuasar } from 'quasar'
import { useGlobalStore } from '@store/globalStore'
import { FormNewsletter } from '../FormNewsletter'
import { MixinBase } from '../../mixins/mixin-base'
import { Logo } from '../logo'
import { useI18n } from '@src/boot/i18n'
export default defineComponent({
name: 'TestPao',
mixins: [MixinBase],
components: { Logo, FormNewsletter },
props: {
mystyle: {
type: Boolean,
required: false,
default: false,
},
},
setup() {
function logoimg() {
return `${tools.getimglogo()}`
}
function logoalt() {
const { t } = useI18n();
return t('ws.sitename')
}
return {
logoimg,
logoalt,
}
},
})

View File

@@ -0,0 +1,11 @@
<template>
<div id="logo">
<img id="logoimg" :alt="logoalt()" :src=logoimg() :style="mystyle">
</div>
</template>
<script lang="ts" src="./testpao.ts">
</script>
<style lang="scss" scoped>
@import './testpao.scss';
</style>