Merge pull request #19 from paoloar77/UserProfile

User profile
This commit is contained in:
Paolo Arena
2019-03-18 00:04:38 +01:00
committed by GitHub
156 changed files with 11513 additions and 32964 deletions

View File

@@ -1,39 +0,0 @@
{
"env": {
"test": {
"presets": [
[
"@babel/preset-env",
{
"modules": "commonjs",
"targets": {
"node": "current"
}
}
]
]
}
},
"presets": [
[
"@babel/preset-env",
{
"modules": false,
"loose": false,
"useBuiltIns": "usage"
}
]
],
"plugins": [
[
"@babel/plugin-transform-runtime",
{
"corejs": false,
"regenerator": false,
"helpers": true,
"useESModules": false
}
]
],
"comments": false
}

2
.gitignore vendored
View File

@@ -2,8 +2,8 @@
.DS_Store
.thumbs.db
.env
.env.development
.env.production
.env.development
.env.production.bak
.env.prod.bak
.env.test

5
babel.config.js Normal file
View File

@@ -0,0 +1,5 @@
module.exports = {
presets: [
'@quasar/babel-preset-app'
]
}

25118
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -18,13 +18,14 @@
"test:cover": "jest --coverage",
"build": "quasar build -m pwa",
"build:clean": "quasar clean",
"serve": "quasar serve ./dist/pwa-mat",
"serve": "quasar serve ./dist/pwa",
"serve:coverage": "quasar serve test/coverage/lcov-report/ --cache 0 --port 8788",
"deploy": "deploy.sh",
"deploy_server_test": "NODE_ENV=test quasar build -m pwa",
"generate-sw": "workbox generateSW workbox-config.js"
},
"dependencies": {
"@quasar/extras": "^1.1.0",
"@types/vuelidate": "^0.7.0",
"acorn": "^6.0.0",
"axios": "^0.18.0",
@@ -43,8 +44,8 @@
"normalize.css": "^8.0.0",
"npm": "^6.4.1",
"nprogress": "^0.2.0",
"quasar": "^1.0.0-beta.10",
"quasar-extras": "^2.0.8",
"quasar-framework": "0.17.17",
"register-service-worker": "^1.0.0",
"vee-validate": "^2.1.2",
"vue": "^2.5.17",
@@ -53,6 +54,7 @@
"vue-idb": "^0.2.0",
"vue-property-decorator": "^7.2.0",
"vue-router": "^3.0.1",
"vue-scroll-reveal": "^1.0.11",
"vue-svgicon": "^3.1.0",
"vue2-dragula": "^2.5.4",
"vuelidate": "^0.7.4",
@@ -74,10 +76,12 @@
"@babel/template": "7.0.0-beta.54",
"@babel/traverse": "7.0.0-beta.54",
"@babel/types": "7.0.0-beta.54",
"@quasar/app": "^1.0.0-beta.11",
"@quasar/quasar-app-extension-typescript": "^1.0.0-alpha.11",
"@types/dotenv": "^4.0.3",
"@types/jest": "^23.1.4",
"@types/js-cookie": "^2.1.0",
"@types/node": "^10.12.2",
"@types/node": "11.9.5",
"@types/nprogress": "^0.0.29",
"@types/webpack-env": "^1.13.6",
"@vue/babel-preset-app": "3.1.1",
@@ -96,8 +100,8 @@
"jest": "^23.6.0",
"json-loader": "^0.5.4",
"node-sass": "^4.11.0",
"optimize-css-assets-webpack-plugin": "^5.0.1",
"postcss-loader": "^3.0.0",
"quasar-cli": "^0.17.23",
"sass-loader": "^7.1.0",
"strip-ansi": "=3.0.1",
"ts-jest": "^23.0.0",

View File

@@ -54,26 +54,30 @@ const extendHTMLToWebpack = (config) => {
module.exports = function (ctx) {
return {
htmlVariables: {
appName: 'FreePlanet',
appDescription: 'The first Real Social, Free, Fair and Equitable'
},
// Quasar looks for *.js files by default
sourceFiles: {
router: 'src/router/index.ts',
store: 'src/store/index.ts'
},
// app plugins (/src/plugins)
plugins: ['i18n', 'axios', 'vee-validate', 'myconfig', 'local-storage', 'error-handler', 'globalroutines', 'vue-idb', 'dragula', 'guard'],
boot: ['vue-i18n', 'axios', 'vee-validate', 'myconfig', 'local-storage', 'error-handler', 'globalroutines', 'vue-idb', 'dragula', 'guard'],
css: [
'app.styl'
],
extras: [
//ctx.theme.mat ? : null,
'roboto-font',
'material-icons', // optional, you are not bound to it
'ionicons',
// 'mdi',
'fontawesome'
'ionicons-v4',
// 'mdi-v3',
'fontawesome-v5'
],
supportIE: false,
aliases: {
quasar: path.resolve(__dirname, '../node_modules/quasar-framework/'),
quasar: path.resolve(__dirname, '../node_modules/@quasar/'),
src: path.resolve(__dirname, '../src'),
statics: path.resolve(__dirname, '../src/statics'),
components: path.resolve(__dirname, '../src/components')
@@ -94,7 +98,7 @@ module.exports = function (ctx) {
.alias
.set('~', __dirname)
.set('@', helpers.root('src'))
// .set('env', helpers.root('config/helpers/env.js'))
// .set('env', helpers.root('config/helpers/env.js'))
config.module
.rule('template-engine')
.test(/\.pug$/)
@@ -118,57 +122,57 @@ module.exports = function (ctx) {
framework: {
components: [
'QLayout',
'QLayoutHeader',
'QLayoutDrawer',
'QDrawer',
'QItemSection',
'QHeader',
'QFooter',
'QPageContainer',
'QPage',
'QPopupProxy',
'QToolbar',
'QToolbarTitle',
'QBtn',
'QBtnDropdown',
'QIcon',
'QList',
'QListHeader',
'QItemLabel',
'QItem',
'QItemMain',
'QItemTile',
'QItemSide',
'QCard',
'QCardTitle',
'QCardMain',
'QCardMedia',
'QCardSeparator',
'QCardSection',
'QCardActions',
'QField',
'QInput',
'QSelect',
'QPopover',
'QMenu',
'QToggle',
'QFab',
'QInfiniteScroll',
'QAjaxBar',
'QChip',
'QCollapsible',
'QExpansionItem',
'QCheckbox',
'QAlert',
'QBanner',
'QInnerLoading',
'QSpinnerGears',
'QDatetime',
'QDate',
'QTime',
'QSlideTransition',
'QTable',
'QTableColumns',
'QTh',
'QTr',
'QSearch',
'QTd',
'QContextMenu',
'QProgress',
'QLinearProgress',
'QSlider',
'QPopupEdit',
'QCarousel',
'QCarouselControl',
'QPageScroller',
'QAvatar',
'QImg',
'QCarouselSlide'
],
directives: [
'Ripple',
'CloseOverlay',
],
// Quasar plugins
plugins: [
@@ -176,12 +180,12 @@ module.exports = function (ctx) {
'Dialog',
'Notify',
'Cookies',
'ActionSheet', 'Loading'
'Loading'
],
iconSet: 'fontawesome',
i18n: 'it', // Quasar language
iconSet: 'fontawesome-v5',
lang: 'it', // Quasar language
},
animations: [],
animations: 'all',
ssr: {
pwa: {
runtimeCaching: [
@@ -203,10 +207,12 @@ module.exports = function (ctx) {
// workboxPluginMode: 'GenerateSW',
workboxPluginMode: 'InjectManifest',
workboxOptions: {
// skipWaiting: true,
// clientsClaim: true
// swSrc: 'src/sw.js',
},
manifest: {
name: 'Free Planet',
name: 'FreePlanet',
version: '0.0.14',
short_name: 'freeplanet',
description: 'Social project in order to connecting people each others (working in progress...)',

6
quasar.extensions.json Normal file
View File

@@ -0,0 +1,6 @@
{
"@quasar/typescript": {
"webpack": "plugin",
"rename": true
}
}

View File

@@ -81,7 +81,7 @@ if (workbox) {
workbox.routing.registerRoute(
new RegExp(/\.(?:png|gif|jpg|jpeg|svg)$/),
workbox.strategies.staleWhileRevalidate({
new workbox.strategies.CacheFirst({
cacheName: 'images',
plugins: [
new workbox.expiration.Plugin({
@@ -92,6 +92,23 @@ if (workbox) {
}),
);
// Per Articoli....
const articleHandler = workbox.strategies.networkFirst({
cacheName: 'articles-cache',
plugins: [
new workbox.expiration.Plugin({
maxEntries: 50,
})
]
});
workbox.routing.registerRoute(
new RegExp(/(.*)article(.*)\.html/), args => {
return articleHandler.handle(args);
});
workbox.routing.registerRoute(
new RegExp(/.*(?:googleapis|gstatic)\.com.*$/),
workbox.strategies.staleWhileRevalidate({
@@ -207,7 +224,7 @@ if (workbox) {
workbox.routing.registerRoute(
new RegExp(/.*\/(?:statics\/icons).*$/),
workbox.strategies.cacheFirst({
new workbox.strategies.CacheFirst({
cacheName: 'image-cache',
plugins: [
new workbox.expiration.Plugin({
@@ -218,18 +235,13 @@ if (workbox) {
);
workbox.routing.registerRoute(
new RegExp(/.*\/(?:css|font).*/),
workbox.strategies.cacheFirst({
cacheName: 'css-fonts',
plugins: [
new workbox.expiration.Plugin({
maxAgeSeconds: 30 * 24 * 60 * 60,
}),
]
})
new RegExp(/\.(?:js|css|font)$/),
new workbox.strategies.StaleWhileRevalidate( {
cacheName: 'js-css-fonts',
}),
);
/*
workbox.routing.registerRoute(
new RegExp('https://cdnjs.coudflare.com/ajax/libs/material-design-lite/1.3.0/material.indigo-pink.min.css'),
workbox.strategies.staleWhileRevalidate({
@@ -241,6 +253,7 @@ if (workbox) {
]
})
);
*/
// Storage
workbox.routing.registerRoute(
@@ -259,7 +272,7 @@ if (workbox) {
workbox.routing.registerRoute(
new RegExp(/.*\/(?:statics).*$/),
workbox.strategies.cacheFirst({
new workbox.strategies.CacheFirst({
cacheName: 'statics',
plugins: [
new workbox.expiration.Plugin({
@@ -270,6 +283,7 @@ if (workbox) {
})
);
/*
workbox.routing.registerRoute(
new RegExp(/^http/),
workbox.strategies.networkFirst({
@@ -282,6 +296,7 @@ if (workbox) {
]
})
);
*/
workbox.routing.registerRoute(
@@ -289,6 +304,10 @@ if (workbox) {
workbox.strategies.networkOnly()
);
workbox.routing.registerRoute(
new RegExp('/owa/'),
workbox.strategies.networkOnly()
);
}

View File

@@ -39,3 +39,14 @@
transform: translateX(1600px);
}
}
.my-notif-class{
font-weight: bold;
}
.mybanner {
font-weight: bold;
font-size: 1.1rem;
text-align: center;
}

View File

@@ -1,17 +1,13 @@
import Vue from 'vue'
import { Component } from 'vue-property-decorator'
import { UserStore } from '@store'
import { EventBus, RootState, storeBuilder, DebugMode } from '@store'
import router from './router'
import $ from 'jquery'
import Header from './components/Header.vue'
import { Header } from './components/Header'
import globalroutines from './globalroutines/index'
import { GlobalStore } from './store/Modules'
@Component({
components: {
appHeader: Header
@@ -19,25 +15,24 @@ import { GlobalStore } from './store/Modules'
router
})
export default class App extends Vue {
public backgroundColor = 'whitesmoke'
public $q
public listaRoutingNoLogin = ['/vreg?', '/offline']
meta () {
public meta() {
return {
keywords: { name: 'keywords', content: 'WebSite' },
// meta tags
meta: {
mykey: { name: 'mykey', content: 'Key 1' },
keywords: { name: 'keywords', content: 'MyKeywords' }
keywords: { name: 'keywords', content: 'MyKeywords' },
mykey: { name: 'mykey', content: 'Key 1' }
}
}
}
created() {
public created() {
if (process.env.DEV) {
console.info('SESSIONE IN SVILUPPO ! (DEV)')
console.info(process.env)

View File

@@ -1,22 +1,21 @@
<template>
<div id="q-app">
<q-layout :style="">
<app-header></app-header>
<div class="layout-view">
<div>
<q-layout view="hHh Lpr lff" class="shadow-2 rounded-borders">
<app-header></app-header>
<q-ajax-bar></q-ajax-bar>
<q-page-container>
<transition name="fade" mode="out-in">
<router-view/>
</transition>
</q-page-container>
</div>
</q-layout>
<!--<appsignup v-show="true" @close="myshowModal=false"></appsignup>-->
</q-layout>
</div>
</div>
</template>
<script lang="ts" src="./App.ts">
</script>
<style lang="scss" scoped>
<style lang="scss">
@import './App.scss';
</style>

View File

@@ -1,9 +1,6 @@
// import something here
// leave the export, even if you don't use it
export default ({ app, router, store, Vue }) => {
// something to do
// ******************************************
// *** Per non permettere di accedere alle pagine in cui è necessario essere Loggati ! ***
// ******************************************
@@ -15,7 +12,7 @@ export default ({ app, router, store, Vue }) => {
const subsequentMiddleware = middleware[index]
// If no subsequent Middleware exists,
// the default `next()` callback is returned.
if (!subsequentMiddleware) return context.next
if (!subsequentMiddleware) { return context.next }
return (...parameters) => {
// Run the default Vue Router `next()` callback first.
@@ -24,7 +21,7 @@ export default ({ app, router, store, Vue }) => {
// `nextMiddleware()` callback.
const nextMiddleware = nextFactory(context, middleware, index + 1)
subsequentMiddleware({ ...context, next: nextMiddleware })
};
}
}
router.beforeEach((to, from, next) => {

View File

@@ -1,62 +0,0 @@
import { LocalStorage } from 'quasar'
// import { onFail } from '../../_LOCALE/src/session/logout'
// import appSetup from './app-setup'
import config from '../config'
var authorized = false
export default () => {
if (config.localStorage.enableListener) {
window.addEventListener('storage', (e) => {
if (!authorized) {
console.warn('Unauthorized local storage change')
switch (config.localStorage.unauthChange) {
case 'block':
if (e.key === 'null' || e.key === null) {
reload()
} else {
_LocalStorage.setNative(e.key, e.oldValue)
}
break
case 'clear':
reload()
break
default:
reload()
break
}
}
}, false)
}
return Promise.resolve(true)
}
const reload = () => {
// onFail().then(success => appSetup())
}
export const _LocalStorage = {
setNative (key, value) {
authorized = true
localStorage.setItem(key, value)
authorized = false
},
set (key, value) {
authorized = true
LocalStorage.set(key, value)
authorized = false
},
remove (key) {
authorized = true
LocalStorage.remove(key)
authorized = false
},
clear () {
authorized = true
LocalStorage.clear()
authorized = false
},
get (key) {
return LocalStorage.get.item(key)
}
}

View File

@@ -1,5 +1,5 @@
// import something here
import { _LocalStorage } from '../boot/local-storage'
import { _LocalStorage } from '../local-storage'
// leave the export, even if you don't use it
export default ({ app, router, Vue }) => {
// something to do

View File

@@ -3,7 +3,7 @@ import myconfig from '../myconfig'
// leave the export, even if you don't use it
export default ({ Vue }) => {
//Vue.use(myconfig);
// Vue.use(myconfig);
// something to do
Vue.prototype.$myconfig = myconfig
}

View File

@@ -0,0 +1,8 @@
// import something here
import track from '../track'
// leave the export, even if you don't use it
export default ({ app, router, store, Vue }) => {
// something to do
Vue.prototype.$track = track
}

27
src/boot/vue-i18n.ts Normal file
View File

@@ -0,0 +1,27 @@
// src/boot/vue-i18n.js
import VueI18n from 'vue-i18n'
import messages from '../statics/i18n'
import { tools } from '../store/Modules/tools'
export default ({ app, store, Vue }) => {
Vue.use(VueI18n)
// Vue.config.lang = process.env.LANG_DEFAULT;
let mylang = tools.getItemLS(tools.localStorage.lang)
if ((navigator) && (mylang === '')) {
mylang = navigator.language
// console.log(`LANG NAVIGATOR ${mylang}`)
}
mylang = tools.checkLangPassed(mylang)
Vue.config.lang = mylang
// Set i18n instance on app
app.i18n = new VueI18n({
fallbackLocale: mylang,
locale: mylang,
messages
})
}

7
src/boot/vue-idb.ts Normal file
View File

@@ -0,0 +1,7 @@
import Vue from 'vue'
import VueIdb from 'vue-idb'
export default ({ Vue }) => {
Vue.use(VueIdb)
}

View File

@@ -1,17 +0,0 @@
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex);
export const cfg = new Vue({
state:{
lang: 'en'
},
data: {
cost: {
MYAPPMOD_ATTUALE: 'freeplanet',
//MYAPPMOD_ATTUALE: 'karpos',
AA: ''
}
}
});

View File

@@ -1,16 +1,19 @@
export async function askConfirm($q: any, mytitle, mytext, ok, cancel) {
try {
return await $q.dialog({
title: mytitle,
cancel: {
label: cancel
},
message: mytext,
ok: ok,
cancel: cancel
ok: {
label: ok,
push: true
},
title: mytitle
}).then((ris) => {
return true
// this.$q.notify('Agreed!')
return ris
}).catch(() => {
return false
// this.$q.notify('Disagreed...')
})
} catch (e) {
return false

View File

@@ -1,714 +0,0 @@
<template>
<div>
<!--
<router-link :to="'/'" v-if="$router.currentRoute.meta.backButton">
<button>
<i>arrow_back</i>
</button>
</router-link>
-->
<q-layout-header>
<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 id="newvers" v-if="isNewVersionAvailable" color="secondary" rounded icon="refresh"
class="btnNewVersShow" @click="RefreshApp" :label="$t('notification.newVersionAvailable')"/>
<q-toolbar-title>
{{$t('msg.myAppName')}}
<div slot="subtitle">{{$t('msg.myDescriz')}} {{ getAppVersion() }}</div>
</q-toolbar-title>
<div v-if="isAdmin">
<q-btn flat dense round aria-label="">
<q-icon :class="clCloudUpload" name="cloud_upload"></q-icon>
</q-btn>
<q-btn flat dense round aria-label="">
<q-icon :class="clCloudUp_Indexeddb" name="arrow_upward"></q-icon>
</q-btn>
</div>
<q-btn
flat
dense
round
@click=""
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
:label="langshort"
>
<q-list link>
<q-item v-for="langrec in selectOpLang" :key="langrec.value" v-close-overlay
@click.native="lang = langrec.value">
<q-item-side>
<img :src="langrec.image" class="flagimg">
</q-item-side>
<q-item-main>
<q-item-tile sublabel>{{langrec.label}}</q-item-tile>
</q-item-main>
</q-item>
</q-list>
</q-btn-dropdown>
<!--
<message-popover></message-popover>
-->
<!--
<div class="right-itens">
<label>{{ $t('msg.hello') }}</label> <span v-model="prova"></span> !
</div>-->
</q-toolbar>
</q-layout-header>
<q-layout-drawer side="left"
v-model="leftDrawerOpen"
:content-class="['bg-grey-1', 'q-pa-sm']"
:content-style="{padding: '0px'}"
>
<drawer></drawer>
</q-layout-drawer>
</div>
</template>
<script lang="ts">
import Vue from 'vue'
import Component from 'vue-class-component'
import drawer from '../layouts/drawer/drawer.vue'
import messagePopover from '../layouts/toolbar/messagePopover/messagePopover.vue'
import { GlobalStore, UserStore } from '@modules'
import { tools } from '../store/Modules/tools'
import QIcon from "quasar-framework/src/components/icon/QIcon"
import { StateConnection } from "../model"
import { Watch } from "vue-property-decorator"
import QField from "quasar-framework/src/components/field/QField"
@Component({
components: {
QField,
QIcon,
drawer,
messagePopover,
}
})
export default class Header extends Vue {
public $t
public $v
public $q
public isUserNotAuth: boolean = false
public iconConn: string = 'wifi'
public clIconConn: string = 'clIconOnline'
public strConn: string = ''
public langshort: string = ''
public clCloudUpload: string = ''
public clCloudDownload: string = ''
public clCloudUp_Indexeddb: string = ''
public clCloudDown_Indexeddb: string = 'clIndexeddbsend'
get conn_changed() {
return GlobalStore.state.stateConnection
}
get isAdmin() {
return UserStore.state.isAdmin
}
get conndata_changed() {
return GlobalStore.state.connData
}
@Watch('GlobalStore.state.stateConnection', { immediate: true, deep: true })
changeconn(value: string, oldValue: string) {
this.strConn = value
// this.$q.notify({
// color : 'primary',
// icon: 'wifi',
// message: "CAMBIATOO! " + value
// })
}
@Watch('conndata_changed', { immediate: true, deep: true })
changeconnData(value: any, oldValue: any) {
// console.log('CHANGED GlobalStore.state.connData', value)
this.clCloudUpload = (value.uploading_server === 1) ? "clCloudUpload send" : "clCloudUpload"
this.clCloudUpload = (value.downloading_server === 1) ? "clCloudUpload receive" : "clCloudUpload"
this.clCloudUp_Indexeddb = (value.uploading_indexeddb === 1) ? "clIndexeddb send" : "clIndexeddb"
this.clCloudUp_Indexeddb = (value.downloading_indexeddb === 1) ? "clIndexeddb receive" : "clIndexeddb"
this.clCloudUpload = (value.uploading_server === -1) ? "clCloudUpload error" : this.clCloudUpload
this.clCloudUpload = (value.downloading_server === -1) ? "clCloudUpload error" : this.clCloudDownload
this.clCloudUp_Indexeddb = (value.uploading_indexeddb === -1) ? "clIndexeddb error" : this.clCloudUp_Indexeddb
this.clCloudUp_Indexeddb = (value.downloading_indexeddb === -1) ? "clIndexeddb error" : this.clCloudDown_Indexeddb
// console.log('clCloudUpload', this.clCloudUpload)
// console.log('clCloudDownload', this.clCloudDownload)
// console.log('clCloudUp_Indexeddb', this.clCloudUp_Indexeddb)
// console.log('value.downloading_indexeddb', value.downloading_indexeddb)
// console.log('value.uploading_server', value.uploading_server)
}
@Watch('conn_changed', { immediate: true, deep: true })
changeconn_changed(value: string, oldValue: string) {
if (value != oldValue) {
// console.log('SSSSSSSS: ', value, oldValue)
const color = (value === 'online') ? 'positive' : 'warning'
if (oldValue !== undefined) {
this.$q.notify({
color,
icon: 'wifi',
message: this.$t('connection') + ` ${value}`
})
}
this.changeIconConn()
}
}
get isNewVersionAvailable() {
console.log('______________ isNewVersionAvailable')
return GlobalStore.getters.isNewVersionAvailable
}
RefreshApp() {
// Unregister Service Worker
navigator.serviceWorker.getRegistrations().then(function(registrations) {
for(let registration of registrations) {
registration.unregister()
} })
window.location.reload(true)
}
changeIconConn() {
this.iconConn = GlobalStore.state.stateConnection === 'online' ? "wifi" : "wifi_off"
this.clIconConn = GlobalStore.state.stateConnection === 'online' ? 'clIconOnline' : 'clIconOffline'
}
public selectOpLang = [
{ label: 'English', icon: 'fa-flag-us', value: 'enUs', image: '../statics/images/gb.png', short: 'EN' },
// { label: 'German', icon: 'fa-flag-de', value: 'de', image: '../statics/images/de.png', short: 'DE' },
{ label: 'Italiano', icon: 'fa-facebook', value: 'it', image: '../statics/images/it.png', short: 'IT' },
{ label: 'Español', icon: 'fa-flag-es', value: 'esEs', image: '../statics/images/es.png', short: 'ES' }
]
// -------------------------------------------------------------------------
// QUASAR Example using event to open drawer from another component or page
// -------------------------------------------------------------------------
// (1) This code is inside layout file that have a drawer
// if this.leftDrawerOpen is true, drawer is displayed
// (2) Listen for an event in created
/* created(){
this.$root.$on("openLeftDrawer", this.openLeftDrawercb);
},
methods: {
openURL,
// (3) Define the callback in methods
openLeftDrawercb() {
this.leftDrawerOpen = !this.leftDrawerOpen;
}
}
// (4) In another component or page, emit the event!
// Call the method when clicking button etc.
methods: {
openLeftDrawer() {
this.$root.$emit("openLeftDrawer");
}
}
// -------------------------------------------------------------------------
*/
get leftDrawerOpen() {
return GlobalStore.state.leftDrawerOpen
}
set leftDrawerOpen(value) {
GlobalStore.state.leftDrawerOpen = value
localStorage.setItem(tools.localStorage.leftDrawerOpen, value.toString())
}
getAppVersion() {
// return "AA"
let strv = ''
if (process.env.DEV) {
strv = 'DEV '
} else if (process.env.TEST) {
strv = 'TEST '
}
return "[" + strv + process.env.APP_VERSION + "]"
}
get lang() {
return this.$q.i18n.lang
}
setshortlang(lang) {
for (let indrec in this.selectOpLang) {
if (this.selectOpLang[indrec].value === lang) {
// console.log('this.selectOpLang[indrec].short', this.selectOpLang[indrec].short, this.selectOpLang[indrec].value)
this.langshort = this.selectOpLang[indrec].short
return
}
}
}
set lang(lang) {
console.log('set lang(' + this.$i18n.locale)
this.$i18n.locale = this.snakeToCamel(lang)
// this.$q.notify('IMPOSTA LANG= ' + this.$i18n.locale)
// console.log('IMPOSTA LANG= ' + this.$i18n.locale)
UserStore.mutations.setlang(this.$i18n.locale)
let mylangtopass = lang
this.setshortlang(mylangtopass)
if (mylangtopass === 'enUs')
mylangtopass = 'en-us'
if (mylangtopass === 'esEs')
mylangtopass = 'es'
// dynamic import, so loading on demand only
import(`quasar-framework/i18n/${mylangtopass}`).then(lang => {
this.$q.i18n.set(lang.default)
import(`src/statics/i18n`).then(function () {
})
})
}
getLangAtt() {
return this.$q.i18n.lang
}
setLangAtt(mylang) {
console.log('MYLL=', mylang)
this.$q.i18n.lang = mylang
}
beforeMount() {
// Estrai la Lang dal Localstorage
let my = this.getLangAtt()
// this.$q.notify('prima: ' + String(my))
let mylang = tools.getItemLS(tools.localStorage.lang)
if (mylang === '') {
if (navigator) {
mylang = navigator.language
console.log(`LANG2 NAVIGATOR ${mylang}`)
} else {
mylang = this.$q.i18n.lang
}
console.log('IMPOSTA LANGMY', mylang)
}
if (mylang !== '') {
if (mylang.toLowerCase() === 'enus')
mylang = 'enUs'
if ((mylang.toLowerCase() === 'eses') || (mylang.toLowerCase() === 'es-es'))
mylang = 'esEs'
if ((mylang.toLowerCase() === 'enus') || (mylang.toLowerCase() === 'en-us'))
mylang = 'enUs'
}
if (!mylang)
mylang = process.env.LANG_DEFAULT
this.setLangAtt(mylang)
this.setshortlang(mylang)
// this.$q.notify('Dopo: ' + String(this.getLangAtt()))
}
mounted() {
// Test this by running the code snippet below and then
// use the "TableOnlyView" checkbox in DevTools Network panel
let mythis = this
// console.log('Event LOAD')
if (window) {
window.addEventListener('load', function () {
// console.log('2) ENTERING Event LOAD')
function updateOnlineStatus(event) {
if (navigator.onLine) {
// console.log('EVENT ONLINE!')
// handle online status
GlobalStore.mutations.setStateConnection('online')
mythis.changeIconConn()
} else {
// console.log('EVENT OFFLINE!')
// handle offline status
GlobalStore.mutations.setStateConnection('offline')
mythis.changeIconConn()
}
}
window.addEventListener('online', updateOnlineStatus)
window.addEventListener('offline', updateOnlineStatus)
})
}
}
public snakeToCamel(str) {
return str.replace(/(-\w)/g, m => {
return m[1].toUpperCase()
})
}
}
</script>
<style lang="scss">
.layout-padding {
padding: 1em 4em;
}
.item-content {
font-size: 0.8rem;
font-weight: 350;
}
@media screen and (max-width: 600px) {
.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;
}
.underline {
text-decoration: underline;
}
.toolbar {
min-height: 30px;
}
.right-itens a, .right-itens button {
margin-right: 10px;
}
.sel_lang {
padding: 5px;
color: white;
}
.fa-facebook:before {
content: url('../statics/icons/flag_it.svg');
}
.fa-flag-it:before {
content: url('../statics/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;
}
</style>

View File

@@ -0,0 +1,288 @@
.layout-padding {
padding: 1em 4em;
}
.item-content {
font-size: 0.8rem;
font-weight: 350;
}
@media screen and (max-width: 600px) {
.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;
}
.underline {
text-decoration: underline;
}
.toolbar {
min-height: 30px;
}
.right-itens a, .right-itens button {
margin-right: 10px;
}
.sel_lang {
padding: 5px;
color: white;
}
.fa-facebook:before {
content: url('../../statics/icons/flag_it.svg');
}
.fa-flag-it:before {
content: url('../../statics/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;
}

View File

@@ -0,0 +1,330 @@
import Vue from 'vue'
import Component from 'vue-class-component'
import drawer from '../../layouts/drawer/drawer.vue'
import messagePopover from '../../layouts/toolbar/messagePopover/messagePopover.vue'
import { GlobalStore, UserStore } from '@modules'
// import { StateConnection } from '../../model'
import { Watch } from 'vue-property-decorator'
import { tools } from '../../store/Modules/tools'
import Quasar from 'quasar'
@Component({
components: {
drawer,
messagePopover
}
})
export default class Header extends Vue {
public $t
public $v
public $q
public isUserNotAuth: boolean = false
public iconConn: string = 'wifi'
public clIconConn: string = 'clIconOnline'
public strConn: string = ''
public langshort: string = ''
public clCloudUpload: string = ''
public clCloudDownload: string = ''
public clCloudUp_Indexeddb: string = ''
public clCloudDown_Indexeddb: string = 'clIndexeddbsend'
public right: boolean = false
public photo = ''
public visuimg: boolean = true
public selectOpLang = [
{ label: 'English', icon: 'fa-flag-us', value: 'enUs', image: '../statics/images/gb.png', short: 'EN' },
{ label: 'Español', icon: 'fa-flag-es', value: 'es', image: '../statics/images/es.png', short: 'ES' },
{ label: 'Italiano', icon: 'fa-facebook', value: 'it', image: '../statics/images/it.png', short: 'IT' }
// { label: 'German', icon: 'fa-flag-de', value: 'de', image: '../statics/images/de.png', short: 'DE' },
]
get conn_changed() {
return GlobalStore.state.stateConnection
}
get isonline() {
return GlobalStore.state.stateConnection === 'online'
}
get isAdmin() {
return UserStore.state.isAdmin
}
get conndata_changed() {
return GlobalStore.state.connData
}
get isNewVersionAvailable() {
return GlobalStore.getters.isNewVersionAvailable
}
// -------------------------------------------------------------------------
// QUASAR Example using event to open drawer from another component or page
// -------------------------------------------------------------------------
// (1) This code is inside layout file that have a drawer
// if this.leftDrawerOpen is true, drawer is displayed
// (2) Listen for an event in created
/* created(){
this.$root.$on("openLeftDrawer", this.openLeftDrawercb);
},
methods: {
openURL,
// (3) Define the callback in methods
openLeftDrawercb() {
this.leftDrawerOpen = !this.leftDrawerOpen;
}
}
// (4) In another component or page, emit the event!
// Call the method when clicking button etc.
methods: {
openLeftDrawer() {
this.$root.$emit("openLeftDrawer");
}
}
// -------------------------------------------------------------------------
*/
get leftDrawerOpen() {
return GlobalStore.state.leftDrawerOpen
}
set leftDrawerOpen(value) {
GlobalStore.state.leftDrawerOpen = value
localStorage.setItem(tools.localStorage.leftDrawerOpen, value.toString())
}
get lang() {
return this.$q.lang.isoName
}
set lang(lang) {
console.log('set lang', this.$i18n.locale)
this.$i18n.locale = this.snakeToCamel(lang)
// tools.showNotif(this.$q, 'IMPOSTA LANG= ' + this.$i18n.locale)
// console.log('IMPOSTA LANG= ' + this.$i18n.locale)
UserStore.mutations.setlang(this.$i18n.locale)
let mylangtopass = lang
mylangtopass = tools.checkLangPassed(mylangtopass)
this.setshortlang(mylangtopass)
this.setLangAtt(mylangtopass)
}
@Watch('GlobalStore.state.stateConnection', { immediate: true, deep: true })
public changeconn(value: string, oldValue: string) {
this.strConn = value
}
@Watch('conndata_changed', { immediate: true, deep: true })
public changeconnData(value: any, oldValue: any) {
// console.log('CHANGED GlobalStore.state.connData', value)
this.clCloudUpload = (value.uploading_server === 1) ? 'clCloudUpload send' : 'clCloudUpload'
this.clCloudUpload = (value.downloading_server === 1) ? 'clCloudUpload receive' : 'clCloudUpload'
this.clCloudUp_Indexeddb = (value.uploading_indexeddb === 1) ? 'clIndexeddb send' : 'clIndexeddb'
this.clCloudUp_Indexeddb = (value.downloading_indexeddb === 1) ? 'clIndexeddb receive' : 'clIndexeddb'
this.clCloudUpload = (value.uploading_server === -1) ? 'clCloudUpload error' : this.clCloudUpload
this.clCloudUpload = (value.downloading_server === -1) ? 'clCloudUpload error' : this.clCloudDownload
this.clCloudUp_Indexeddb = (value.uploading_indexeddb === -1) ? 'clIndexeddb error' : this.clCloudUp_Indexeddb
this.clCloudUp_Indexeddb = (value.downloading_indexeddb === -1) ? 'clIndexeddb error' : this.clCloudDown_Indexeddb
// console.log('clCloudUpload', this.clCloudUpload)
// console.log('clCloudDownload', this.clCloudDownload)
// console.log('clCloudUp_Indexeddb', this.clCloudUp_Indexeddb)
// console.log('value.downloading_indexeddb', value.downloading_indexeddb)
// console.log('value.uploading_server', value.uploading_server)
}
@Watch('conn_changed', { immediate: true, deep: true })
public changeconn_changed(value: string, oldValue: string) {
if (value !== oldValue) {
// console.log('SSSSSSSS: ', value, oldValue)
const color = (value === 'online') ? 'positive' : 'warning'
if (oldValue !== undefined) {
tools.showNotif(this.$q, this.$t('connection') + ` ${value}`, {
color,
icon: 'wifi'
})
}
this.changeIconConn()
}
}
public RefreshApp() {
// Unregister Service Worker
navigator.serviceWorker.getRegistrations().then((registrations) => {
for (const registration of registrations) {
registration.unregister()
}
})
window.location.reload(true)
}
public changeIconConn() {
this.iconConn = GlobalStore.state.stateConnection === 'online' ? 'wifi' : 'wifi_off'
this.clIconConn = GlobalStore.state.stateConnection === 'online' ? 'clIconOnline' : 'clIconOffline'
}
public getAppVersion() {
// return "AA"
let strv = ''
if (process.env.DEV) {
strv = 'DEV '
} else if (process.env.TEST) {
strv = 'TEST '
}
return '[' + strv + process.env.APP_VERSION + ']'
}
public setshortlang(lang) {
for (const indrec in this.selectOpLang) {
if (this.selectOpLang[indrec].value === lang) {
// console.log('this.selectOpLang[indrec].short', this.selectOpLang[indrec].short, this.selectOpLang[indrec].value)
this.langshort = this.selectOpLang[indrec].short
return
}
}
}
public getLangAtt() {
return this.$q.lang.isoName
}
public setLangAtt(mylang) {
console.log('MYLL=', mylang)
// console.log('PRIMA this.$q.lang.isoName', this.$q.lang.isoName)
// dynamic import, so loading on demand only
import(`quasar/lang/${mylang}`).then((lang) => {
Quasar.lang.set(lang.default)
import(`../../statics/i18n`).then(() => {
// console.log('MY LANG DOPO=', this.$q.lang.isoName)
})
})
// this.$q.lang.set(mylang)
}
public beforeMount() {
// Estrai la Lang dal Localstorage
// console.log('this.$q.i18n=', this.$q.i18n, 'this.$q.getLocale()=', this.$q.lang.isoName)
const mybrowserLang = this.getLangAtt()
// tools.showNotif(this.$q, 'prima: ' + String(my))
let mylang = tools.getItemLS(tools.localStorage.lang)
if (mylang === '') {
if (navigator) {
mylang = navigator.language
// console.log(`LANG2 NAVIGATOR ${mylang}`)
} else {
mylang = this.$q.lang.isoName
}
// console.log('IMPOSTA LANGMY', mylang)
}
mylang = tools.checkLangPassed(mylang)
this.setLangAtt(mylang)
this.setshortlang(mylang)
}
public mounted() {
// Test this by running the code snippet below and then
// use the "TableOnlyView" checkbox in DevTools Network panel
const mythis = this
// console.log('Event LOAD')
if (window) {
window.addEventListener('load', () => {
// console.log('2) ENTERING Event LOAD')
function updateOnlineStatus(event) {
if (navigator.onLine) {
// console.log('EVENT ONLINE!')
// handle online status
GlobalStore.mutations.setStateConnection('online')
mythis.changeIconConn()
} else {
// console.log('EVENT OFFLINE!')
// handle offline status
GlobalStore.mutations.setStateConnection('offline')
mythis.changeIconConn()
}
}
window.addEventListener('online', updateOnlineStatus)
window.addEventListener('offline', updateOnlineStatus)
})
}
}
public snakeToCamel(str) {
return str.replace(/(-\w)/g, (m) => {
return m[1].toUpperCase()
})
}
get imglogo() {
return '../../' + tools.getimglogo()
}
public toggleanimation() {
console.log('toggleanimation')
this.visuimg = false
setTimeout(() => {
this.visuimg = true
}, 100)
}
get MenuCollapse() {
return GlobalStore.state.menuCollapse
// return true
}
get Username() {
return UserStore.state.username
}
get Verificato() {
return UserStore.state.verified_email
}
get Email() {
return UserStore.state.email
}
public logoutHandler() {
UserStore.actions.logout()
.then(() => {
this.$router.replace('/logout')
setTimeout(() => {
this.$router.replace('/')
}, 1000)
tools.showNotif(this.$q, this.$t('logout.uscito'), {icon: 'exit_to_app'})
})
}
}

View File

@@ -0,0 +1,157 @@
<template>
<div>
<q-header reveal elevated class="bg-primary text-white">
<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-toolbar-title>
<q-avatar>
<img :src="imglogo" height="27">
</q-avatar>
{{$t('msg.myAppName')}}
<div slot="subtitle">{{$t('msg.myDescriz')}} {{ getAppVersion() }}</div>
</q-toolbar-title>
<!--
<div v-if="isAdmin">
<q-btn flat dense round aria-label="">
<q-icon :class="clCloudUpload" name="cloud_upload"></q-icon>
</q-btn>
<q-btn flat dense round aria-label="">
<q-icon :class="clCloudUp_Indexeddb" name="arrow_upward"></q-icon>
</q-btn>
</div>
-->
<q-btn
v-if="!isonline"
flat
dense
round
@click=""
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
flat
:label="langshort"
auto-close
>
<q-list bordered>
<q-item clickable v-ripple
v-for="langrec in selectOpLang" :key="langrec.value"
@click="lang = langrec.value">
<q-item-section avatar>
<img :src="langrec.image" class="flagimg">
</q-item-section>
<q-item-section>
{{langrec.label}}
</q-item-section>
</q-item>
</q-list>
</q-btn-dropdown>
<!--
<message-popover></message-popover>
-->
<!--
<div class="right-itens">
<label>{{ $t('msg.hello') }}</label> <span v-model="prova"></span> !
</div>-->
<q-btn dense flat round icon="menu" @click="right = !right"/>
</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></drawer>
</q-drawer>
<q-drawer v-model="right" side="right" overlay bordered>
<div id="profile">
<q-img class="absolute-top" src="https://cdn.quasar-framework.org/img/material.png"
style="height: 150px">
<div class="absolute-bottom bg-transparent">
<q-avatar class="q-mb-sm">
<img src="../../statics/images/avatar-1.svg">
</q-avatar>
<div v-if="Username" class="text-weight-bold">{{ Username }}</div>
<div v-else class="text-italic">{{ $t('user.loggati') }}</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="Username" id="user-actions">
<q-btn round color="primary" icon="person"></q-btn>
<q-btn round color="warning" icon="lock"></q-btn>
<q-btn round color="secondary" icon="exit_to_app" @click='logoutHandler'></q-btn>
</div>
</div>
</q-img>
</div>
</q-drawer>
</div>
</template>
<script lang="ts" src="./Header.ts">
</script>
<style lang="scss" scoped>
@import './Header.scss';
</style>

View File

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

View File

@@ -3,6 +3,7 @@ import { Component, Watch } from 'vue-property-decorator'
import { SingleCat } from '../SingleCat'
import { ICategory } from '@src/model'
import { tools } from "@src/store/Modules/tools"
@Component({
@@ -176,13 +177,10 @@ export default class Category extends Vue {
const seldel = [...this.selectedSecond]
if (this.deleteCategory(this.selectedSecond)) {
this.$q.notify({
tools.showNotif(this.$q, `Deleted ` + (seldel.length.toString()) + ' item', {
color: 'primary',
icon: 'delete',
message: `Deleted ` + (seldel.length.toString()) + ' item'
})
}
}

View File

@@ -3,6 +3,7 @@ import { Component, Watch } from 'vue-property-decorator'
import { ICategory } from '@src/model'
import globalroutines from "@src/globalroutines"
import { tools } from "@src/store/Modules/tools"
@Component({
})
@@ -172,10 +173,9 @@ export default class Tabledata extends Vue {
const seldel = [...this.selectedSecond]
if (this.deleteCategory(this.selectedSecond)) {
this.$q.notify({
tools.showNotif(this.$q, `Deleted ` + (seldel.length.toString()) + ' item', {
color: 'primary',
icon: 'delete',
message: `Deleted ` + (seldel.length.toString()) + ' item'
icon: 'delete'
})

View File

@@ -5,19 +5,20 @@ import { TimelineLite, Back } from 'gsap'
import $ from 'jquery'
import Timeout = NodeJS.Timeout
import { tools } from "@src/store/Modules/tools"
@Component({
})
export default class Logo extends Vue {
logoimg: string = ''
public logoimg: string = ''
created() {
this.logoimg = 'statics/images/' + process.env.LOGO_REG
public created() {
this.logoimg = '../../' + tools.getimglogo()
this.animate()
}
animate () {
public animate() {
const timeline = new TimelineLite()
/*
@@ -31,7 +32,6 @@ export default class Logo extends Vue {
mysmile.addClass('smile_hide')
}, 1000)
setTimeout(() => {
mysmile.addClass('smilevisible')
mysmile.removeClass('smile_hide')
@@ -39,7 +39,6 @@ export default class Logo extends Vue {
*/
/*
timeline.to('#smile', 5, {
cy: 20,

View File

@@ -25,7 +25,7 @@ $heightdescr: 20px;
.flex-container2 {
flex-flow: row wrap;
justify-content: space-between;
margin: 0px 5px 0px 5px; // top right bottom left
margin: 0px 1px 0px 1px; // top right bottom left
}
// Set visibility: visible to the icon menu of pos-item-popover
@@ -71,7 +71,7 @@ $heightdescr: 20px;
.pos-item {
max-width: 24px;
min-width: 24px;
min-width: 26px;
margin-left: 1px;
margin-right: 1px;
padding-left: 1px;
@@ -121,7 +121,7 @@ $heightdescr: 20px;
//visibility: hidden;
}
//.q-popover.animate-scale {
//.q-menu.animate-scale {
// animation: none;
//}
@@ -218,19 +218,35 @@ $heightdescr: 20px;
}
.data-item {
max-width: 84px;
max-width: 78px;
@media (max-width: 600px) {
max-width: 22px;
}
//min-width: 100px;
//display: flex;
//visibility: initial;
margin-right: 3px;
color: #ccc;
color: #585858;
order: 1;
flex: 1;
height: $heightBtn;
line-height: $heightBtn;
height: $heightitem;
line-height: $heightitem;
padding-left: 2px;
padding-right: 0px;
//height: $heightBtn;
//line-height: $heightBtn;
}
.data_string {
@media (max-width: 600px) {
display: none;
}
}
.data-item .q-input-target{
color:red !important;
}
@@ -261,9 +277,10 @@ $heightdescr: 20px;
color: blue !important;
overflow: hidden;
align-items: center;
vertical-align: middle;
line-height: 120%;
max-height: 40px;
//background-color: #d50000;
@@ -279,14 +296,17 @@ $heightdescr: 20px;
}
.div_descr {
display: table-cell;
display: -webkit-box;
max-height: 45px;
}
.div_descr_edit {
//display: block;
max-height: 90px;
//line-height: 120%;
//max-height: 90px;
line-height: $heightitem;
}

View File

@@ -1,22 +1,19 @@
import Vue from 'vue'
import { Component, Prop, Watch } from 'vue-property-decorator'
import { tools } from '../../../store/Modules/tools'
import { UserStore } from '@modules'
import { tools } from '../../../store/Modules/tools'
import { ITodo } from '../../../model/index'
import { SubMenus } from '../SubMenus'
import $ from 'jquery'
// import { debounce } from '../../../classes/debounce'
import { date } from 'quasar'
import { askConfirm } from '../../../classes/routinestd'
@Component({
name: 'SingleTodo',
components: { SubMenus }
components: { SubMenus },
name: 'SingleTodo'
})
export default class SingleTodo extends Vue {
public selectPriority: [] = []
@@ -25,7 +22,7 @@ export default class SingleTodo extends Vue {
public classCompleted: string = ''
public classDescr: string = ''
public classDescrEdit: string = ''
public classExpiring: string = ''
public classExpiring: string = 'flex-item data-item shadow-1'
public classExpiringEx: string = ''
public iconPriority: string = ''
public popover: boolean = false
@@ -43,20 +40,19 @@ export default class SingleTodo extends Vue {
public clButtPopover: string = 'pos-item-popover'
public numpos: number = 0
$q: any
@Prop({ required: true }) itemtodo: ITodo
public $q: any
@Prop({ required: true }) public itemtodo: ITodo
// @Watch('itemtodo.completed') valueChanged() {
// this.watchupdate('completed')
// }
@Watch('itemtodo.enableExpiring') valueChanged4() {
@Watch('itemtodo.enableExpiring') public valueChanged4() {
this.watchupdate('enableExpiring')
}
@Watch('itemtodo.expiring_at') valueChanged2() {
@Watch('itemtodo.expiring_at') public valueChanged2() {
this.watchupdate('expiring_at')
}
@@ -64,39 +60,44 @@ export default class SingleTodo extends Vue {
// this.watchupdate('priority')
// }
@Watch('itemtodo.descr') valueChanged5() {
@Watch('itemtodo.descr') public valueChanged5() {
this.precDescr = this.itemtodo.descr
}
@Watch('itemtodo.progress') valueChanged6() {
@Watch('itemtodo.progress') public valueChanged6() {
console.log('itemtodo.progress')
this.updateClasses()
console.log('this.percentageProgress', this.percentageProgress, 'this.itemtodo.progress', this.itemtodo.progress)
this.watchupdate('progress')
}
dateToYYYYMMDD(date) {
/*
public dateToYYYYMMDD(date) {
// may have timezone caveats https://stackoverflow.com/a/29774197/1850609
return date && date.toISOString().split('T')[0]
}
*/
// Computed:
get isSel() {
return this.sel
}
isTodo() {
public isTodo() {
return this.isTodoByElem(this.itemtodo)
}
isTodoByElem(elem) {
public isTodoByElem(elem) {
return elem.descr.slice(-1) !== ':'
}
watchupdate(field = '') {
public watchupdate(field = '') {
this.$emit('eventupdate', {myitem: this.itemtodo, field } )
this.updateicon()
}
updateClasses() {
public updateClasses() {
// this.classCompleted = 'completed-item'
this.classCompleted = 'completed-item-popover'
this.classDescr = 'flex-item div_descr show donotdrag'
@@ -106,6 +107,9 @@ export default class SingleTodo extends Vue {
this.classDescrEdit += ' titleLista-item'
}
if (this.itemtodo.progress > 100)
this.itemtodo.progress = 100
this.classExpiring = 'flex-item data-item shadow-1'
this.classExpiringEx = ''
if (this.itemtodo.completed) {
@@ -146,8 +150,6 @@ export default class SingleTodo extends Vue {
this.clButtPopover += ' pos-item-popover_cursor'
}
// if (this.inEdit) {
// this.classDescr += ' hide'
// this.classDescrEdit += ' show'
@@ -162,8 +164,9 @@ export default class SingleTodo extends Vue {
// console.log('classDescr', this.classDescr)
// console.log('UserStore.state.lang', UserStore.state.lang)
if (this.isTodo())
if (this.isTodo()) {
this.menuPopupTodo = tools.menuPopupTodo[UserStore.state.lang]
}
else {
this.menuPopupTodo = []
this.menuPopupTodo.push(tools.menuPopupTodo[UserStore.state.lang][tools.INDEX_MENU_DELETE])
@@ -171,7 +174,11 @@ export default class SingleTodo extends Vue {
}
created() {
public getstrDate(mytimestamp) {
return date.formatDate(mytimestamp, 'DD-MM-YY')
}
public created() {
this.precDescr = this.itemtodo.descr
this.updateicon()
@@ -179,14 +186,13 @@ export default class SingleTodo extends Vue {
this.selectPriority = tools.selectPriority[UserStore.state.lang]
}
getClassRow() {
public getClassRow() {
return 'row flex-container2 ' + this.classRow
}
clickRiga(clickmenu: boolean = false) {
public clickRiga(clickmenu: boolean = false) {
// console.log('CLICK RIGA ************')
if (!this.sel) {
@@ -202,7 +208,7 @@ export default class SingleTodo extends Vue {
}
}
selectRiga() {
public selectRiga() {
// console.log('selectRiga', this.itemtodo.descr)
this.sel = true
this.classRow = 'rowselected'
@@ -210,7 +216,7 @@ export default class SingleTodo extends Vue {
// console.log('FINE selectRiga', this.itemtodo.descr)
}
deselectRiga() {
public deselectRiga() {
// console.log('DeselectRiga', this.itemtodo.descr)
this.sel = false
this.classRow = ''
@@ -218,12 +224,12 @@ export default class SingleTodo extends Vue {
this.updateClasses()
}
deselectAndExitEdit() {
public deselectAndExitEdit() {
this.deselectRiga()
this.exitEdit()
}
mouseUp() {
public mouseUp() {
if (!this.inEdit) {
if (this.sel) {
this.selectRiga()
@@ -233,45 +239,50 @@ export default class SingleTodo extends Vue {
}
}
clickRow() {
public clickRow() {
this.clickRiga()
}
editTodo() {
public editTodo() {
if (!this.itemtodo.completed) {
// console.log('INIZIO - editTodo')
this.$emit('click')
this.precDescr = this.itemtodo.descr
this.inEdit = true
if (!this.sel)
if (!this.sel) {
this.selectRiga()
else
}
else {
this.updateClasses()
}
this.faiFocus('inputdescr')
}
// console.log('FINE - editTodo')
}
faiFocus(elem, isparent: boolean = false) {
let mythis = this
public faiFocus(elem, isparent: boolean = false) {
setTimeout(() => {
let theField = null
if (isparent)
theField = <HTMLInputElement>mythis.$parent.$parent.$parent.$parent.$refs[elem]
else
theField = <HTMLInputElement>mythis.$refs[elem]
if (isparent) {
theField = this.$parent.$parent.$parent.$parent.$refs[elem] as HTMLInputElement
}
else {
theField = this.$refs[elem] as HTMLInputElement
}
if (theField !== undefined)
if (theField !== undefined) {
theField.focus()
}
// console.log('focus()')
}, 100)
}
exitEdit(singola: boolean = false) {
public exitEdit(singola: boolean = false) {
if (this.inEdit) {
if (this.precDescr !== this.itemtodo.descr)
if (this.precDescr !== this.itemtodo.descr) {
this.updateTodo()
}
// console.log('exitEdit')
this.inEdit = false
this.updateClasses
@@ -279,8 +290,7 @@ export default class SingleTodo extends Vue {
}
}
keyDownRow(e) {
public keyDownRow(e) {
console.log('keyDownRow')
// Delete Key or Backspage
if (((e.keyCode === 8) || (e.keyCode === 46)) && (this.precDescr === '') && !e.shiftKey) {
@@ -295,7 +305,7 @@ export default class SingleTodo extends Vue {
}
keyDownArea(e) {
public keyDownArea(e) {
console.log('keyDownArea')
/*
if ((e.key === 'ArrowUp') && !e.shiftKey) {
@@ -343,9 +353,10 @@ export default class SingleTodo extends Vue {
}
updateTodo() {
if (this.itemtodo.descr === this.precDescr)
public updateTodo() {
if (this.itemtodo.descr === this.precDescr) {
return
}
this.itemtodo.descr = this.precDescr
console.log('updateTodo', this.precDescr, this.itemtodo.descr)
@@ -358,7 +369,15 @@ export default class SingleTodo extends Vue {
this.updateClasses()
}
setCompleted() {
public aggiornaProgress(value, initialval){
if (value !== initialval) {
this.itemtodo.progress = value
this.updatedata('progress')
this.deselectAndExitEdit()
}
}
public setCompleted() {
// console.log('setCompleted')
this.itemtodo.completed = !this.itemtodo.completed
@@ -369,41 +388,44 @@ export default class SingleTodo extends Vue {
this.deselectAndExitEdit()
}
updatedata(field: string) {
public updatedata(field: string) {
// const myitem = tools.jsonCopy(this.itemtodo)
console.log('calling this.$emit(eventupdate)', this.itemtodo)
this.$emit('eventupdate', { myitem: this.itemtodo, field } )
}
updateicon() {
public updateicon() {
// console.log('updateicon')
if (this.itemtodo.completed)
if (this.itemtodo.completed) {
this.iconCompleted = 'check_circle'
else
}
else {
this.iconCompleted = 'check_circle_outline'
}
if (this.itemtodo.priority === tools.Todos.PRIORITY_HIGH)
this.iconPriority = 'expand_less' // expand_less
else if (this.itemtodo.priority === tools.Todos.PRIORITY_NORMAL)
if (this.itemtodo.priority === tools.Todos.PRIORITY_HIGH) {
this.iconPriority = 'expand_less'
} // expand_less
else if (this.itemtodo.priority === tools.Todos.PRIORITY_NORMAL) {
this.iconPriority = 'remove'
else if (this.itemtodo.priority === tools.Todos.PRIORITY_LOW)
this.iconPriority = 'expand_more' // expand_more
}
else if (this.itemtodo.priority === tools.Todos.PRIORITY_LOW) {
this.iconPriority = 'expand_more'
} // expand_more
this.updateClasses()
}
removeitem(id) {
public removeitem(id) {
this.$emit('deleteItem', id)
}
enableExpiring() {
public enableExpiring() {
this.itemtodo.enableExpiring = !this.itemtodo.enableExpiring
}
async clickMenu(action) {
public async clickMenu(action) {
console.log('click menu: ', action)
if (action === tools.MenuAction.DELETE) {
return await this.askConfirmDelete()
@@ -419,7 +441,7 @@ export default class SingleTodo extends Vue {
}
setPriority(newpriority) {
public setPriority(newpriority) {
if (this.itemtodo.priority !== newpriority) {
this.itemtodo.priority = newpriority
@@ -429,24 +451,22 @@ export default class SingleTodo extends Vue {
this.updateicon()
}
// this.$q.notify('setPriority: ' + elem)
}
async askConfirmDelete() {
public async askConfirmDelete() {
const deletestr = this.$t('dialog.delete')
const cancelstr = this.$t('dialog.cancel')
let msg = this.$t('dialog.msg.deleteTask', {'mytodo' : this.itemtodo.descr })
const msg = this.$t('dialog.msg.deleteTask', {mytodo : this.itemtodo.descr })
await askConfirm(this.$q, this.$t('dialog.msg.titledeleteTask'), msg, deletestr, cancelstr)
.then(ris => {
.then((ris) => {
console.log('ris', ris)
if (ris) {
this.removeitem(this.itemtodo._id)
}
}).catch(err => {
}).catch((err) => {
})
}
}

View File

@@ -1,12 +1,5 @@
<template>
<div :class="getClassRow()" @click="clickRow">
<!--<div v-if="isTodo()" class="flex-item counter-item dragula-container">{{itemtodo.pos}}</div>-->
<!--<div v-if="isFirst">-->
<!--<q-context-menu ref="contextMenu">-->
<!--<SubMenus :menuPopupTodo="menuPopupTodo" :itemtodo="itemtodo" @clickMenu="clickMenu" @setPriority="setPriority"></SubMenus>-->
<!--</q-context-menu>-->
<!--</div>-->
<div v-if="isTodo()" class="flex-item completed-item donotdrag">
<q-btn push flat
:class="classCompleted"
@@ -18,6 +11,9 @@
<div class="flex-item donotdrag divdescrTot">
<q-input v-if="sel && !itemtodo.completed" hide-underline type="textarea" ref="inputdescr"
v-model.trim="precDescr"
autogrow
borderless
dense
:class="classDescrEdit" :max-height="100"
@keydown="keyDownArea" v-on:keydown.esc="exitEdit" @blur="exitEdit(true)" @click="editTodo()"/>
@@ -37,17 +33,22 @@
<!--<q-field>{{ itemtodo.descr }}</q-field>-->
<!--</div>-->
<div v-if="isTodo() && (percentageProgress > 0) " class="flex-item progress-item shadow-1">
<q-progress
:percentage="percentageProgress"
<div v-if="isTodo() && (itemtodo.progress > 0) " class="flex-item progress-item shadow-1">
<q-linear-progress
stripe
rounded
:value="percentageProgress / 100"
class="progrbar-item"
:color="colProgress"
>
</q-progress>
</q-linear-progress>
<div :class="percProgress">
{{percentageProgress}}%
<q-popup-edit v-model="itemtodo.progress" title="Progress" buttons class="editProgress">
<q-input type="number" v-model="itemtodo.progress" :max="100" :min="0"/>
<q-popup-edit v-model="percentageProgress" title="Progress" buttons class="editProgress"
@change="val => { model = val }"
@save="aggiornaProgress"
>
<q-input dense autofocus type="number" v-model="percentageProgress" :max="100" :min="0"/>
</q-popup-edit>
</div>
@@ -55,23 +56,34 @@
<div v-if="itemtodo.enableExpiring" :class="classExpiring">
<q-datetime
type="date"
v-model="itemtodo.expiring_at"
class="myexpired"
format="DD/MM/YY"
@change="val => { model = val }">
</q-datetime>
<span class="data_string">{{getstrDate(itemtodo.expiring_at)}}</span>
<q-icon name="event" class="cursor-pointer" style="padding: 2px;">
<q-popup-proxy>
<q-date v-model="itemtodo.expiring_at" today-btn/>
</q-popup-proxy>
</q-icon>
<!--<q-icon name="event" class="cursor-pointer" />-->
<!--<q-popup-edit v-model="itemtodo.expiring_at"-->
<!--title="Edit"-->
<!--buttons class="">-->
<!--<q-input-->
<!--filled-->
<!--v-model="itemtodo.expiring_at"-->
<!--type="date"-->
<!--class="myexpired"-->
<!--format="DD/MM/YYYY"-->
<!--&gt;-->
<!--</q-input>-->
<!--</q-popup-edit>-->
</div>
<div v-if="isTodo()" class="flex-item pos-item " @mousedown="clickRiga">
<q-btn push
:class="clButtPopover"
icon="menu">
<q-popover id="popmenu" v-if="true" self="top right">
<q-menu id="popmenu" v-if="true" self="top right">
<SubMenus :menuPopupTodo="menuPopupTodo" :itemtodo="itemtodo" @clickMenu="clickMenu"
@setPriority="setPriority"></SubMenus>
</q-popover>
</q-menu>
</q-btn>
</div>

View File

@@ -11,7 +11,8 @@
cursor: pointer;
}
.menuInputProgress > div:nth-child(2) > div > input {
.menuInputProgress > div > div > div > input {
min-width: 30px;
max-width: 30px;
width: 30px;
}

View File

@@ -1,9 +1,9 @@
import Vue from 'vue'
import { Component, Prop } from 'vue-property-decorator'
import { Component, Prop, Watch } from 'vue-property-decorator'
import { ITodo } from '../../../model/index'
import { tools } from '@src/store/Modules/tools'
import { UserStore } from '@store'
import { ITodo } from '../../../model/index'
// Doesn't exist in quasar this ? error TS2305
// import { format } from 'quasar'
@@ -18,19 +18,19 @@ import { UserStore } from '@store'
export default class SubMenus extends Vue {
public selectPriority: [] = tools.selectPriority[UserStore.state.lang]
@Prop({ required: false }) menuPopupTodo: any[]
@Prop({ required: false }) itemtodo: ITodo
$q: any
@Prop({ required: false }) public menuPopupTodo: any[]
@Prop({ required: false }) public itemtodo: ITodo
public $q: any
clickMenu (field) {
public clickMenu(field) {
this.$emit('clickMenu', field)
}
setPriority (field) {
public setPriority(field) {
this.$emit('setPriority', field)
}
KeychangeProgress (e) {
public KeychangeProgress(e) {
// between(50, 10, 20)
if (this.itemtodo.progress > 100) {
@@ -46,7 +46,7 @@ export default class SubMenus extends Vue {
}
}
create () {
public create() {
this.selectPriority = tools.selectPriority[UserStore.state.lang]
console.log('CREAZIONE')

View File

@@ -1,71 +1,82 @@
<template>
<div>
<q-list link separator no-border class="todo-menu">
<q-list separator no-border class="todo-menu">
<div v-for="field in menuPopupTodo" :key="field.value">
<q-item v-if="(field.value !== 130) && (field.value !== 100)" :icon="field.icon"
<q-item clickable v-if="(field.value !== 130) && (field.value !== 100)" :icon="field.icon"
@click.native="clickMenu(field.value)">
<q-item-side :icon="field.icon"/>
<q-item-section avatar>
<q-icon :name="field.icon"/>
</q-item-section>
<q-item-main v-if="field.value !== 120">
<q-item-tile label class="item-menu">{{field.label}}</q-item-tile>
</q-item-main>
<q-item-section v-if="field.value !== 120" label class="item-menu">
<q-item-label>{{field.label}}</q-item-label>
</q-item-section>
<q-item-side v-if="field.value === 101">
<q-item-section side top v-if="field.value === 101">
<q-checkbox v-model="itemtodo.enableExpiring"/>
</q-item-side>
<q-item-side v-if="field.value === 110">
</q-item-section>
<q-item-section side v-if="field.value === 110">
<q-checkbox v-model="itemtodo.completed"/>
</q-item-side>
</q-item-section>
<q-item-main v-if="field.value === 120">
<q-slider :class="$parent.menuProgress" v-model="itemtodo.progress" :min="0" :max="100"
:step="5"/>
</q-item-main>
<q-item-side v-if="field.value === 120" >
<q-item-section v-if="field.value === 120">
<q-slider label
:class="$parent.menuProgress"
v-model="itemtodo.progress"
:min="0"
:max="100"
:step="5" @change="val => { lazy = val }"
/>
</q-item-section>
<q-item-section side v-if="field.value === 120">
<div>
<q-input v-model="itemtodo.progress"
class="menuInputProgress"
type="number"
suffix="%"
@change="val => { model = val }"
@keydown="KeychangeProgress"
/>
<q-item-label style="color: blue">{{itemtodo.progress}} %</q-item-label>
</div>
</q-item-side>
<!--<q-item-side right v-if="field.value === 120">-->
<!--<div :class="$parent.percProgress">-->
<!--{{$parent.percentageProgress}}%-->
<!--</div>-->
<!--</q-item-side>-->
</q-item-section>
</q-item>
<q-item v-if="(field.value === 100)" :icon="field.icon" v-close-overlay
<q-item v-if="(field.value === 100)" :icon="field.icon"
@click.native="clickMenu(field.value)">
<q-item-side :icon="field.icon"/>
<q-item-main label class="item-menu">{{field.label}}</q-item-main>
<q-item-section avatar>
<q-icon :name="field.icon" inverted color="primary"/>
</q-item-section>
<q-item-section class="item-menu">
{{field.label}}
</q-item-section>
</q-item>
<q-item v-if="(field.value === 130)" :icon="field.icon"
@click.native="clickMenu(field.value)">
<q-item clickable v-if="(field.value === 130)">
<q-item-section avatar>
<q-icon name="priority_high" inverted color="primary"/>
</q-item-section>
<q-item-side :icon="$parent.iconPriority"/>
<q-item-section>{{field.label}}</q-item-section>
<q-item-section side>
<q-icon name="keyboard_arrow_right"/>
</q-item-section>
<q-item-main>
<q-btn-dropdown ref="dropdown_priority" flat :label="field.label"
>
<q-list link>
<q-item v-close-overlay v-for="field in selectPriority" :key="field.value"
@click.native="setPriority(field.value)">
<q-item-side :icon="field.icon" inverted color="primary"/>
<q-item-main>
<q-item-tile label>{{field.label}}</q-item-tile>
</q-item-main>
</q-item>
</q-list>
</q-btn-dropdown>
</q-item-main>
<q-menu auto-close anchor="bottom middle" self="top middle">
<q-list dense>
<q-item side clickable :icon="field.icon"
@click="clickMenu(field.value)">
<q-item-section>
<q-list dense>
<q-item clickable v-ripple v-for="fieldprior in selectPriority"
:key="fieldprior.value"
@click="setPriority(fieldprior.value)">
<q-item-section avatar>
<q-icon :name="fieldprior.icon" inverted color="primary"/>
</q-item-section>
<q-item-section>
{{fieldprior.label}}
</q-item-section>
</q-item>
</q-list>
</q-item-section>
</q-item>
</q-list>
</q-menu>
</q-item>
</div>
</q-list>

View File

@@ -1,8 +1,8 @@
import Vue from 'vue'
import { Component, Watch } from 'vue-property-decorator'
import { ICfgServer, IDrag, IGlobalState, ITodo, ITodosState } from '@src/model'
import { SingleTodo } from '../SingleTodo'
import { ITodo, ITodosState, IDrag, IGlobalState, ICfgServer } from '@src/model'
import { tools } from '../../../store/Modules/tools'
@@ -11,82 +11,34 @@ import { UserStore } from '@store'
// _.cloneDeep( Per clonare un oggetto
import { Getter, State, Mutation } from 'vuex-class'
import { costanti } from '@src/store/Modules/costanti'
import { Getter, Mutation, State } from 'vuex-class'
const namespace: string = 'Todos'
import globalroutines from './../../../globalroutines/index'
@Component({
components: { SingleTodo },
filters: {
capitalize: function (value) {
if (!value) return ''
capitalize(value) {
if (!value) { return '' }
value = value.toString()
return value.charAt(0).toUpperCase() + value.slice(1)
}
}
})
export default class Todo extends Vue {
$q: any
filter: boolean = false
title: string = ''
todotop: string = ''
todobottom: string = ''
drag: boolean = true
startpos: number = 0
listPriorityLabel: number[] = []
arrPrior: number[] = []
itemDragStart: any = null
polling = null
loadDone: boolean = false
public inddragging: number = -1
public service: any
public actualMaxPosition: number = 15
public scrollable = true
public tmpstrTodos: string = ''
public categoryAtt: string = ''
// public showtype: number = Todos.state.showtype
$refs: {
single: SingleTodo[]
}
@Getter('todos_dacompletare', { namespace })
public todos_dacompletare: (state: ITodosState, category: string) => ITodo[]
@Getter('todos_completati', { namespace })
public todos_completati: (state: ITodosState, category: string) => ITodo[]
@Watch('$route.params.category') changecat() {
this.categoryAtt = this.$route.params.category
}
get showtype () {
get showtype() {
return Todos.state.showtype
}
set showtype (value) {
set showtype(value) {
console.log('showtype', value)
GlobalStore.mutations.setShowType(value)
}
// clickaggshowtype () {
// console.log('1B) clickaggshowtype Todos.state.showtype=', Todos.state.showtype)
// Todos.state.showtype = costanti.ShowTypeTask.SHOW_ALL
// console.log('2B) Dopo: showtype=', this.showtype)
// }
loadval (e) {
console.log('1) loadval, showtype=', this.showtype)
this.showtype = Todos.state.showtype
console.log('2) Dopo: showtype=', this.showtype)
}
get doneTodosCount() {
return Todos.getters.doneTodosCount(this.categoryAtt)
}
@@ -106,7 +58,7 @@ export default class Todo extends Vue {
get todos_vista() {
let mystr = ''
const arr = Todos.getters.todos_dacompletare(this.categoryAtt)
for (let ind in arr) {
for (const ind in arr) {
mystr += this.getstrelem(arr[ind]) + '\n'
}
@@ -118,7 +70,6 @@ export default class Todo extends Vue {
// return todos_dacompletare(this.categoryAtt)
// }
// @Watch('$route', { immediate: true, deep: true })
// onUrlChange(newVal: any) {
// // Some action
@@ -132,79 +83,93 @@ export default class Todo extends Vue {
set reload_fromServer(value: number) {
Todos.state.reload_fromServer = value
}
public $q: any
public filter: boolean = false
public title: string = ''
public todotop: string = ''
public todobottom: string = ''
public drag: boolean = true
public startpos: number = 0
public listPriorityLabel: number[] = []
public arrPrior: number[] = []
public itemDragStart: any = null
public polling = null
public loadDone: boolean = false
public inddragging: number = -1
public service: any
public actualMaxPosition: number = 15
public scrollable = true
public tmpstrTodos: string = ''
public categoryAtt: string = ''
// public showtype: number = Todos.state.showtype
getmyid(id) {
public $refs: {
single: SingleTodo[]
}
@Getter('todos_dacompletare', { namespace })
public todos_dacompletare: (state: ITodosState, category: string) => ITodo[]
@Getter('todos_completati', { namespace })
public todos_completati: (state: ITodosState, category: string) => ITodo[]
@Watch('$route.params.category') public changecat() {
this.categoryAtt = this.$route.params.category
}
// clickaggshowtype () {
// console.log('1B) clickaggshowtype Todos.state.showtype=', Todos.state.showtype)
// Todos.state.showtype = costanti.ShowTypeTask.SHOW_ALL
// console.log('2B) Dopo: showtype=', this.showtype)
// }
public loadval(e) {
console.log('1) loadval, showtype=', this.showtype)
this.showtype = Todos.state.showtype
console.log('2) Dopo: showtype=', this.showtype)
}
public getmyid(id) {
return 'row' + id
}
showTask(field_value) {
public showTask(field_value) {
return field_value === tools.MenuAction.SHOW_TASK
}
onStart() {
public onStart() {
this.startpos = 0
this.itemDragStart = null
}
logelem(mystr, elem) {
public logelem(mystr, elem) {
console.log(mystr, 'elem [', elem._id, '] ', elem.descr, ' Pr(', this.getPriorityByInd(elem.priority), ') [', elem.id_prev, '] modif=', elem.modified)
}
getstrelem(elem) {
public getstrelem(elem) {
return 'elem [' + elem._id + '] ' + elem.descr + ' Pr(' + this.getPriorityByInd(elem.priority) + ') [ID_PREV=' + elem.id_prev + '] modif=' + elem.modified + ' '
}
// getPriorityToSet(ind1, ind2) {
// let elem1 = this.getelem(ind1)
// let elem2 = this.getelem(ind2)
//
// if ((elem1 !== null) && (elem2 !== null)) {
// if (elem1.priority === elem2.priority) {
// return elem1.priority
// } else {
// // if different priority then take the first
// return elem1.priority
// }
// } else {
// return (elem1 != null) ? elem1.priority : ((elem2 != null) ? elem2.priority : null)
// }
// }
//
getCompleted(ind1, ind2) {
// let elem1 = this.getelem(ind1)
// let elem2 = this.getelem(ind2)
//
// if ((elem1 !== null) && (elem2 !== null)) {
// if (elem1.completed === elem2.completed) {
// return elem1.completed
// } else {
// return elem1.completed
// }
// } else {
// return (elem1 != null) ? elem1.completed : ((elem2 != null) ? elem2.completed : null)
// }
}
getTitlePriority(priority) {
public getTitlePriority(priority) {
let cl = ''
if (priority === tools.Todos.PRIORITY_HIGH)
if (priority === tools.Todos.PRIORITY_HIGH) {
cl = 'high_priority'
else if (priority === tools.Todos.PRIORITY_NORMAL)
}
else if (priority === tools.Todos.PRIORITY_NORMAL) {
cl = 'medium_priority'
else if (priority === tools.Todos.PRIORITY_LOW)
}
else if (priority === tools.Todos.PRIORITY_LOW) {
cl = 'low_priority'
}
return cl + ' titlePriority'
}
logga_arr(myarr: ITodo[]) {
public logga_arr(myarr: ITodo[]) {
let mystr = '\n'
myarr.forEach(item => {
myarr.forEach((item) => {
mystr += '[' + item.pos + '] ' + item.descr + ' Pr(' + this.getPriorityByInd(item.priority) + ') [' + item.id_prev + '] modif=' + item.modified + '\n'
// mystr += '[' + item.pos + '] ' + item.descr + '\n'
})
@@ -212,74 +177,30 @@ export default class Todo extends Vue {
return mystr
}
async onEnd(itemdragend) {
public async onEnd(itemdragend) {
console.log('************ END DRAG: ', itemdragend)
this.inddragging = -1
await Todos.actions.swapElems(itemdragend)
// If the newIndex is between another priority, then change priority
// if (!changecompleted) {
// // if I changed the completed, I don't have to put in other list priority
// let newpriority = this.getPriorityToSet(indini, indfine)
// if (newpriority != null && newpriority >= 0) {
// myobj.modified = (myobj.priority !== newpriority) ? true : myobj.modified
// myobj.priority = newpriority
// console.log('NewPriority: ', newpriority)
// }
// }
// let completed = this.getCompleted(indini, indfine)
// let changecompleted = false
// if (completed != null) {
// myobj.modified = (myobj.completed !== completed) ? true : myobj.modified
// myobj.completed = completed
// changecompleted = true
// console.log('Newcompleted: ', completed, 'modif', myobj.modified)
// }
}
private getElementIndex(el: any) {
return [].slice.call(el.parentElement.children).indexOf(el)
}
private getElementOldIndex(el: any) {
return parseInt(el.attributes['index'].value)
}
private getElementParentId(el: any) {
const elem = [].slice.call(el.parentElement.children)
console.log('elem', elem)
const id = elem.attributes['id'].substring(3)
return id
}
private getElementId(el: any) {
console.log(' el ', el)
const id = el.attributes['id'].value.substring(3)
return id
}
created() {
public created() {
const $service = this.$dragula.$service
$service.options('first',
{
// isContainer: function (el) {
// return el.classList.contains('dragula-container')
// },
moves: function (el, source, handle, sibling) {
moves(el, source, handle, sibling) {
// console.log('moves')
return !el.classList.contains('donotdrag') // elements are always draggable by default
},
accepts: function (el, target, source, sibling) {
accepts(el, target, source, sibling) {
// console.log('accepts dragging '+ el.id + ' from ' + source.id + ' to ' + target.id)
return true // elements can be dropped in any of the `containers` by default
},
invalid: function (el, handle) {
invalid(el, handle) {
// console.log('invalid')
return el.classList.contains('donotdrag') // don't prevent any drags from initiating by default
},
@@ -287,9 +208,7 @@ export default class Todo extends Vue {
})
$service.eventBus.$on('dragend', (args) => {
let itemdragend: IDrag = {
// newIndex: this.getElementIndex(args.el),
// oldIndex: this.getElementOldIndex(args.el)
const itemdragend: IDrag = {
category: this.categoryAtt,
newIndex: this.getElementIndex(args.el),
oldIndex: this.getElementOldIndex(args.el)
@@ -298,57 +217,53 @@ export default class Todo extends Vue {
this.onEnd(itemdragend)
})
let mythis = this
$service.eventBus.$on('drag', function (el, source) {
$service.eventBus.$on('drag', (el, source) => {
// mythis.inddragging = mythis.getElementIndex(el)
console.log('+++ DRAG ind=', mythis.inddragging)
mythis.scrollable = false
console.log('+++ DRAG ind=', this.inddragging)
this.scrollable = false
})
$service.eventBus.$on('drop', function (el, source) {
$service.eventBus.$on('drop', (el, source) => {
console.log('+++ DROP')
mythis.scrollable = true
this.scrollable = true
})
this.load()
}
mounted() {
public mounted() {
// console.log('*** MOUNTED ***')
this.categoryAtt = this.$route.params.category
let mythis = this
if (window) {
window.addEventListener('touchmove', function (e) {
window.addEventListener('touchmove', (e) => {
// console.log('touchmove')
if (!mythis.scrollable) {
if (!this.scrollable) {
e.preventDefault()
}
}, { passive: false })
}
}
setarrPriority() {
public setarrPriority() {
this.arrPrior = []
const arr = tools.selectPriority[UserStore.state.lang]
if (arr) {
arr.forEach(rec => {
arr.forEach((rec) => {
this.arrPrior.push(rec.value)
})
}
// console.log('Array PRIOR:', this.arrPrior)
}
async load() {
public async load() {
console.log('LOAD TODO....')
this.categoryAtt = this.$route.params.category
// Set last category selected
localStorage.setItem(tools.localStorage.categorySel, this.categoryAtt)
for (let todosKey in tools.Todos) {
for (const todosKey in tools.Todos) {
this.listPriorityLabel.push(tools.Todos[todosKey])
}
// console.log('Priority:' + this.listPriorityLabel)
@@ -361,24 +276,24 @@ export default class Todo extends Vue {
}
// Call to check if need to refresh
checkUpdate_everytime() {
public checkUpdate_everytime() {
this.polling = setInterval(() => {
this.checkUpdate()
}, 60000)
}
beforedestroy() {
public beforeDestroy() {
clearInterval(this.polling)
}
getPriorityByInd(index) {
public getPriorityByInd(index) {
// console.log('LANG in PRIOR', UserStore.state.lang)
try {
const arr = tools.selectPriority[UserStore.state.lang]
for (let rec of arr) {
if (rec.value === index)
for (const rec of arr) {
if (rec.value === index) {
return rec.label
}
}
} catch (e) {
@@ -386,36 +301,38 @@ export default class Todo extends Vue {
return ''
}
isRegistered() {
public isRegistered() {
return localStorage.getItem(tools.localStorage.userId) !== ''
}
mydeleteItem(idobj: string) {
public mydeleteItem(idobj: string) {
console.log('mydeleteItem', idobj)
return Todos.actions.deleteItem({ cat: this.categoryAtt, idobj })
}
insertTodo(atfirst: boolean = false) {
public insertTodo(atfirst: boolean = false) {
let descr = this.todobottom.trim()
if (atfirst)
if (atfirst) {
descr = this.todotop.trim()
}
if (descr === '')
if (descr === '') {
return
}
if (UserStore.state.userId === undefined) {
this.$q.notify(this.$t('todo.usernotdefined'))
tools.showNotif(this.$q, this.$t('todo.usernotdefined'))
return
}
if (!this.isRegistered()) {
// Not logged
this.$q.notify(this.$t('user.notregistered'))
tools.showNotif(this.$q, this.$t('user.notregistered'))
return
}
let myobj: ITodo = {
descr: descr,
const myobj: ITodo = {
descr,
category: this.categoryAtt
}
@@ -423,22 +340,20 @@ export default class Todo extends Vue {
.then((data) => {
console.log('data', data)
if (data !== null)
this.$q.notify(data)
// if (data !== null) {
// tools.showNotif(this.$q, data)
// }
// empty the field
if (atfirst)
if (atfirst) {
this.todotop = ''
else
}
else {
this.todobottom = ''
}
})
}
/*
sendMessageToSW(recdata, method) {
@@ -453,7 +368,7 @@ export default class Todo extends Vue {
}
*/
async updateitem({ myitem, field }) {
public async updateitem({ myitem, field }) {
console.log('calling MODIFY updateitem', myitem, field)
// Update the others components...
@@ -471,14 +386,14 @@ export default class Todo extends Vue {
}
deselectAllRows(item: ITodo, check, onlythis: boolean = false) {
public deselectAllRows(item: ITodo, check, onlythis: boolean = false) {
// console.log('deselectAllRows : ', item)
for (let i = 0; i < this.$refs.single.length; i++) {
let contr = <SingleTodo>this.$refs.single[i]
const contr = this.$refs.single[i] as SingleTodo
// @ts-ignore
let id = contr.itemtodo._id
const id = contr.itemtodo._id
// Don't deselect the actual clicked!
let des = false
if (onlythis) {
@@ -493,11 +408,11 @@ export default class Todo extends Vue {
}
}
checkUpdate() {
public checkUpdate() {
Todos.actions.waitAndcheckPendingMsg()
}
loadMoreTodo(index, done) {
public loadMoreTodo(index, done) {
setTimeout(() => {
this.actualMaxPosition += 15
done()
@@ -505,24 +420,31 @@ export default class Todo extends Vue {
}
getArrTodos() {
public getArrTodos() {
let mystr = ''
let mythis = this
mythis.tmpstrTodos = ''
this.tmpstrTodos = ''
return globalroutines(null, 'readall', 'todos', null)
.then(function (alldata) {
.then((alldata) => {
const myrecs = [...alldata]
myrecs.forEach(rec => {
myrecs.forEach((rec) => {
mystr = mystr + rec.descr + rec.completed + '] ['
})
mythis.tmpstrTodos = 'TODOS: ' + mystr
this.tmpstrTodos = 'TODOS: ' + mystr
})
}
private getElementIndex(el: any) {
return [].slice.call(el.parentElement.children).indexOf(el)
}
private getElementOldIndex(el: any) {
return parseInt(el.attributes.index.value, 10)
}
// setArrTodos() {
//
// let mystr = ''
@@ -536,5 +458,4 @@ export default class Todo extends Vue {
// }
//
}

View File

@@ -7,37 +7,58 @@
<div class="flex-item">
<q-btn push
icon="settings">
<q-popover id="popconfig" self="top right">
<q-menu id="popconfig" self="top right">
<q-list link separator no-border class="todo-menu">
<div v-for="field in menuPopupConfigTodo" :key="field.value">
<q-item :icon="field.icon"
@click.native="">
<q-item-side :icon="field.icon"/>
<q-item clickable v-for="field in menuPopupConfigTodo" :key="field.value">
<q-item-section avatar>
<q-icon :name="field.icon"/>
</q-item-section>
<q-item-main v-if="showTask(field.value)">
<q-item-section>{{field.label}}</q-item-section>
<q-select
radio
color="secondary"
:float-label="field.label"
v-model="showtype"
:options="listOptionShowTask"/>
</q-item-main>
<q-item-main v-else>
<q-item-tile label class="item-menu">{{field.label}}</q-item-tile>
</q-item-main>
</q-item>
</div>
<q-item-section side v-if="showTask(field.value)">
<q-item-section side>
<q-icon name="keyboard_arrow_right"/>
</q-item-section>
<q-menu auto-close anchor="bottom middle" self="top middle">
<q-list dense>
<q-item side :icon="field.icon">
<q-item-section>
<q-list dense>
<q-item clickable v-ripple v-for="opt in listOptionShowTask"
:key="opt.value"
@click="showtype = opt.value">
<q-item-section avatar>
<q-icon :name="opt.icon" inverted color="primary"/>
</q-item-section>
<q-item-section>
{{opt.label}}
</q-item-section>
</q-item>
</q-list>
</q-item-section>
</q-item>
</q-list>
</q-menu>
</q-item-section>
</q-item>
</q-list>
</q-popover>
</q-menu>
</q-btn>
</div>
</div>
</div>
<q-input ref="insertTask" v-model="todotop" inverted :float-label="$t('todo.inserttop')"
<q-input ref="insertTask" color="blue-12" v-model="todotop" :label="$t('todo.inserttop')"
style="margin-left: 6px;"
:after="[{icon: 'arrow_forward', content: true, handler () {}}]"
v-on:keyup.enter="insertTodo(true)"/>
v-on:keyup.enter="insertTodo(true)">
<template v-slot:prepend>
<q-icon name="add"/>
</template>
</q-input>
<div style="display: none">{{ prior = 0, priorcomplet = false }}</div>
<div>
@@ -87,8 +108,10 @@
</div>
<q-input v-if="TodosCount > 0" ref="insertTaskBottom" v-model="todobottom" inverted
:float-label="$t('todo.insertbottom')"
<q-input v-if="TodosCount > 0" ref="insertTaskBottom" v-model="todobottom"
style="margin-left: 6px;"
color="blue-12"
:label="$t('todo.insertbottom')"
:after="[{icon: 'arrow_forward', content: true, handler () {}}]"
v-on:keyup.enter="insertTodo(false)"/>
@@ -102,8 +125,8 @@
<!--&lt;!&ndash;<q-btn class="mybtn" round color="" icon="list" @click="reload_fromServer++">Reload</q-btn>&ndash;&gt;-->
<!--</div>-->
<!--
<!--&lt;!&ndash;<q-input v-model="testPao" float-label="testPao"/>&ndash;&gt;-->
<!--
<!--&lt;!&ndash;<q-input v-model="testPao" float-label="testPao"/>&ndash;&gt;-->
<!--<q-input v-model="todos_changed" float-label="todos_changed"/>-->
<!--<q-input v-model="reload_fromServer" float-label="reload_fromServer"/>-->

View File

@@ -1,20 +1,19 @@
interface IUriConfig {
auth?: string
content?: string
site?: string
services?: string
auth?: string
content?: string
site?: string
services?: string
}
const uri: IUriConfig = {}
const addProp = (obj: {}, propName: string, value: string) => {
Object.defineProperty(obj, propName, {
enumerable: false,
get: () => {
return '//' + window.location.host + value
}
})
Object.defineProperty(obj, propName, {
enumerable: false,
get: () => {
return '//' + window.location.host + value
}
})
}
addProp(uri, 'auth', '/auth/')
@@ -23,17 +22,17 @@ addProp(uri, 'site', process.env.MONGODB_HOST)
addProp(uri, 'services', '/api/')
const config = {
uri: uri,
claimsNamespace: '//toucan/claims',
auth: {
accessTokenKey: 'AUTH-LOCAL',
externalProviderKey: 'AUTH-EXTERNAL'
},
uopt: 'UOPT',
xsrf: {
cookieName: 'XSRF-TOKEN',
headerName: 'X-XSRF-TOKEN'
}
claimsNamespace: '//toucan/claims',
uri,
auth: {
accessTokenKey: 'AUTH-LOCAL',
externalProviderKey: 'AUTH-EXTERNAL'
},
uopt: 'UOPT',
xsrf: {
cookieName: 'XSRF-TOKEN',
headerName: 'X-XSRF-TOKEN'
}
}
export default config

View File

@@ -0,0 +1,19 @@
// Quasar Stylus Variables
// --------------------------------------------------
// To customize the look and feel of this app, you can override
// the Stylus variables found in Quasar's source Stylus files.
// Check documentation for full list of Quasar variables
// It's highly recommended to change the default colors
// to match your app's branding.
// Tip: Use the "Theme Builder" on Quasar's documentation website.
$primary = #027BE3
$secondary = #26A69A
$accent = #9C27B0
$positive = #21BA45
$negative = #C10015
$info = #31CCEC
$warning = #F2C037

View File

@@ -1,26 +0,0 @@
// App Shared Variables
// --------------------------------------------------
// To customize the look and feel of this app, you can override
// the Stylus variables found in Quasar's source Stylus files. Setting
// variables before Quasar's Stylus will use these variables rather than
// Quasar's default Stylus variable values. Stylus variables specific
// to the themes belong in either the variables.ios.styl or variables.mat.styl files.
// Check documentation for full list of Quasar variables
// App Shared Color Variables
// --------------------------------------------------
// It's highly recommended to change the default colors
// to match your app's branding.
$primary = #027be3
$secondary = #26A69A
$tertiary = #555
$neutral = #E0E1E2
$positive = #21BA45
$negative = #DB2828
$info = #31CCEC
$warning = #F2C037

View File

@@ -1,7 +0,0 @@
// App Shared Variables
// --------------------------------------------------
// Shared Stylus variables go in the common.variables.styl file
@import 'common.variables'
// iOS only Quasar variables overwrites
// -----------------------------------------

View File

@@ -1,7 +0,0 @@
// App Shared Variables
// --------------------------------------------------
// Shared Stylus variables go in the common.variables.styl file
@import 'common.variables'
// Material only Quasar variables overwrites
// -----------------------------------------

7
src/env.d.ts vendored Normal file
View File

@@ -0,0 +1,7 @@
declare namespace NodeJS {
interface ProcessEnv {
NODE_ENV: string
VUE_ROUTER_MODE: 'hash' | 'history' | 'abstract' | undefined
VUE_ROUTER_BASE: string | undefined
}
}

View File

@@ -0,0 +1,24 @@
// import { i18n } from '../boot/vue-i18n'
import { Notify } from 'quasar'
export default (error) => {
/*
let message = this.$i18n.t('errors.backend.undefined')
if (error.response.data.error && error.response.data.message) {
message = error.response.data.message
}
if (error.response.data.errors) {
const errors = Object.keys(error.response.data.errors)
message = error.response.data.errors[errors[0]][0]
}
Notify.create({
message,
position: 'center'
})
if (message === this.$i18n.t('errors.backend.undefined')) {
console.log(error.response)
}
*/
}

View File

@@ -0,0 +1,24 @@
import store from '../store'
// import { i18n } from '../boot/vue-i18n'
import { Notify } from 'quasar'
export default (error) => {
/*
switch (error.code) {
case 'messaging/notifications-blocked':
case 'messaging/permission-blocked':
store.commit('session/fcmNotificationPromptShowed', true)
store.commit('session/fcmNotificationsBlocked', true)
break
case 'messaging/token-unsubscribe-failed':
Notify.create({
message: i18n.t('errors.firebase.try_again'),
position: 'center'
})
break
default:
console.error(error)
break
}
*/
}

View File

@@ -1,6 +1,7 @@
import { i18n } from '../plugins/i18n'
// import { i18n } from '../boot/vue-i18n'
import { Notify } from 'quasar'
export default (error) => {
/*
let message = this.$i18n.t('errors.graphql.undefined')
if (error[0].validation) {
@@ -16,4 +17,5 @@ export default (error) => {
if (message === this.$i18n.t('errors.graphql.undefined')) {
console.log(error.response)
}
*/
}

View File

@@ -1,12 +1,12 @@
import indexdb from './indexdb'
import { GlobalStore } from "../store/Modules";
import { GlobalStore } from '../store/Modules'
export default async (context, cmd, table, data = null, id = '') => {
const descr = data !== null ? data.descr : ''
// console.log('globalroutines', cmd, table, descr, id)
return await indexdb(context, cmd, table, data, id)
.then(ris => {
setTimeout(function () {
setTimeout(() => {
GlobalStore.state.connData.uploading_indexeddb = 0
GlobalStore.state.connData.downloading_indexeddb = 0
}, 1000)
@@ -14,7 +14,7 @@ export default async (context, cmd, table, data = null, id = '') => {
}
).catch(err => {
setTimeout(function () {
setTimeout(() => {
GlobalStore.state.connData.uploading_indexeddb = (GlobalStore.state.connData.uploading_indexeddb === 1) ? -1 : GlobalStore.state.connData.uploading_indexeddb
GlobalStore.state.connData.downloading_indexeddb = (GlobalStore.state.connData.downloading_indexeddb === 1) ? -1 : GlobalStore.state.connData.downloading_indexeddb
}, 1000)

View File

@@ -1,18 +1,18 @@
import store, { GlobalStore } from '../store'
import { Todos, UserStore } from '@store'
import _ from 'lodash'
import { UserStore, Todos } from '@store'
import { i18n } from '../plugins/i18n'
import store, { GlobalStore } from '../store'
import { idbKeyval as storage } from '../js/storage.js';
import { costanti } from '../store/Modules/costanti';
import { idbKeyval as storage } from '../js/storage.js'
import { costanti } from '../store/Modules/costanti'
import { ICfgData } from '@src/model'
function saveConfigIndexDb(context) {
let data = []
data['_id'] = costanti.CONFIG_ID_CFG
data['lang'] = UserStore.state.lang
data['token'] = UserStore.state.x_auth_token
data['userId'] = UserStore.state.userId
const data: ICfgData = {}
data._id = costanti.CONFIG_ID_CFG
data.lang = UserStore.state.lang
data.token = UserStore.state.x_auth_token
data.userId = UserStore.state.userId
writeConfigIndexDb('config', data)
}
@@ -21,7 +21,7 @@ function writeConfigIndexDb(context, data) {
// console.log('writeConfigIndexDb', data)
storage.setdata('config', data)
.then(ris => {
.then((ris) => {
return true
})
@@ -31,32 +31,35 @@ async function readfromIndexDbToStateTodos(context, table) {
console.log('*** readfromIndexDbToStateTodos ***')
return await storage.getalldata(table)
.then(reccat => {
.then((reccat) => {
// console.log('&&&&&&& readfromIndexDbToStateTodos OK: Num RECORD: ', records.length)
if (table === 'categories') {
console.log('reccat', reccat)
Todos.state.categories = []
for (let indcat in reccat) {
for (const indcat in reccat) {
Todos.state.categories.push(reccat[indcat].valore)
}
console.log('ARRAY Categories', Todos.state.categories)
return storage.getalldata('todos')
.then(records => {
.then((records) => {
console.log('todos records', records)
// console.log('&&&&&&& readfromIndexDbToStateTodos OK: Num RECORD: ', records.length)
for (let myrec in records) {
/*
for (const myrec in records) {
const cat = myrec.category
let indcat = state.categories.indexOf(cat)
if (Todos.state.todos[indcat] === undefined)
const indcat = state.categories.indexOf(cat)
if (Todos.state.todos[indcat] === undefined) {
Todos.state.todos[indcat] = {}
}
// add to the right array
Todos.state.todos[indcat].push(myrec)
}
*/
console.log('************ ARRAYS SALVATI IN MEMORIA Todos.state.todos ', Todos.state.todos)
})
@@ -83,31 +86,36 @@ export default async (context, cmd, table, datakey = null, id = '') => {
// console.log('TABLE', table, 'cmd', cmd)
if (cmd === 'loadapp') {
// ****** LOAD APP AL CARICAMENTO ! *******
return saveConfigIndexDb(context, datakey)
return saveConfigIndexDb(context)
} else if (cmd === 'write') {
if (GlobalStore)
if (GlobalStore) {
GlobalStore.state.connData.uploading_indexeddb = 1
}
return await storage.setdata(table, datakey)
} else if (cmd === 'updatefromIndexedDbToStateTodo') {
return await readfromIndexDbToStateTodos(context, table)
} else if (cmd === 'readall') {
if (GlobalStore)
if (GlobalStore) {
GlobalStore.state.connData.downloading_indexeddb = 1
}
return await storage.getalldata(table)
} else if (cmd === 'count') {
return await storage.count(table)
} else if (cmd === 'read') {
if (GlobalStore)
if (GlobalStore) {
GlobalStore.state.connData.downloading_indexeddb = 1
}
return await storage.getdata(table, id)
} else if (cmd === 'delete') {
if (GlobalStore)
if (GlobalStore) {
GlobalStore.state.connData.uploading_indexeddb = 1
}
return await storage.deletedata(table, id)
} else if (cmd === 'clearalldata') {
if (GlobalStore)
if (GlobalStore) {
GlobalStore.state.connData.uploading_indexeddb = 1
}
return await storage.clearalldata(table)
} else if (cmd === 'log') {
consolelogpao(table)

View File

@@ -1,15 +1,15 @@
import { UserStore } from "../store/Modules";
import messages from "../statics/i18n";
import { UserStore } from '../store/Modules'
import messages from '../statics/i18n'
function translate(params) {
let msg = params.split('.')
let lang = UserStore.state.lang
const msg = params.split('.')
const lang = UserStore.state.lang
let stringa = messages[lang]
const stringa = messages[lang]
let ris = stringa
if (ris !== undefined) {
msg.forEach(param => {
msg.forEach((param) => {
ris = ris[param]
})
} else {

View File

@@ -1,10 +1,10 @@
<!DOCTYPE html>
<html>
<head>
<title><%= htmlWebpackPlugin.options.productName %></title>
<title><%= htmlWebpackPlugin.options.appName %></title>
<meta charset="utf-8">
<meta name="description" content="<%= htmlWebpackPlugin.options.productDescription %>">
<meta name="description" content="<%= htmlWebpackPlugin.options.appDescription %>">
<meta name="format-detection" content="telephone=no">
<meta name="msapplication-tap-highlight" content="no">
<meta name="viewport"
@@ -14,12 +14,13 @@
<link rel="icon" type="image/png" sizes="32x32" href="<%= htmlWebpackPlugin.files.publicPath %>statics/icons/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="<%= htmlWebpackPlugin.files.publicPath %>statics/icons/favicon-16x16.png">
<link rel="stylesheet" type="text/css" href="<%= htmlWebpackPlugin.files.publicPath %>statics/css/dragula.css">
<script defer src="<%= htmlWebpackPlugin.files.publicPath %>statics/js/material.min.js"></script>
<!--<script defer src="<%= htmlWebpackPlugin.files.publicPath %>statics/js/material.min.js"></script>-->
<!--<script src="<%= htmlWebpackPlugin.files.publicPath %>statics/js/promise.js"></script>-->
<!--<script src="<%= htmlWebpackPlugin.files.publicPath %>statics/js/fetch.js"></script>-->
<!--<script src="<%= htmlWebpackPlugin.files.publicPath %>statics/js/idb.js"></script>-->
<!--<script src="<%= htmlWebpackPlugin.files.publicPath %>statics/js/storage.js"></script>-->
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<script src="<%= htmlWebpackPlugin.files.publicPath %>statics/js/track.js"></script>
</head>
<body>

View File

@@ -29,10 +29,10 @@
}
#user-actions {
left: 90px;
bottom: 71px;
position: relative;
width: 171px;
//left: 90px;
//bottom: 40px;
//position: relative;
//width: 171px;
}
#menu-collapse {

View File

@@ -1,12 +1,12 @@
import menuOne from './menuOne.vue'
import menuOne from '../menuone/menuOne.vue'
import Vue from 'vue'
import { Component, Watch, Prop } from 'vue-property-decorator'
import { Store } from 'vuex'
import { UserStore } from '@modules'
import { GlobalStore } from '@modules'
import { ITodoList } from '../../model'
import Vue from 'vue'
import { Component, Prop } from 'vue-property-decorator'
import { tools } from '@src/store/Modules/tools'
const namespace: string = 'GlobalModule'
@Component({
components: {
@@ -16,112 +16,8 @@ import { ITodoList } from '../../model'
export default class Drawer extends Vue {
public $q
$t: any
public arrlista = GlobalStore.state.listatodo
photo = ''
user = null
links
created() {
let listatodo = []
this.arrlista.forEach((elem: ITodoList) => {
let item = {
route: '/todo/' + elem.namecat,
faIcon: 'fa fa-list-alt',
materialIcon: 'todo',
name: 'pages.' + elem.description
}
listatodo.push(item)
})
if (UserStore.state.isAdmin) {
this.links = {
Dashboard: {
routes: [
{ route: '/', faIcon: 'fa fa-home', materialIcon: 'home', name: 'pages.home' },
{
route: '/todo', faIcon: 'fa fa-list-alt', materialIcon: 'todo', name: 'pages.Todo',
routes2: listatodo
},
{ route: '/category', faIcon: 'fa fa-list-alt', materialIcon: 'category', name: 'pages.Category' },
// { route: '/signup', faIcon: 'fa fa-registered', materialIcon: 'home', name: 'pages.SignUp' },
{ route: '/admin/cfgserv', faIcon: 'fa fa-database', materialIcon: 'admin', name: 'pages.Admin' },
{ route: '/admin/testp1/par1', faIcon: 'fa fa-database', materialIcon: 'admin', name: 'pages.Test1' },
{ route: '/admin/testp1/par2', faIcon: 'fa fa-database', materialIcon: 'admin', name: 'pages.Test2' },
// { route: '/signin', faIcon: 'fa fa-anchor', materialIcon: 'home', name: 'pages.SignIn' },
/* {route: '/vreg?idlink=aaa', faIcon: 'fa fa-login', materialIcon: 'login', name: 'pages.vreg'},*/
],
show: true
}
}
} else {
// PRODUCTION USER:
if (process.env.PROD) {
this.links = {
Dashboard: {
routes: [
{ route: '/', faIcon: 'fa fa-home', materialIcon: 'home', name: 'pages.home' },
],
show: true,
}
}
} else {
// SERVER TEST
this.links = {
Dashboard: {
routes: [
{ route: '/', faIcon: 'fa fa-home', materialIcon: 'home', name: 'pages.home' },
{
route: '/todo', faIcon: 'fa fa-list-alt', materialIcon: 'todo', name: 'pages.Todo',
routes2: listatodo
},
{ route: '/category', faIcon: 'fa fa-list-alt', materialIcon: 'category', name: 'pages.Category' }
// { route: '/signup', faIcon: 'fa fa-registered', materialIcon: 'home', name: 'pages.SignUp' },
// { route: '/signin', faIcon: 'fa fa-anchor', materialIcon: 'home', name: 'pages.SignIn' },
/* {route: '/vreg?idlink=aaa', faIcon: 'fa fa-login', materialIcon: 'login', name: 'pages.vreg'},*/
],
show: true,
}
}
}
}
public $t: any
public user = null
}
get MenuCollapse() {
return GlobalStore.state.menuCollapse
// return true
}
get Username() {
return UserStore.state.username
}
get Verificato() {
return UserStore.state.verified_email
}
get Email() {
return UserStore.state.email
}
logoutHandler() {
UserStore.actions.logout()
.then(() => {
this.$router.replace('/logout')
const mythis = this
setTimeout(function () {
mythis.$router.replace('/')
}, 1000)
this.$q.notify(this.$t('logout.uscito'))
})
}
}

View File

@@ -1,33 +1,6 @@
<template>
<div>
<div id="profile" v-if="Username">
<img :src="photo" style='height: 80px' class="inline-block">
<img src="../img/avatar-1.svg" id="avatar" class="inline-block">
<div id="user-name">
<span class="text-white"> {{ Username }} </span>
<hr>
<span class="text-white" v-if="Verificato"> {{$t('reg.verificato')}} </span>
<span class="text-white background-red" v-else> {{$t('reg.non_verificato')}} </span>
<!-- <span class="text-white"> {{ Email }} </span>-->
</div>
<div id="user-actions">
<q-btn round color="primary" icon="person"></q-btn>
<q-btn round color="warning" icon="lock"></q-btn>
<q-btn round color="secondary" icon="exit_to_app" @click='logoutHandler'></q-btn>
</div>
</div>
<menu-one :links="links"></menu-one>
<!--<footer>
<small>- Small</small>
</footer>-->
<!--<div class="fixed-bottom text-center light text-italic">-->
<!--Powered by Perseo-->
<!--</div>-->
<menu-one></menu-one>
</div>
</template>

View File

@@ -1,130 +0,0 @@
<template>
<div class="list no-border platform-delimiter light-paragraph">
<q-icon name="action"/>
<template v-for="(parent, index) in links">
<!--
<div class="list-label cursor-pointer" @click="parent.show = !parent.show">
{{replaceUnderlineToSpace(index)}} <div class="menu_freccina"><i aria-hidden="true" class="v-icon material-icons theme--light">keyboard_arrow_down</i></div>
</div>
-->
<div class="q-list-header">{{replaceUnderlineToSpace(index)}}</div>
<template v-for="child in parent.routes">
<div v-if="child.routes2">
<q-collapsible menu :label="$t(child.name)" icon="format_list_bulleted" class="titleSubMenu">
<div v-for="child2 in child.routes2">
<q-item link :to="child2.route" exact
class="item item-link drawer-closer cursor-pointer">
<i :class="child2.faIcon" class="item-primary"></i>
<div class="item-content">{{$t(child2.name)}}</div>
</q-item>
</div>
</q-collapsible>
</div>
<div v-else>
<q-slide-transition :duration=200>
<div v-show="true">
<q-item link :to="child.route" exact
class="item item-link drawer-closer cursor-pointer">
<i :class="child.faIcon" class="item-primary"></i>
<div class="item-content">{{$t(child.name)}}</div>
</q-item>
</div>
</q-slide-transition>
</div>
</template>
</template>
</div>
</template>
<script>
export default {
props: ['links'],
watch: {
'$route.path'() {
Object.keys(this.links).forEach(parentName => {
this.setParentVisibilityBasedOnRoute(this.links[parentName])
})
}
},
computed: {
currentRoutePath() {
return this.$route.path
}
},
methods: {
created() {
console.log("MENUONE CREATED!");
},
setParentVisibilityBasedOnRoute(parent) {
parent.routes.forEach(item => {
if (this.$route.path === item.route) {
parent.show = true
return
}
})
},
replaceUnderlineToSpace(text) {
while (text.indexOf('_') !== -1) {
text = text.replace('_', ' ')
}
return text
}
}
}
</script>
<style scoped>
.q-list-header {
min-height: 12px;
padding: 5px 8px;
}
.menu-hr {
border-color: #dedede;
height: 0.5px;
}
.router-link-active {
color: #027be3;
background-color: #dadada !important;
border-right: 2px solid #027be3;
}
.list-label:first-child {
line-height: 20px;
padding: 5px;
margin: 1px;
}
/*
.menu-enter-active, .scale-enter {
-webkit-animation: moveFromTopFade .5s ease both;
animation: moveFromTopFade .5s ease both;
}
.menu-leave-to, .scale-leave-active {
-webkit-animation: moveToBottom .5s ease both;
animation: moveToBottom .5s ease both;
}
*/
.router-link-active {
color: #027be3;
background-color: #dadada !important;
border-right: 2px solid #027be3;
}
.router-link-active .item-primary {
color: #027be3;
}
.menu_freccina {
position: absolute;
right: 10px;
display: inline-block;
padding: 0 0px 0px 0px;
-webkit-transform: rotate(-180deg);
transform: rotate(-180deg);
}
</style>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.5 KiB

View File

@@ -0,0 +1,76 @@
.q-list-header {
min-height: 12px;
padding: 5px 8px;
}
.menu-hr {
border-color: #dedede;
height: 0.5px;
}
.router-link-active {
color: #027be3;
background-color: #dadada !important;
border-right: 2px solid #027be3;
}
.list-label:first-child {
line-height: 20px;
padding: 5px;
margin: 1px;
}
/*
.menu-enter-active, .scale-enter {
-webkit-animation: moveFromTopFade .5s ease both;
animation: moveFromTopFade .5s ease both;
}
.menu-leave-to, .scale-leave-active {
-webkit-animation: moveToBottom .5s ease both;
animation: moveToBottom .5s ease both;
}
*/
.router-link-active {
color: #027be3;
background-color: #dadada !important;
border-right: 2px solid #027be3;
}
.router-link-active .item-primary {
color: #027be3;
}
.menu_freccina {
position: absolute;
right: 10px;
display: inline-block;
padding: 0 0px 0px 0px;
-webkit-transform: rotate(-180deg);
transform: rotate(-180deg);
}
.my-menu, .my-menu > i{
min-width: 26px;
font-size: 1rem;
}
.my-menu-icon{
min-width: 26px;
font-size: 1rem;
}
.my-menu-icon > i{
min-width: 26px;
font-size: 1.5rem;
}
.my-menu-active {
background-color: rgba(174, 189, 241, 0.71);
}
.my-menu-separat > i{
min-width: 26px;
font-size: 1rem;
}

View File

@@ -0,0 +1,38 @@
import Vue from 'vue'
import { Watch } from 'vue-property-decorator'
import { GlobalStore } from '../../store/Modules'
export default class MenuOne extends Vue {
@Watch('$route.path')
private modifroute() {
Object.keys(this.getmenu).forEach((parentName) => {
this.setParentVisibilityBasedOnRoute(this.getmenu[parentName])
})
}
// get currentRoutePath() {
// return this.$route.path
// }
get getmenu() {
return GlobalStore.getters.getmenu
}
public setParentVisibilityBasedOnRoute(parent) {
parent.routes.forEach((item) => {
if (this.$route.path === item.route) {
parent.show = true
return
}
})
}
public replaceUnderlineToSpace(text) {
while (text.indexOf('_') !== -1) {
text = text.replace('_', ' ')
}
return text
}
}

View File

@@ -0,0 +1,66 @@
<template>
<div class="no-border">
<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="item in parent.routes">
<div v-if="item.routes2">
<q-expansion-item
:header-inset-level="0.5"
:content-inset-level="0.5"
:label="$t(item.name)"
:icon="item.materialIcon"
expand-icon-class="my-menu-separat"
header-class="my-menu"
active-class="my-menu-active"
>
<q-expansion-item v-for="(child2, index) in item.routes2" :to="child2.route" :key="index"
:header-inset-level="0.5"
:duration="300"
expand-icon="map"
active-class="my-menu-active"
class="item item-link drawer-closer cursor-pointer my-menu"
:label="$t(child2.name)">
</q-expansion-item>
</q-expansion-item>
</div>
<div v-else>
<q-slide-transition :duration=200>
<div v-show="true">
<q-item
clickable
v-ripple
exact
:to="item.route"
active-class="my-menu-active"
>
<q-item-section avatar class="my-menu-icon">
<q-icon :name="item.materialIcon"/>
</q-item-section>
<q-item-section class="my-menu">
{{$t(item.name)}}
</q-item-section>
</q-item>
</div>
</q-slide-transition>
</div>
<!--<q-separator spaced />-->
</div>
</template>
</q-list>
</div>
</template>
<script lang="ts" src="./menuOne.ts">
</script>
<style lang="scss" scoped>
@import './menuOne.scss';
</style>

View File

@@ -11,7 +11,7 @@ import './messagePopover.scss'
export default class MessagePopover extends Vue {
posts: IPost[] = []
created() {
public created() {
if (GlobalStore.state.posts.length < 1) {
this.requestPosts()
}

View File

@@ -2,7 +2,7 @@
<button class="relative-position animate-bounce">
<i class="fa fa-2x fa-envelope-o"></i>
<span class="floating label bg-dark">5</span>
<q-popover self="top right">
<q-menu self="top right">
<div class="list striped">
<p class="caption no-margin text-center text-white bg-teal">Messages from people</p>
<div class="item item-link two-lines item-delimiter no-margin"
@@ -18,7 +18,7 @@
</span>
</div>
</div>
</q-popover>
</q-menu>
</button>
</template>

View File

@@ -0,0 +1,66 @@
import { LocalStorage } from 'quasar'
// import { onFail } from '../../_LOCALE/src/session/logout'
// import appSetup from './app-setup'
import config from '../config'
let authorized = false
export default () => {
// #Todo: Fix localStorage security ...
/*
if (config.localStorage.enableListener) {
window.addEventListener('storage', (e) => {
if (!authorized) {
console.warn('Unauthorized local storage change')
switch (config.localStorage.unauthChange) {
case 'block':
if (e.key === 'null' || e.key === null) {
reload()
} else {
_LocalStorage.setNative(e.key, e.oldValue)
}
break
case 'clear':
reload()
break
default:
reload()
break
}
}
}, false)
}
*/
return Promise.resolve(true)
}
const reload = () => {
// onFail().then(success => appSetup())
}
export const _LocalStorage = {
setNative(key, value) {
authorized = true
localStorage.setItem(key, value)
authorized = false
},
set(key, value) {
authorized = true
LocalStorage.set(key, value)
authorized = false
},
remove(key) {
authorized = true
LocalStorage.remove(key)
authorized = false
},
clear() {
authorized = true
LocalStorage.clear()
authorized = false
},
get(key) {
return LocalStorage.get.item(key)
}
}

View File

@@ -1,3 +1,6 @@
import { costanti } from "@src/store/Modules/costanti"
import { UserStore } from "@store"
export interface IPost {
title: string
}
@@ -15,6 +18,13 @@ export interface ICfgServer {
valore: string
}
export interface ICfgData {
_id?: string
lang?: string
token?: string
userId?: string
}
export interface ITestp1 {
contatore: number
mioarray: ICfgServer[]
@@ -44,6 +54,7 @@ export interface IGlobalState {
testp1: ITestp1
connData: IConnData
posts: IPost[]
menulinks: {}
listatodo: ITodoList[]
arrConfig: IConfig[]
}

View File

@@ -11,7 +11,7 @@ export const DefaultUser = <IUserState>{
export interface IUserState {
userId?: string
email?: string
username: string
username?: string
idapp?: any
password?: string
lang?: string

View File

@@ -1,39 +0,0 @@
// src/plugins/i18n.js
import VueI18n from 'vue-i18n';
import messages from 'src/statics/i18n';
import { tools } from "../store/Modules/tools";
export default ({ app, store, Vue }) => {
Vue.use(VueI18n);
// Vue.config.lang = process.env.LANG_DEFAULT;
let mylang = tools.getItemLS(tools.localStorage.lang)
if ((navigator) && (mylang === '')) {
mylang = navigator.language
console.log(`LANG NAVIGATOR ${mylang}`)
}
if (mylang === '')
mylang = process.env.LANG_DEFAULT;
if (mylang.toLowerCase() === 'es-es')
mylang = 'esEs'
console.log('MYLANG2=', mylang)
console.log('process.env.LANG_DEFAULT=', process.env.LANG_DEFAULT)
Vue.config.lang = mylang
// console.log("PLUGINS INIT....");
//console.log("LANG_DEFAULT: ")
//console.log(process.env.LANG_DEFAULT)
// Set i18n instance on app
app.i18n = new VueI18n({
locale: mylang,
fallbackLocale: mylang,
messages
})
}

View File

@@ -1,20 +0,0 @@
import Vue from 'vue'
import VueIdb from 'vue-idb'
export default ({ Vue }) => {
Vue.use(VueIdb)
}
/*
export default new VueIdb({
version: 1,
database: 'test',
schemas: [
{ categories: '++_id, sub_categ_id, descr_it' }
]
})
*/

View File

@@ -1,28 +0,0 @@
TweenMax.set('.vlogo', {
opacity: 1
})
TweenMax.set('#words', {
visibility: 'visible'
})
//repeating for all the birds, uses classes
exports.anima = () => {
alert("prova")
const tl = new TimelineMax({
repeat: 2,
yoyo: true
})
tl.add('start')
tl.to('.sun ', 1, {
rotation: -45,
y: -20,
transformOrigin: '50% 90%'
}, 'start')
tl.timeScale(2)
return tl
}

View File

@@ -1,8 +1,33 @@
body {
font-family: 'Source Sans Pro', 'Helvetica Neue', Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
color: #a7a7a7;
line-height: 1.5;
//font-size: 1rem;
}
$grayshadow: #555;
.testo-banda {
//background: -webkit-gradient(linear, left top, left bottom, from(#3144f0), to(transparent));
//background: linear-gradient(180deg, #3144f0, transparent);
//background: rgba(0, 0, 0, .6)
}
p {
margin: 0 0 16px;
text-shadow: 2px 2px 4px $grayshadow;
}
.mycard {
visibility: hidden;
}
.landing {
}
.landing_background {
background: #000 url(../../statics/images/cover.jpg) no-repeat 50% fixed;
background-size: cover
}
@@ -14,16 +39,16 @@
-webkit-box-pack: center;
-ms-flex-pack: center;
justify-content: center;
padding: 0 16px
//padding: 0 16px
}
.landing > section.padding {
padding: 180px 16px
padding: 90px 16px
}
.landing > section > div {
position: relative;
max-width: 1040px;
max-width: 1240px;
width: 100%
}
@@ -40,7 +65,7 @@
}
.landing__hero {
min-height: 100vh
min-height: 50vh
}
.landing__header {
@@ -48,7 +73,7 @@
}
.landing__arrow {
bottom: 8px;
bottom: 25px;
opacity: .4
}
@@ -61,28 +86,40 @@
width: 150px;
height: 150px;
margin-top: 21px;
-webkit-animation: logo-rotate 240s linear infinite;
animation: logo-rotate 240s linear infinite
//-webkit-animation: logo-rotate 240s linear infinite;
//animation: logo-rotate 240s linear infinite
}
.landing__features .q-icon {
font-size: 64px
}
h4 {
line-height: 1.5;
text-shadow: 4px 4px 8px $grayshadow;
}
.landing__features h4, .landing__features h6 {
margin: 26px 0
}
.landing__features p {
opacity: .6;
font-size: 16px
opacity: .7;
font-size: 1rem;
line-height: 1.5;
}
.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, .1) 65%, #000);
//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) 75%, #FFF);
padding-top: 72px !important;
//padding-bottom: 72px !important
padding-bottom: 72px !important
}
.icon_contact:hover {
color: blue;
border-color: white;
border-width: 1px;
}
.landing__footer .doc-link {
@@ -97,40 +134,25 @@
background-repeat: no-repeat !important;
background-position: top;
background-size: contain !important;
background-image: url(https://cdn.quasar-framework.org/img/landing_first_section.png) !important
background-image: url(../../statics/images/landing_first_section.png) !important
}
@media (max-width: 718px) {
.landing__hero {
text-align: center
}
.landing__header {
height: 9vh
}
.landing__hero .text-h1 {
font-size: 3rem;
line-height: 3.05rem;
margin-bottom: 24px
}
.landing > section.padding {
padding-top: 50px;
//padding-bottom: 90px
}
.landing .feature-item {
text-align: center
}
.landing__hero-content {
//padding-bottom: 180px
}
.landing__hero-btns {
-webkit-box-pack: center;
-ms-flex-pack: center;
justify-content: center
}
.feat-descr {
font-size: 1.15rem;
}
.feat-descr:hover {
transition: opacity 0.5s ease-in-out;
opacity: 0.9;
}
.q-col-gutter-sm {
padding: 50px 50px;
//margin-left: -48px
}
body.mobile .landing {
background: unset
//background: unset
}
body.mobile .landing:before {
@@ -142,10 +164,12 @@ body.mobile .landing:before {
right: 0;
bottom: 0;
z-index: -1;
background: #000 url(../../statics/images/cover.jpg) 50%;
//background: #000 url(../../statics/images/cover.jpg) 50%;
background-size: cover
}
/*
@-webkit-keyframes logo-rotate {
to {
-webkit-transform: rotate(-1turn);
@@ -159,9 +183,7 @@ body.mobile .landing:before {
transform: rotate(-1turn)
}
}
*/
.home {
//background-color: rgb(250, 250, 250);
@@ -179,15 +201,14 @@ body.mobile .landing:before {
.shadow {
//color: white;
text-shadow: 2px 2px 4px #000000;
text-shadow: 2px 2px 4px $grayshadow;
}
.shadow-max {
//color: white;
text-shadow: 4px 4px 8px #000000;
text-shadow: 4px 4px 8px $grayshadow;
}
.text-h1 {
font-size: 6rem;
font-weight: 300;
@@ -195,25 +216,174 @@ body.mobile .landing:before {
letter-spacing: -.01562em;
}
.text-h2 {
font-size: 3.75rem;
font-weight: 300;
line-height: 3.75rem;
letter-spacing: -.00833em;
}
.text-weight-bold {
font-weight: 700;
}
.text-subtitle1 {
font-size: 1.25rem;
font-size: 1.35rem;
font-weight: 400;
line-height: 1.75rem;
text-shadow: 4px 4px 8px $grayshadow;
letter-spacing: .00937em;
&.big {
font-size: 1.5rem;
}
}
.text-subtitle2 {
.text-subtitle2 {
font-size: 1.15rem;
font-weight: 400;
line-height: 1.75rem;
letter-spacing: .00937em;
text-shadow: 4px 4px 8px $grayshadow;
}
.text-subtitle3 {
font-size: 1rem;
font-weight: 400;
line-height: 1.75rem;
letter-spacing: .00937em;
text-shadow: 2px 2px 4px $grayshadow;
}
.homep-cover-img-1 {
background: #000 url(../../statics/images/cover.jpg) no-repeat 50% fixed;
//transition: background-image 1s ease-in-out;
}
.homep-cover-img-2 {
background: #000 url(../../statics/images/hand_people.jpg) no-repeat 50% fixed;
//transition: background-image 1s ease-in-out;
}
.homep-cover-img-3 {
background: #000 url(../../statics/images/cibo_sano.jpg) no-repeat 50% fixed;
//transition: background-image 1s ease-in-out;
}
.homep-cover-img.hide-filter:before {
opacity: 0
}
.landing__footer-icons {
font-size: 28px
}
.landing__footer-icons a {
margin: 0 8px 8px;
text-decoration: none;
outline: 0;
color: #fff;
transition: color .28s
}
.landing__footer-icons a:hover {
color: #e0e0e0
}
.doc-img {
max-width: 100%;
}
.mylist {
background: #3fdaff;
padding-left: 20px;
}
.clgutter {
margin-top: 20px;
padding: 10px;
}
.carousel_img_3 {
//background-image: url(../../statics/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: 0px;
padding: 0px;
}
.landing__hero .text-h1 {
font-size: 3rem;
line-height: 3.05rem;
margin-bottom: 24px
}
.landing > section.padding {
padding: 40px 16px
//padding-bottom: 90px
}
.landing__features h4, .landing__features h6 {
margin: 20px 0
}
h4 {
line-height: 1.4;
text-shadow: 4px 4px 8px $grayshadow;
}
.landing .feature-item {
text-align: center;
margin-top: 20px;
}
.landing__hero-content {
padding-bottom: 180px
}
.landing__hero-btns {
-webkit-box-pack: center;
-ms-flex-pack: center;
justify-content: center
}
.q-col-gutter-sm {
padding: 10px 5px;
}
.text-subtitle1 {
font-size: 1.25rem;
}
.text-subtitle2 {
font-size: 1rem;
}
.text-subtitle3 {
font-size: 0.75rem;
}
.carousel_img_3 {
//background-image: url(../../statics/images/cibo_sano.jpg);
background-size: 620px 620px !important;
background-position: 50% top !important;
background-repeat: no-repeat !important;
}
}
.custom-caption {
text-align: center;
padding: 12px;
color: white;
background-color: rgba(0, 0, 0, .3);
}

View File

@@ -4,18 +4,38 @@ import { GlobalStore, UserStore } from '@store'
import { Logo } from '../../components/logo'
import VueScrollReveal from 'vue-scroll-reveal'
import { tools } from '@src/store/Modules/tools'
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({
components: { Logo }
})
export default class Home extends Vue {
text: string = ''
visibile: boolean = false
cardvisible: string = 'hidden'
displaycard: string = 'block'
svgclass: string = 'svgclass'
$t: any
public text: string = ''
public visibile: boolean = false
public cardvisible: string = 'hidden'
public displaycard: string = 'block'
public svgclass: string = 'svgclass'
public $t: any
// public firstClassSection: string = 'landing_background fade homep-cover-img animate-fade homep-cover-img-1'
public firstClassSection: string = 'fade homep-cover-img animate-fade homep-cover-img-1'
public $q
public polling
public slide = 'first'
public animare: number = 0
constructor() {
super()
@@ -23,19 +43,46 @@ export default class Home extends Vue {
this.initprompt()
}
created() {
// console.log('Home created...')
public mounted() {
let primo = true
const mytime = 10000
this.polling = setInterval(() => {
this.firstClassSection = 'landing_background fade homep-cover-img ' + (primo ? 'homep-cover-img-2' : 'homep-cover-img-1')
primo = !primo
// console.log('this.firstClassSection', this.firstClassSection)
}, mytime)
}
get appname() {
return process.env.APP_NAME
}
public beforeDestroy() {
console.log('beforeDestroy')
clearInterval(this.polling)
}
public created() {
this.animare = process.env.DEV ? 0 : 8000
GlobalStore.actions.prova()
}
get isLogged(){
get isLogged() {
return UserStore.state.isLogged
}
get TelegramSupport() {
return process.env.TELEGRAM_SUPPORT
}
meta() {
get FBPage() {
return process.env.URL_FACEBOOK
}
public meta() {
return {
keywords: { name: 'keywords', content: 'Quasar website' },
// meta tags
@@ -43,13 +90,12 @@ export default class Home extends Vue {
mykey: { name: 'mykey', content: 'Key 1' },
description: { name: 'description', content: 'Page 1' },
keywords: { name: 'keywords', content: 'Quasar website' },
equiv: { 'http-equiv': 'Content-Type', content: 'text/html; charset=UTF-8' }
equiv: { 'http-equiv': 'Content-Type', 'content': 'text/html; charset=UTF-8' }
}
}
}
mystilecard() {
public mystilecard() {
return {
visibility: this.cardvisible,
display: this.displaycard
@@ -60,23 +106,18 @@ export default class Home extends Vue {
return GlobalStore.state.conta
}
public getenv(myvar) {
return process.env[myvar]
}
set conta(valore) {
GlobalStore.actions.setConta(valore)
let my = this.$q.i18n.lang
this.showNotif(String(my))
const my = this.$q.lang.isoName
tools.showNotif(this.$q, String(my))
}
showNotif(message: string, color = 'primary', icon = '') {
this.$q.notify({
color,
icon,
message
})
}
initprompt() {
window.addEventListener('beforeinstallprompt', function (event) {
public initprompt() {
window.addEventListener('beforeinstallprompt', function(event) {
// console.log('******************************** beforeinstallprompt fired')
event.preventDefault()
// console.log('§§§§§§§§§§§§§§§§§§§§ IMPOSTA DEFERRED PROMPT !!!!!!!!!!!!!!!!! ')
@@ -86,27 +127,27 @@ export default class Home extends Vue {
}
get isInCostruction () {
get isInCostruction() {
return process.env.IN_CONSTRUCTION === '1'
}
getPermission() {
public getPermission() {
return Notification.permission
}
NotServiceWorker() {
public NotServiceWorker() {
return (!('serviceWorker' in navigator))
}
PagLogin () {
public PagLogin() {
this.$router.replace('/signin')
}
PagReg () {
public PagReg() {
this.$router.replace('/signup')
}
displayConfirmNotification() {
public displayConfirmNotification() {
let options = null
if ('serviceWorker' in navigator) {
options = {
@@ -127,21 +168,21 @@ export default class Home extends Vue {
if ('serviceWorker' in navigator) {
navigator.serviceWorker.ready
.then(function (swreg) {
.then(function(swreg) {
swreg.showNotification('Successfully subscribed!', options)
})
}
}
}
urlBase64ToUint8Array(base64String) {
let padding = '='.repeat((4 - base64String.length % 4) % 4)
let base64 = (base64String + padding)
public urlBase64ToUint8Array(base64String) {
const padding = '='.repeat((4 - base64String.length % 4) % 4)
const base64 = (base64String + padding)
.replace(/\-/g, '+')
.replace(/_/g, '/')
let rawData = window.atob(base64)
let outputArray = new Uint8Array(rawData.length)
const rawData = window.atob(base64)
const outputArray = new Uint8Array(rawData.length)
for (let i = 0; i < rawData.length; ++i) {
outputArray[i] = rawData.charCodeAt(i)
@@ -149,22 +190,21 @@ export default class Home extends Vue {
return outputArray
}
dataURItoBlob(dataURI) {
let byteString = atob(dataURI.split(',')[1])
let mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0]
let ab = new ArrayBuffer(byteString.length)
let ia = new Uint8Array(ab)
public dataURItoBlob(dataURI) {
const byteString = atob(dataURI.split(',')[1])
const mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0]
const ab = new ArrayBuffer(byteString.length)
const ia = new Uint8Array(ab)
for (let i = 0; i < byteString.length; i++) {
ia[i] = byteString.charCodeAt(i)
}
let blob = new Blob([ab], { type: mimeString })
const blob = new Blob([ab], { type: mimeString })
return blob
}
showNotificationExample() {
public showNotificationExample() {
let options = null
let mythis = this
const mythis = this
if ('serviceWorker' in navigator) {
options = {
body: mythis.$t('notification.subscribed'),
@@ -177,30 +217,27 @@ export default class Home extends Vue {
tag: 'confirm-notification',
renotify: true, // if it's already sent, will Vibrate anyway
actions: [
{ action: 'confirm', title: mythis.$t('dialog.ok'), icon: '/statics/icons/android-chrome-192x192.png', }
{ action: 'confirm', title: mythis.$t('dialog.ok'), icon: '/statics/icons/android-chrome-192x192.png' }
// { action: 'cancel', title: 'Cancel', icon: '/statics/icons/android-chrome-192x192.png', }
]
}
navigator.serviceWorker.ready
.then(function (swreg) {
.then(function(swreg) {
swreg.showNotification('aaa', options)
})
}
}
public askfornotification() {
tools.showNotif(this.$q, this.$t('notification.waitingconfirm'), {color: 'positive', icon: 'notifications'})
askfornotification() {
this.showNotif(this.$t('notification.waitingconfirm'), 'positive', 'notifications')
let mythis = this
Notification.requestPermission(function (result) {
Notification.requestPermission((result) => {
console.log('User Choice', result)
if (result === 'granted') {
mythis.showNotif(mythis.$t('notification.confirmed'), 'positive', 'notifications')
tools.showNotif(this.$q, this.$t('notification.confirmed'), {color: 'positive', icon: 'notifications'})
} else {
mythis.showNotif(mythis.$t('notification.denied'), 'negative', 'notifications')
tools.showNotif(this.$q, this.$t('notification.denied'), {color: 'negative', icon: 'notifications'})
// displayConfirmNotification();
}
@@ -208,8 +245,7 @@ export default class Home extends Vue {
}
test_fetch() {
public test_fetch() {
fetch('https:/httpbin.org/post', {
method: 'POST',
headers: {
@@ -219,20 +255,22 @@ export default class Home extends Vue {
// mode: 'no-cors',
mode: 'cors',
body: JSON.stringify({ message: 'Does this work?' })
}).then(function (response) {
}).then(function(response) {
console.log(response)
if (response)
if (response) {
return response.json()
else
}
else {
return null
}).then(function (data) {
}
}).then(function(data) {
console.log(data)
}).catch(function (err) {
}).catch(function(err) {
console.log(err)
})
}
openCreatePostModal() {
public openCreatePostModal() {
console.log('APERTO ! openCreatePostModal')
this.conta = this.conta + 1
@@ -248,4 +286,20 @@ export default class Home extends Vue {
}
}
/*
backgroundSequence() {
window.clearTimeout()
let k = 0
for (let i = 0; i < bgImageArray.length; i++) {
const mythis = this
setTimeout(function() {
document.documentElement.style.background = 'url(' + mythis.base + mythis.bgImageArray[k] + ') no-repeat center center fixed'
document.documentElement.style.backgroundSize = 'cover'
if ((k + 1) === mythis.bgImageArray.length) { setTimeout(function() { mythis.backgroundSequence() }, (mythis.secs * 1000))} else { k++ }
}, (mythis.secs * 1000) * i)
}
}
backgroundSequence()
*/
}

View File

@@ -3,104 +3,406 @@
<div class="landing">
<section>
<div class="landing__hero">
<div class="landing__header"></div>
<div class="landing__hero-content row justify-center q-gutter-xl">
<div class="row">
<logo></logo>
</div>
<div class="flex justify-end">
<div class="q-gutter-sm">
<div class="text-h1 shadow-max">FreePlanet</div>
<div class="text-subtitle1 shadow text-italic q-pl-sm">{{$t('msg.sottoTitoloApp')}}
</div>
<div class="text-subtitle1 shadow big text-italic q-pl-sm"><strong>{{$t('msg.sottoTitoloApp2')}}</strong>
</div>
<div class="text-subtitle2 shadow text-italic q-pl-sm ">{{$t('msg.sottoTitoloApp3')}}
<q-carousel
animated
:autoplay="animare"
swipeable
infinite
navigation
transition-next="slide-left"
transition-prev="slide-right"
v-model="slide"
height="100%"
width="100%"
>
<q-carousel-slide name="first" img-src="../../statics/images/cover.jpg">
<div class="landing__header"></div>
<div class="landing__hero-content row justify-center q-gutter-xs clgutter">
<div class="row">
<logo></logo>
</div>
<div class="flex justify-end">
<div class="q-gutter-xs testo-banda clgutter">
<div class="text-h1 shadow-max">{{appname}}</div>
<div class="text-subtitle1 shadow text-italic q-pl-sm">
{{$t('msg.sottoTitoloApp')}}
</div>
<div class="text-subtitle1 shadow-max big text-italic q-pl-sm"><strong>{{$t('msg.sottoTitoloApp2')}}</strong>
</div>
<div class="text-subtitle2 shadow text-italic q-pl-sm">
{{$t('msg.sottoTitoloApp3')}}
</div>
<div class="text-subtitle3 shadow text-italic q-pl-sm ">
{{$t('msg.sottoTitoloApp4')}}
</div>
<div v-if="isInCostruction" style="margin: 5px;">
<q-banner
rounded
class="bg-primary text-white"
style="text-align: center;">
<span class="mybanner">{{$t('msg.underconstruction')}}</span>
</q-banner>
<br>
</div>
<div v-else>
<div v-if="!isLogged" style="margin: 5px; padding: 5px;" class="home">
<q-btn rounded size="lg" color="primary" @click="PagLogin"
class="btn-start">
{{$t('login.enter')}}
</q-btn>
<q-btn rounded size="lg" color="positive" @click="PagReg"
class="btn-start">
{{$t('reg.submit')}}
</q-btn>
</div>
</div>
<div v-if="isLogged">
<div>
<!--<q-field-->
<!--v-if="getPermission() === 'granted'"-->
<!--icon="notifications"-->
<!--class="shadow"-->
<!--:label="$t('notification.titlegranted')"-->
<!--:helper="$t('notification.statusnot')">-->
<!--</q-field>-->
<q-field
v-if="NotServiceWorker()"
class="shadow"
icon="notifications"
label="Service Worker not present"
>
</q-field>
</div>
<div>
<q-btn v-if="getPermission() !== 'granted'"
class="enable-notifications shadow"
color="primary" rounded
size="md"
icon="notifications" @click="askfornotification"
:label="$t('notification.ask')"/>
<!--<q-btn v-if="getPermission() === 'granted'" class="enable-notifications" color="primary" rounded size="lg" icon="notifications" @click="showNotificationExample" label="Send Notification"/>-->
<!--<q-btn v-if="getPermission() === 'granted'" class="enable-notifications" color="secondary" rounded size="lg" icon="notifications" @click="createPushSubscription" label="Create Push Subscription !"/>-->
</div>
</div>
<!--
<q-btn>
Canale Telegram: <a href="https://t.me/freeplanet_channel" target="_blank"
style="color: white;">
<q-icon class="fab fa-telegram" size="2rem"/>
</a>
</q-btn>
-->
<div v-if="isInCostruction" style="margin: 5px;">
<q-alert
type="info"
class="q-mb-sm">
{{$t('msg.underconstruction')}}
</q-alert>
<br>
</div>
<div v-else>
<div v-if="!isLogged" style="margin: 5px; padding: 5px;" class="home">
<q-btn rounded size="lg" color="primary" @click="PagLogin" class="btn-start">
{{$t('login.enter')}}
</q-btn>
<q-btn rounded size="lg" color="positive" @click="PagReg" class="btn-start">
{{$t('reg.submit')}}
</q-btn>
<div class="q-pt-md q-pl-sm">
<div class="text-body2">Ver. {{getenv('APP_VERSION')}}</div>
</div>
</div>
</div>
<div>
<q-field
v-if="getPermission() === 'granted'"
icon="notifications"
class="shadow"
:label="$t('notification.titlegranted')"
:helper="$t('notification.statusnot')">
</q-field>
<q-field
v-if="NotServiceWorker()"
class="shadow"
icon="notifications"
label="Service Worker not present"
>
</q-field>
</div>
<div>
<q-btn v-if="getPermission() !== 'granted'" class="enable-notifications shadow"
color="primary" rounded
size="lg"
icon="notifications" @click="askfornotification"
:label="$t('notification.ask')"/>
<!--<q-btn v-if="getPermission() === 'granted'" class="enable-notifications" color="primary" rounded size="lg" icon="notifications" @click="showNotificationExample" label="Send Notification"/>-->
<!--<q-btn v-if="getPermission() === 'granted'" class="enable-notifications" color="secondary" rounded size="lg" icon="notifications" @click="createPushSubscription" label="Create Push Subscription !"/>-->
</div>
<!--<div class="q-pt-md q-pl-sm">-->
<!--<div class="landing__hero-btns q-gutter-md row items-center"><a tabindex="0"-->
<!--type="button"-->
<!--href="/introduction-to-quasar"-->
<!--class="q-btn inline relative-position q-btn-item non-selectable q-btn&#45;&#45;rectangle bg-white text-primary q-focusable q-hoverable q-btn&#45;&#45;push">-->
<!--<div class="q-focus-helper"></div>-->
<!--<div class="q-btn__content text-center col items-center q-anchor&#45;&#45;skip justify-center row">-->
<!--<div>About</div>-->
<!--</div>-->
<!--</a><a tabindex="0" type="button" href="/start"-->
<!--class="q-btn inline relative-position q-btn-item non-selectable q-btn&#45;&#45;rectangle bg-white text-primary q-focusable q-hoverable q-btn&#45;&#45;push">-->
<!--<div class="q-focus-helper"></div>-->
<!--<div class="q-btn__content text-center col items-center q-anchor&#45;&#45;skip justify-center row">-->
<!--<div>Get started</div>-->
<!--</div>-->
<!--</a>-->
<!--<div class="text-body2">v1.0.0-beta.4</div>-->
<!--</div>-->
<!--</div>-->
</div>
</div>
<div class="landing__arrow absolute-bottom text-center">
<i aria-hidden="true" class="q-icon text-h2 text-white material-icons">expand_more</i>
</div>
</q-carousel-slide>
<q-carousel-slide name="second" img-src="../../statics/images/hand_people.jpg">
<div class="landing__header"></div>
<div class="landing__hero-content row justify-center q-gutter-xs clgutter">
<div class="row">
<logo></logo>
</div>
<div class="flex justify-end">
<div class="q-gutter-xs testo-banda clgutter">
<div class="text-h1 shadow-max">FreePlanet</div>
<div class="text-subtitle1 shadow text-italic q-pl-sm">
{{$t('msg.sottoTitoloApp')}}
</div>
<div class="text-subtitle1 shadow-max big text-italic q-pl-sm"><strong>{{$t('msg.sottoTitoloApp2')}}</strong>
</div>
<div class="text-subtitle2 shadow text-italic q-pl-sm">
{{$t('msg.sottoTitoloApp3')}}
</div>
<div class="text-subtitle3 shadow text-italic q-pl-sm ">
{{$t('msg.sottoTitoloApp4')}}
</div>
<div v-if="isInCostruction" style="margin: 5px;">
<q-banner
rounded
class="bg-primary text-white"
style="text-align: center;">
<span class="mybanner">{{$t('msg.underconstruction')}}</span>
</q-banner>
<br>
</div>
<div v-else>
<div v-if="!isLogged" style="margin: 5px; padding: 5px;" class="home">
<q-btn rounded size="lg" color="primary" @click="PagLogin"
class="btn-start">
{{$t('login.enter')}}
</q-btn>
<q-btn rounded size="lg" color="positive" @click="PagReg"
class="btn-start">
{{$t('reg.submit')}}
</q-btn>
</div>
</div>
<div v-if="isLogged">
<div>
<!--<q-field-->
<!--v-if="getPermission() === 'granted'"-->
<!--icon="notifications"-->
<!--class="shadow"-->
<!--:label="$t('notification.titlegranted')"-->
<!--:helper="$t('notification.statusnot')">-->
<!--</q-field>-->
<q-field
v-if="NotServiceWorker()"
class="shadow"
icon="notifications"
label="Service Worker not present"
>
</q-field>
</div>
<div>
<q-btn v-if="getPermission() !== 'granted'"
class="enable-notifications shadow"
color="primary" rounded
size="md"
icon="notifications" @click="askfornotification"
:label="$t('notification.ask')"/>
<!--<q-btn v-if="getPermission() === 'granted'" class="enable-notifications" color="primary" rounded size="lg" icon="notifications" @click="showNotificationExample" label="Send Notification"/>-->
<!--<q-btn v-if="getPermission() === 'granted'" class="enable-notifications" color="secondary" rounded size="lg" icon="notifications" @click="createPushSubscription" label="Create Push Subscription !"/>-->
</div>
</div>
<div class="q-pt-md q-pl-sm">
<div class="text-body2">Ver. {{getenv('APP_VERSION')}}</div>
</div>
</div>
</div>
</div>
<div class="landing__arrow absolute-bottom text-center">
<i aria-hidden="true" class="q-icon text-h2 text-white material-icons">expand_more</i>
</div>
<!--<div class="absolute-bottom custom-caption">-->
<!--<div class="text-h2">Second stop</div>-->
<!--<div class="text-subtitle1">Famous City</div>-->
<!--</div>-->
</q-carousel-slide>
<q-carousel-slide name="third" img-src="../../statics/images/cibo_sano.jpg" class="carousel_img_3">
<div class="landing__header"></div>
<div class="landing__hero-content row justify-center q-gutter-xs clgutter">
<div class="row">
<logo></logo>
</div>
<div class="flex justify-end">
<div class="q-gutter-xs testo-banda clgutter">
<div class="text-h1 shadow-max">FreePlanet</div>
<div class="text-subtitle1 shadow text-italic q-pl-sm">
{{$t('msg.sottoTitoloApp')}}
</div>
<div class="text-subtitle1 shadow-max big text-italic q-pl-sm"><strong>{{$t('msg.sottoTitoloApp2')}}</strong>
</div>
<div class="text-subtitle2 shadow text-italic q-pl-sm">
{{$t('msg.sottoTitoloApp3')}}
</div>
<div class="text-subtitle3 shadow text-italic q-pl-sm ">
{{$t('msg.sottoTitoloApp4')}}
</div>
<div v-if="isInCostruction" style="margin: 5px;">
<q-banner
rounded
class="bg-primary text-white"
style="text-align: center;">
<span class="mybanner">{{$t('msg.underconstruction')}}</span>
</q-banner>
<br>
</div>
<div v-else>
<div v-if="!isLogged" style="margin: 5px; padding: 5px;" class="home">
<q-btn rounded size="lg" color="primary" @click="PagLogin"
class="btn-start">
{{$t('login.enter')}}
</q-btn>
<q-btn rounded size="lg" color="positive" @click="PagReg"
class="btn-start">
{{$t('reg.submit')}}
</q-btn>
</div>
</div>
<div v-if="isLogged">
<div>
<!--<q-field-->
<!--v-if="getPermission() === 'granted'"-->
<!--icon="notifications"-->
<!--class="shadow"-->
<!--:label="$t('notification.titlegranted')"-->
<!--:helper="$t('notification.statusnot')">-->
<!--</q-field>-->
<q-field
v-if="NotServiceWorker()"
class="shadow"
icon="notifications"
label="Service Worker not present"
>
</q-field>
</div>
<div>
<q-btn v-if="getPermission() !== 'granted'"
class="enable-notifications shadow"
color="primary" rounded
size="md"
icon="notifications" @click="askfornotification"
:label="$t('notification.ask')"/>
<!--<q-btn v-if="getPermission() === 'granted'" class="enable-notifications" color="primary" rounded size="lg" icon="notifications" @click="showNotificationExample" label="Send Notification"/>-->
<!--<q-btn v-if="getPermission() === 'granted'" class="enable-notifications" color="secondary" rounded size="lg" icon="notifications" @click="createPushSubscription" label="Create Push Subscription !"/>-->
</div>
</div>
<div class="q-pt-md q-pl-sm">
<div class="text-body2">Ver. {{getenv('APP_VERSION')}}</div>
</div>
</div>
</div>
</div>
<div class="landing__arrow absolute-bottom text-center">
<i aria-hidden="true" class="q-icon text-h2 text-white material-icons">expand_more</i>
</div>
<!--<div class="absolute-bottom custom-caption">-->
<!--<div class="text-h2">Third stop</div>-->
<!--<div class="text-subtitle1">Famous Bridge</div>-->
<!--</div>-->
</q-carousel-slide>
</q-carousel>
</div>
</section>
<section class="padding bg-white text-grey-10 text-center" v-scroll-reveal.reset>
<div class="landing__features row items-start q-col-gutter-sm">
<div class="col-12 text-center">
<div class="feature-item q-mx-md"><img src="statics/images/group-together.jpg"
class="doc-img"></div>
</div>
<div class="col-12 text-center"><h4>{{$t('homepage.descrapp_title1')}}</h4>
<p v-html="$t('homepage.descrapp_pag1')"></p>
<p v-html="$t('homepage.descrapp_pag2')"></p>
</div>
</div>
</section>
<section class="padding bg-primary landing__swirl-bg" v-scroll-reveal.reset>
<div class="landing__features row justify-between items-start q-col-gutter-sm">
<div class="col-12 col-sm-5">
<div class="feature-item"><i aria-hidden="true"
class="q-icon fas fa-users"> </i><h4>
{{$t('homepage.freesocial.title')}}</h4>
<p class="feat-descr" v-html="$t('homepage.freesocial.descr')"></p></div>
</div>
<div class="col-12 col-sm-5">
<div class="feature-item"><i aria-hidden="true"
class="q-icon fas fa-user-clock"> </i><h4>
{{$t('homepage.freetalent.title')}}</h4>
<p class="feat-descr" v-html="$t('homepage.freetalent.descr')"></p></div>
</div>
<div class="col-12 col-sm-5">
<div class="feature-item"><i aria-hidden="true"
class="q-icon fas fa-apple-alt"> </i><h4>
{{$t('homepage.freegas.title')}}</h4>
<p class="feat-descr" v-html="$t('homepage.freegas.descr')"></p></div>
</div>
<div class="col-12 col-sm-5">
<div class="feature-item"><i aria-hidden="true"
class="q-icon fas fa-home"> </i><h4>
{{$t('homepage.freeliving.title')}}</h4>
<p class="feat-descr" v-html="$t('homepage.freeliving.descr')"></p></div>
</div>
</div>
</section>
<section class="padding bg-indigo-8" v-scroll-reveal.reset>
<div class="landing__features row justify-between items-start q-col-gutter-sm">
<div class="col-12 col-sm-5">
<div class="feature-item"><i aria-hidden="true"
class="q-icon fas fa-people-carry"> </i><h4>
{{$t('homepage.freecollabora.title')}}</h4>
<p class="feat-descr" v-html="$t('homepage.freecollabora.descr')"></p></div>
</div>
<div class="col-12 col-sm-5">
<div class="feature-item"><i aria-hidden="true"
class="q-icon fas fa-hands-helping"> </i><h4>
{{$t('homepage.freesostieni.title')}}</h4>
<p class="feat-descr" v-html="$t('homepage.freesostieni.descr')"></p></div>
</div>
<div class="col-12 col-sm-5">
<div class="feature-item"><i aria-hidden="true"
class="q-icon fas fa-browser"> </i>
<div class="q-gutter-sm"><i aria-hidden="true"
class="q-icon fas fa-browser"> </i><i
aria-hidden="true" class="q-icon fab fa-chrome"> </i><i
aria-hidden="true" class="q-icon fab fa-firefox"> </i><i
aria-hidden="true" class="q-icon fab fa-safari"> </i><i
aria-hidden="true" class="q-icon fab fa-edge"> </i></div>
<h4>{{$t('homepage.multiplatform.title')}}</h4>
<p class="feat-descr" v-html="$t('homepage.multiplatform.descr')"></p></div>
</div>
<div class="col-12 col-sm-5">
<div class="feature-item"><i aria-hidden="true"
class="q-icon fas fa-universal-access"> </i><h4>
{{$t('homepage.free.title')}}</h4>
<p class="feat-descr" v-html="$t('homepage.free.descr')"></p></div>
</div>
</div>
</section>
<section class="landing__footer">
<div class="text-center">
<div class="landing__footer-icons row flex-center">
<a :href="FBPage" target="_blank">
<i aria-hidden="true" class="q-icon fab fa-facebook-f icon_contact"> </i></a>
<a :href="TelegramSupport" target="_blank">
<i aria-hidden="true" class="q-icon fab fa-telegram icon_contact"></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 class="q-mt-xs text-weight-thin" style="text-shadow: 4px 4px 8px #555;">
{{$t('msg.myAppName')}} - {{$t('homepage.contacts')}}
<!--Released under the-->
<!--<a href="https://github.com/quasarframework/quasar/blob/dev/LICENSE" target="_blank"-->
<!--rel="noopener noreferrer" class="doc-link">-->
<!--MIT LICENSE-->
<!--<i aria-hidden="true"-->
<!--class="q-icon material-icons">launch</i></a>-->
<!--| <a href="https://www.iubenda.com/privacy-policy/40685560" target="_blank"-->
<!--rel="noopener noreferrer" class="doc-link">Privacy Policy<i aria-hidden="true"-->
<!--class="q-icon material-icons">launch</i></a>-->
</div>
</div>
</section>
<q-page-scroller position="bottom-right" :scroll-offset="850" :offset="[18, 18]" style="opacity: 0.3">
<q-btn fab icon="keyboard_arrow_up" color="accent" />
</q-page-scroller>
</div>
</q-page>

View File

@@ -1,98 +0,0 @@
<template>
<q-page class="landing text-white">
<section>
<div class="landing__hero">
<div style="height: 28vh;"></div>
<div class="landing__hero-content row justify-center q-gutter-xl">
<div class="row"><img src="https://cdn.quasar-framework.org/logo/svg/quasar-logo.svg"
class="landing__logo"></div>
<div class="flex justify-end">
<div class="q-gutter-sm">
<div class="text-h1">
<div class="text-weight-bold">Quasar</div>
<div>Framework</div>
</div>
<div class="text-subtitle1 text-italic q-pl-sm">High performance, <strong>Material
Design
2</strong>, full front end stack with <strong>Vuejs</strong></div>
<div class="q-pt-md q-pl-sm">
<div class="landing__hero-btns q-gutter-md row items-center"><a tabindex="0"
type="button"
href="/introduction-to-quasar"
class="q-btn inline relative-position q-btn-item non-selectable q-btn--rectangle bg-white text-primary q-focusable q-hoverable q-btn--push">
<div class="q-focus-helper"></div>
<div class="q-btn__content text-center col items-center q-anchor--skip justify-center row">
<div>About</div>
</div>
</a><a tabindex="0" type="button" href="/start"
class="q-btn inline relative-position q-btn-item non-selectable q-btn--rectangle bg-white text-primary q-focusable q-hoverable q-btn--push">
<div class="q-focus-helper"></div>
<div class="q-btn__content text-center col items-center q-anchor--skip justify-center row">
<div>Get started</div>
</div>
</a>
<div class="text-body2">v1.0.0-beta.4</div>
</div>
</div>
</div>
</div>
</div>
<div class="landing__arrow absolute-bottom text-center"><i aria-hidden="true"
class="q-icon text-h2 text-white material-icons">expand_more</i>
</div>
</div>
<!--<div>-->
<!--<logo></logo>-->
<!--</div>-->
<!--<div>-->
<!--&lt;!&ndash; the row with a type of gutter &ndash;&gt;-->
<!--<q-alert-->
<!--avatar="statics/boy-avatar.png"-->
<!--color="primary"-->
<!--message="Jack"-->
<!--detail="Per un mondo più Consapevole"-->
<!--/>-->
<!--</div>-->
<!--<div>-->
<!--<q-btn v-if="getPermission() !== 'granted'" class="enable-notifications" color="primary" rounded-->
<!--size="lg"-->
<!--icon="notifications" @click="askfornotification" :label="$t('notification.ask')"/>-->
<!--&lt;!&ndash;<q-btn v-if="getPermission() === 'granted'" class="enable-notifications" color="primary" rounded size="lg" icon="notifications" @click="showNotificationExample" label="Send Notification"/>&ndash;&gt;-->
<!--&lt;!&ndash;<q-btn v-if="getPermission() === 'granted'" class="enable-notifications" color="secondary" rounded size="lg" icon="notifications" @click="createPushSubscription" label="Create Push Subscription !"/>&ndash;&gt;-->
<!--</div>-->
<!--<div>-->
<!--<q-chip square color="secondary">-->
<!--{{$t('notification.status')}}-->
<!--</q-chip>-->
<!--</div>-->
<!--<div>-->
<!--<q-field-->
<!--v-if="getPermission() === 'granted'"-->
<!--icon="notifications"-->
<!--:label="$t('notification.titlegranted')"-->
<!--helper="Stato Notifiche">-->
<!--</q-field>-->
<!--<q-field-->
<!--v-if="NotServiceWorker()"-->
<!--icon="notifications"-->
<!--label="Service Worker not present"-->
<!--&gt;-->
<!--</q-field>-->
<!--</div>-->
</section>
</q-page>
</template>
<script lang="ts" src="./home.ts">
</script>
<style lang="scss" scoped>
@import './home.scss';
</style>

View File

@@ -43,7 +43,10 @@ export const RouteConfig: VueRouteConfig[] = [
{
path: '/admin/cfgserv',
name: 'cfgserv',
component: () => import('@/components/admin/cfgServer/cfgServer.vue')
component: () => import('@/components/admin/cfgServer/cfgServer.vue'),
meta: {
middleware: [auth]
}
},
{
path: '/admin/testp1/:category',

View File

@@ -0,0 +1,22 @@
.gu-mirror {
position: fixed !important;
margin: 0 !important;
z-index: 9999 !important;
opacity: 0.8;
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=80)";
filter: alpha(opacity=80);
}
.gu-hide {
display: none !important;
}
.gu-unselectable {
-webkit-user-select: none !important;
-moz-user-select: none !important;
-ms-user-select: none !important;
user-select: none !important;
}
.gu-transit {
opacity: 0.2;
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=20)";
filter: alpha(opacity=20);
}

695
src/statics/i18n.js Normal file
View File

@@ -0,0 +1,695 @@
const messages = {
it: {
dialog: {
ok: 'Ok',
yes: 'Si',
no: 'No',
delete: 'Elimina',
cancel: 'Annulla',
msg: {
titledeleteTask: 'Elimina Task',
deleteTask: "Vuoi Eliminare {mytodo}?"
}
},
comp: {
Conta: "Conta",
},
msg: {
hello: 'Buongiorno',
myAppName: 'FreePlanet',
underconstruction: 'App in costruzione...',
myDescriz: '',
sottoTitoloApp: 'Il primo Vero Social',
sottoTitoloApp2: 'Libero, Equo e Solidale',
sottoTitoloApp3: 'dove Vive Consapevolezza e Aiuto Comunitario',
sottoTitoloApp4: 'Gratuito e senza Pubblicità',
},
homepage: {
descrapp_title1: 'Uniti per Evolvere e Sperimentare',
descrapp_pag1: 'Riscopri come il valore della <strong>Condivisione</strong> e della <strong>Cooperazione</strong>, possa aiutarci a ritrovare il profondo ' +
'senso della <strong>Vita</strong>, perduto in questa società consumista, e riporti quei <strong>Sani Pricìpi Naturali</strong> ed Umani di <strong>Fratellanza</strong>' +
' che intere popolazioni antiche conoscevano bene.',
descrapp_pag2: 'E\' giunta l\'ora di utilizzare i nuovi strumenti <strong>Tecnologici</strong> a nostro <strong>favore</strong>, per <strong>Liberarci</strong> ' +
'così piano piano dalla <strong>schiavitù</strong> del <strong>"Lavoro per generare Denaro"</strong> e trasformando le nostre <strong>Capacitá</strong> in ' +
'<strong>Risorse Umane</strong> per poterci sostenere e vivere in <strong>Armonia</strong> con gli altri.',
freesocial: {
title: 'Free Social',
descr: 'Una Community organizzata per <strong>Categorie</strong>, dove potrai unirti a <strong>Gruppi Tematici</strong>, ' +
'Condividere <strong>Esperienze</strong> e unire Competenze per organizzare e sostenere <strong>Progetti Innovativi</strong> per il Popolo.<br><br>' +
'Verranno evidenziati sviluppi <strong>Etici</strong> come l\'<strong>Auto-Produzione</strong>, la <strong>Sostenibilitá</strong>, ' +
'la Buona <strong>Salute Naturale</strong> e il <strong>Rispetto per l\'Ambiente</strong> e per tutti gli <strong>Esseri Viventi</strong> di questo ' +
'<strong>Pianeta</strong>. Chiunque potrá esprimere il proprio <strong>Consenso o Dissenso</strong> partecipando a <strong>Sondaggi Interattivi</strong>' +
' e realizzare insieme i <strong>Cambiamenti</strong> necessari alla nostra Società.',
},
freetalent: {
title: 'Free Talent',
descr: 'Condividi i tuoi <strong>Talenti</strong> e <strong>Abilità</strong>, ' +
'al posto del denaro guadagnagnerai <strong>Tempo</strong>.<br> ' +
'<strong>"1 ora"</strong> diventa moneta di scambio, uguale per tutti.<br>' +
'Potrai utilizzare questi tuoi <strong>"Crediti Tempo"</strong> per soddisfare le tue necessità, cercando nelle <strong>Competenze Disponibili</strong>.<br>' +
'Nel Dare e Ricevere, si creeranno così legami di <strong>Amicizia, Solidarietà, Cooperazione e Divertimento</strong><br><br>' +
'Questo progetto vuole diffondere, ora in maniera informatizzata, questa realtà che gia esiste da tanti anni, e viene chiamata <strong>"Banca del Tempo"</strong>. ' +
'Le <strong>segreterie</strong> sparse in tutto il mondo, serviranno a dare maggiore <strong>affidabilità</strong> e <strong>fiducia</strong> negli scambi di talenti tra persone sconosciute. ' +
'Creeremo così una <strong>rete di fiducia</strong> nel vicinato, come giá viene praticato in numerosi <strong>Ecovillaggi</strong> e Comunità del mondo.',
},
freegas: {
title: 'Free G.A.S.',
descr: 'Ti piacerebbe utilizzare una App che ti permetta facilmente di acquistare Prodotti Locali direttamente dal <strong>Produttore</strong>?<br>' +
'Con i <strong>Gruppi di Acquisto Solidale</strong> si evitano intermediazioni inutili, ottenendo parecchi benefici tra cui:<br>' +
'<ul class="mylist" style="padding-left: 20px;"><li><strong>Qualitá Superiore</strong> del prodotto</li>' +
'<li>Le <strong>Recensioni</strong> dei consumatori favoriranno i Produttori con Sani Intenti</li>' +
'<li>Possiblità d\'interagire con il Produttore</li>' +
'<li>Apertura alle Relazioni tra persone, condividendo <strong>Ricette</strong> e <strong>Consigli</strong> preziosi</li>' +
'<li><strong>Risparmio</strong> di soldi (prezzi all\'Ingrosso)</li>' +
'<li>Valorizzare il <strong>Territorio</strong> e l\'Economia <strong>Locale</strong></li>' +
'<li>Condizioni <strong>Eque</strong> per i Lavoratori</li>' +
'<li>Ridotto <strong>Impatto Ambientale</strong></ul>',
},
freeliving: {
title: 'Free Co-Living',
descr: 'Unire più realtà, condividendo l\'esperienza di abitare insieme, per un periodo definito:<br>' +
'1) C\'è chi <strong>Vive solo</strong> ed ha una casa.<br>' +
'2) Chi ha bisogno di un <strong>alloggio</strong> temporaneo.<br><br>' +
'Oggi sempre più persone <strong>abitano da sole</strong> e vorrebbero continuare a vivere nella propria abitazione.<br>' +
'Altre persone invece hanno bisogno di una <strong>stanza</strong>, per scelta o per necessita, ed in cambio sono disponibili a ' +
'<strong>contribuire alle spese</strong> per le utenze domestiche o magari <strong>aiutare</strong> la persona a <strong>fare la spesa</strong>, cucinare, <strong>pulire casa</strong> oppure offrendogli semplicemente <strong>compagnia</strong>.<br><br>' +
'Tramite questo strumento, le persone potranno trovarsi, mettersi in contatto e decidere in che forma <strong>co-abitare</strong> e per quanto tempo. Le <strong>recensioni</strong> rilasciate ed il <strong>dettaglio</strong> dei profili utenti, ' +
'aiuterà nella scelta della persona più in <strong>sintonia</strong>.'
},
freecollabora: {
title: 'Chi può Collaborare?',
descr: 'Tutti coloro che sono in linea con <strong>Princìpi Etici</strong> e ricerca del <strong>Benessere Globale del Pianeta</strong><br>' +
'Pertanto sono i benvenuti:' +
'<ul class="mylist" style="padding-left: 20px;">' +
'<li><strong>Associazioni no-profit, Ecovillaggi, Comunità</strong></li>' +
'<li>Gruppi che intendono promuovere <strong>Progetti Sociali Innovativi</strong> per una <strong>Decrescita Felice</strong></li>' +
'<li>Chi gestisce un <strong>Gruppo di Acquisto Solidale (G.A.S.)</strong></li>' +
'<li>Chi gestisce una <strong>Banca del Tempo</strong></li>' +
'<li><strong>Chiunque voglia partecipare</strong>, nella forma che ritiene più opportuna.</li>' +
'</ul>',
},
freesostieni: {
title: 'Come Sostenere il progetto?',
descr: '<ul class="mylist" style="padding-left: 20px;">' +
'<li><strong>Condividendolo</strong> a tutti coloro che vogliono far parte insieme della crescita e sviluppo di una Nuova Era</li>' +
'<li>Rispondendo ai <strong>Sondaggi Popolari</strong> e lasciando <strong>Feedback</strong></li>' +
'<li>Tramite una <strong>donazione</strong> (<strong>anche 1€</strong> ) per le spese.<br>' +
'</ul>',
},
multiplatform: {
title: 'Multi-piattaforma',
descr: 'E\' compatibile con Google Chrome, Firefox, Safari, iOS, Android e PC. L\'Applicazione s\'installa facilmente, senza passare dallo store. ' +
'basta condividere il nome del sito <strong>www.freeplanet.app</strong>.<br>' +
'Dopo la registrazione chiederà di aggiungerlo alla lista delle applicazioni e sullo sfondo',
},
free: {
title: 'Gratuita, Open Source e Niente Pubblicità',
descr: 'Vedo un <strong>futuro</strong> dove non si utilizzerà più denaro. Dove le persone si <strong>aiuteranno</strong> a vicenda e non avranno bisogno di "possedere" cose, ma le <strong>condivideranno</strong> con gli altri.<br>' +
'Questa App <strong>non è in vendita</strong>, non ha scopi commerciali, <strong>non ha prezzo</strong> ed appartiene al <strong>Popolo del Nuovo Mondo</strong>. A me il compito di gestirla e proteggerla. ' +
'Verranno accettate solo donazioni Libere di privati ed Associazioni no-profit, in linea con i Principi, che serviranno per coprire le spese.<br>' +
'<strong>Grazie a Tutti per il sostegno</strong>. '
},
contacts: 'Contatti'
},
pages: {
home: 'Principale',
SignUp: 'Registrazione',
SignIn: 'Login',
vreg: 'Verifica Reg',
Test: 'Test',
Category: 'Categorie',
Todo: 'Todo',
personal: 'Personale',
work: 'Lavoro',
shopping: 'Spesa',
Admin: 'Admin',
Test1: 'Test1',
Test2: 'Test2',
},
components: {
authentication: {
login: {
facebook: 'Facebook'
},
email_verification: {
title: 'Inizia la tua registrazione',
introduce_email: 'inserisci la tua email',
email: 'Email',
invalid_email: 'La tua email è invalida',
verify_email: 'Verifica la tua email',
go_login: 'Torna al Login',
incorrect_input: 'Inserimento incorretto.',
link_sent: 'Per confermare la Registrazione, leggi la tua casella di posta e Clicca su "Verifica Email".\nSe non la trovi, cerca nella cartella Spam.'
}
}
},
fetch: {
errore_generico: 'Errore Generico',
errore_server: 'Impossibile accedere al Server. Riprovare Grazie',
error_doppiologin: 'Rieseguire il Login. Accesso aperto da un altro dispositivo.',
},
user: {
notregistered: 'Devi registrarti al servizio prima di porter memorizzare i dati',
loggati: 'Utente non loggato'
},
reg: {
incorso: 'Registrazione in corso...',
richiesto: 'Campo Richiesto',
email: 'Email',
username: 'Nome Utente',
username_login: 'Nome Utente o email',
password: 'Password',
repeatPassword: 'Ripeti password',
terms: "Accetto i termini e le condizioni",
submit: "Registrati",
title_verif_reg: "Verifica Registrazione",
verificato: "Verificato",
non_verificato: "Non Verificato",
forgetpassword: "Password dimenticata?",
err: {
required: 'è richiesto',
email: 'inserire una email valida',
errore_generico: 'Si prega di compilare correttamente i campi',
atleast: 'dev\'essere lungo almeno di',
complexity: 'deve contenere almeno 1 minuscola, 1 maiuscola e 1 cifra',
notmore: 'non dev\'essere lungo più di',
char: 'caratteri',
terms: 'Devi accettare le condizioni, per continuare.',
duplicate_email: 'l\'Email è già stata registrata',
duplicate_username: 'L\'Username è stato già utilizzato',
sameaspassword: 'Le password devono essere identiche',
},
tips: {
email: 'inserisci la tua email',
username: 'username lunga almeno 6 caratteri',
password: 'deve contenere 1 minuscola, 1 maiuscola e 1 cifra',
repeatpassword: 'ripetere la password',
}
},
login: {
incorso: 'Login in corso',
enter: 'Login',
errato: "Username o password errata. Riprovare",
completato: 'Login effettuato!',
},
reset: {
title_reset_pwd: "Reimposta la tua Password",
send_reset_pwd: 'Invia Reimposta la password',
incorso: 'Richiesta Nuova Email...',
email_sent: 'Email inviata',
check_email: 'Controlla la tua email, ti arriverà un messaggio con un link per reimpostare la tua password. Questo link, per sicurezza, scadrà dopo 4 ore.',
title_update_pwd: 'Aggiorna la tua password',
update_password: 'Aggiorna Password',
},
logout: {
uscito: 'Sei Uscito',
},
errors: {
graphql: {
undefined: 'non definito'
}
},
todo: {
titleprioritymenu: 'Priorità:',
inserttop: 'Inserisci il Task in cima',
insertbottom: 'Inserisci il Task in basso',
edit: 'Descrizione Task:',
completed: 'Ultimi Completati',
usernotdefined: 'Attenzione, occorre essere Loggati per poter aggiungere un Todo'
},
notification: {
status: 'Stato',
ask: 'Attiva le Notifiche',
waitingconfirm: 'Conferma la richiesta di Notifica',
confirmed: 'Notifiche Attivate!',
denied: 'Notifiche Disabilitate! Attenzione così non vedrai arrivarti i messaggi. Riabilitali per vederli.',
titlegranted: 'Permesso Notifiche Abilitato!',
statusnot: 'Stato Notifiche',
titledenied: 'Permesso Notifiche Disabilitato!',
title_subscribed: 'Sottoscrizione a FreePlanet.app!',
subscribed: 'Ora potrai ricevere i messaggi e le notifiche.',
newVersionAvailable: 'Aggiorna'
},
connection: 'Connessione',
},
'es': {
dialog: {
ok: 'Vale',
yes: 'Sí',
no: 'No',
delete: 'Borrar',
cancel: 'Cancelar',
msg: {
titledeleteTask: 'Borrar Tarea',
deleteTask: 'Quieres borrar {mytodo}?'
}
},
comp: {
Conta: "Conta",
},
msg: {
hello: 'Buenos Días',
myAppName: 'FreePlanet',
underconstruction: 'App en construcción...',
myDescriz: '',
sottoTitoloApp: 'El primer Verdadero Social',
sottoTitoloApp2: 'Libre, justo y Solidario',
sottoTitoloApp3: 'Donde vive Conciencia y Ayuda comunitaria',
sottoTitoloApp4: 'Gratis y sin publicidad',
},
homepage: {
descrapp_title1: 'Unidos para evolucionar y experimentar',
descrapp_pag1: 'Redescubra cómo el valor de <strong>Compartir</strong> y <strong>Cooperación</strong> puede ayudarnos a encontrar el profundo ' +
'sentido de la <strong>Vida</strong>, perdido en esta sociedad consumista, y mostrando esos <strong>Principios Naturales Saludables</strong> y la <strong>Hermandad Humana</strong>' +
'que toda la población antigua conocía bien.',
descrapp_pag2: 'Ha llegado el momento de utilizar las nuevas herramientas <strong>tecnológicas</strong> en nuestro <strong>favor</strong>, para <strong>liberarnos</strong> ' +
'tan lentamente desde la <strong>esclavitud</strong> de <strong>"Trabaja para generar dinero"</strong> y transformando nuestra <strong>Capacidad</strong> en' +
'<strong>Recursos humanos</strong> para poder apoyar y vivir en <strong>Armonia</strong> con otros.',
freesocial: {
title: 'Free Social',
descr: 'Una comunidad organizada por <strong>Categorías</strong>, donde puedes unirte a <strong>Grupos temáticos</strong>, ' +
'Compartir <strong>experiencias</strong> y combinar habilidades para organizar y apoyar <strong>proyectos innovadores</strong> para la gente.<br><br>' +
'Los desarrollos <strong>éticos</strong> como <strong>:<br>Auto-producción</strong>, <strong>Sostenibilidad</strong>, ' +
'la Buena <strong>Salud natural</strong> y <strong>Respeto por el Medio Ambiente</strong> y para todos los <strong>Seres vivos</strong> de este' +
'<strong>Planeta</strong>. Cualquiera puede expresar su <strong>consentimiento o disidencia</strong> participando en <strong>Encuestas Interactivas</strong> ' +
'y llevar a cabo juntos los <strong>Cambios</strong> necesarios para nuestra sociedad.',
},
freetalent: {
title: 'Free Talent',
descr: 'Comparte tus <strong>Talentos</strong> y <strong>Habilidades</strong>, ' +
'en lugar de dinero, ganarás <strong>Tiempo</strong>. <br>' +
'<strong>"1 hora"</strong> se convierte en una moneda de intercambio, igual para todos. <br>' +
'Puedes usar estos <strong>"Créditos de tiempo"</strong> para satisfacer tus necesidades, buscando en <strong>Habilidades disponibles</strong>. <br> ' +
'En Dar y Recibir, crearemos así vínculos de <strong>Amistad, Solidaridad, Cooperación y Diversión</strong>. <br> <br>' +
'Este proyecto apunta a difundir esta realidad, que ya existe desde hace muchos años y se llama <strong>"Banco de tiempo"</strong>. ' +
'Las <strong>secretarías</strong> dispersas por todo el mundo, servirán para dar mayor <strong>fiabilidad</strong> y <strong>confianza</strong> en el intercambio de talentos entre personas desconocidas. ' +
'Así crearemos una <strong>red de confianza</strong> en el vecindario, como ya se practica en numerosos <strong>Ecoaldeas</strong> y en la Comunidades del mundo.',
},
freegas: {
title: 'Free G.A.S. (G.C.S.)',
descr: '¿Le gustaría usar una aplicación que le permita comprar productos locales directamente desde el <strong>Productor</strong>? <br> ' +
'Con <strong>Grupos de Compra Solidarios</strong> evitamos intermediarios innecesarios, obteniendo muchos beneficios, incluyendo: <br>' +
'<ul class = "mylist" style = "padding-left: 20px;"> <li> <strong>Superior Quality</strong> del producto </li>' +
'<li> Opiniones <strong>de consumidores</strong> favorecerá a los productores con intenciones saludables </li>' +
'<li> Posibilidad de interactuar con el Productor </li>' +
'<li> Abierto a relaciones entre personas, compartiendo <strong>Recetas</strong> y <strong>Consejos</strong> preciosos </li>' +
'<li> <strong>Ahorros</strong> de dinero (precios al por mayor) </li>' +
'<li> Mejorando el <strong>Territorio</strong> y la Economía <strong>Local</strong> </li>' +
'<li> Condiciones <strong>Justa</strong> para Trabajadores </li>' +
'<li> Reducido <strong>Impacto Ambiental</strong> </ul>',
},
freeliving: {
title: 'Free Co-Living',
descr: 'Para unir más realidad, compartiendo la experiencia de vivir juntos, por un período definido: <br> '+
'1) Hay quien <strong>vive solo</strong> y tiene un hogar. <br>' +
'2) Quién necesita un alojamiento <strong>temporal</strong>. <br><br>' +
'Hoy en día, más y más personas <strong>viven solas</strong> y les gustaría seguir viviendo en sus propios hogares. <br>' +
'Otras personas necesitan una <strong>Habitación</strong>, por elección o por necesidad, y a cambio están disponibles en' +
'<strong>contribuir a los gastos</strong> para los billetes de casa o tal vez <strong>ayuda</strong> a la persona mayor para <strong>ir de compras</strong>, cocinar, <strong>limpiar casa</strong> o simplemente ofreciéndole <strong>compañía</strong>. <br><br> ' +
'A través de esta herramienta, las personas pueden ponerse en contacto y decidir en qué forma <strong>co-habitar</strong>. Los <strong>comentarios</strong> publicados y el <strong>detalle</strong> de los perfiles de usuario, ' +
'ayudará a elegir a la persona más en <strong>armonía</strong>.'
},
freecollabora: {
title: '¿Quién puede colaborar?',
descr: 'Todos aquellos que están en línea con <strong>Principios éticos</strong> y la investigación de <strong>Bienestar Global del Planeta</strong> <br> ' +
'Por eso son bienvenidos:' +
'<ul class = "mylist" style = "padding-left: 20px;">' +
'<li> <strong>Asociaciones sin ánimo de lucro, Ecoaldeas, Comunidades</strong> </li>' +
'<li> Grupos que desean promover <strong>Proyectos sociales innovadores</strong> para <strong>Feliz Decrecimiento</strong> </li>' +
'<li> Quién administra un <strong>Grupo de Compra Solidario (G.C.S.)</strong> </li>' +
'<li> Quién administra un <strong>Banco de Tiempo</strong> </li>' +
'<li> <strong>Cualquier persona que quiera participar</strong>, en la forma que considere más apropiada. </li>' +
'</ul>',
},
freesostieni: {
title: '¿Cómo apoyar el proyecto?',
descr: '<ul class="mylist" style="padding-left: 20px;">' +
'<li> <strong>Compartiéndolo</strong> a todos aquellos que quieran unirse en el crecimiento y desarrollo de una Nueva Era </li> ' +
'<li> Respondiendo a <strong>Encuestas populares</strong> y dejando <strong>Comentarios</strong> </li>' +
'<li> A través de una <strong>donación</strong> (<strong>incluso € 1</strong>) para los gastos. <br>' +
'</ul>',
},
multiplatform: {
title: 'Multi-plataforma',
descr: 'Compatible con Google Chrome, Firefox, Safari, iOS, Android y PC. La aplicación se instala fácilmente, sin pasar por el store. ' +
'para compartirlo, necesita solo el nombre del sitio web: <strong>www.freeplanet.app</strong>.<br>' +
'Después del registro, le pedirá que lo agregue a la lista de aplicaciones y en la pantalla.',
},
free: {
title: 'Libre, Código Abierto y Sin Publicidad',
descr: 'Veo un <strong>futuro</strong> en el que ya no usarás dinero. Donde las personas <strong>se ayudarán unos a otros</strong> y no necesiten "poseer" cosas, pero <strong>compartirán</strong> con otros. <br> ' +
'Esta aplicación <strong>no está a la venta</strong>, no tiene un propósito comercial, <strong>no tiene precio</strong> y pertenece a <strong>la Gente del Nuevo Mundo</strong>. A mí la tarea de gestionarlo y protegerlo. ' +
'Solo se aceptarán donaciones de particulares y asociaciones sin änimo de lucro, en línea con los Principios, que se utilizarán para cubrir los gastos. <br>' +
'<strong>Gracias a todos por el apoyo</strong>. '
},
contacts: 'Contactos'
},
pages: {
home: 'Principal',
SignUp: 'Nueva Cuenta',
SignIn: 'Entrar',
vreg: 'Verifica Reg',
Test: 'Test',
Category: 'Categorías',
Todo: 'Tareas',
personal: 'Personal',
work: 'Trabajo',
shopping: 'Compras',
Admin: 'Administración',
Test1: 'Test1',
Test2: 'Test2',
},
components: {
authentication: {
login: {
facebook: 'Facebook'
},
email_verification: {
title: 'Crea una cuenta',
introduce_email: 'ingrese su dirección de correo electrónico',
email: 'Email',
invalid_email: 'Tu correo electrónico no es válido',
verify_email: 'Revisa tu email',
go_login: 'Vuelve al Login',
incorrect_input: 'Entrada correcta.',
link_sent: 'Para confirmar el registro, lea su buzón y haga clic en "Verificar correo electrónico".\n' + 'Si no lo encuentras, busca en la carpeta Spam.'
}
}
},
fetch: {
errore_generico: 'Error genérico',
errore_server: 'No se puede acceder al Servidor. Inténtalo de nuevo, Gracias',
error_doppiologin: 'Vuelva a iniciar sesión. Acceso abierto por otro dispositivo.',
},
user: {
notregistered: 'Debe registrarse en el servicio antes de poder almacenar los datos',
loggati: 'Usuario no ha iniciado sesión'
},
reg: {
incorso: 'Registro en curso...',
richiesto: 'Campo requerido',
email: 'Email',
username: 'Nombre usuario',
username_login: 'Nombre usuario o email',
password: 'contraseña',
repeatPassword: 'Repetir contraseña',
terms: "Acepto los términos y condiciones",
submit: "Registrarse",
title_verif_reg: "Verifica registro",
verificato: "Verificado",
non_verificato: "No Verificado",
forgetpassword: "¿Olvidaste tu contraseña?",
err: {
required: 'se requiere',
email: 'Debe ser una email válida.',
errore_generico: 'Por favor, rellene los campos correctamente',
atleast: 'debe ser al menos largo',
complexity: 'debe contener al menos 1 minúscula, 1 mayúscula y 1 dígito',
notmore: 'no tiene que ser más largo que',
char: 'caracteres',
terms: 'Debes aceptar las condiciones, para continuar..',
duplicate_email: 'La email ya ha sido registrada',
duplicate_username: 'El nombre de usuario ya ha sido utilizado',
sameaspassword: 'Las contraseñas deben ser idénticas',
}
},
login: {
incorso: 'Login en curso',
enter: 'Entra',
errato: "Nombre de usuario, correo o contraseña incorrectos. inténtelo de nuevo",
completato: 'Login realizado!',
},
reset: {
title_reset_pwd: "Restablece tu contraseña",
send_reset_pwd: 'Enviar restablecer contraseña',
incorso: 'Solicitar nueva Email...',
email_sent: 'Email enviada',
check_email: 'Revise su correo electrónico, recibirá un mensaje con un enlace para restablecer su contraseña. Este enlace, por razones de seguridad, expirará después de 4 horas.',
title_update_pwd: 'Actualiza tu contraseña',
update_password: 'Actualizar contraseña',
},
logout: {
uscito: 'Estás desconectado',
},
errors: {
graphql: {
undefined: 'no definido'
}
},
todo: {
titleprioritymenu: 'Prioridad:',
inserttop: 'Ingrese una nueva Tarea arriba',
insertbottom: 'Ingrese una nueva Tarea abajo',
edit: 'Descripción Tarea:',
completed: 'Ultimos Completados',
usernotdefined: 'Atención, debes iniciar sesión para agregar una Tarea'
},
notification: {
status: 'Estado',
ask: 'Activar notificaciones',
waitingconfirm: 'Confirmar la solicitud de notificación.',
confirmed: 'Notificaciones activadas!',
denied: 'Notificaciones deshabilitadas! Ten cuidado, así no verás llegar los mensajes. Rehabilítalos para verlos.',
titlegranted: 'Notificaciones permitidas habilitadas!',
statusnot: 'Estado Notificaciones',
titledenied: 'Notificaciones permitidas deshabilitadas!',
title_subscribed: 'Suscripción a FreePlanet.app!',
subscribed: 'Ahora puedes recibir mensajes y notificaciones.',
newVersionAvailable: 'Actualiza'
},
connection: 'Connection',
},
'enUs': {
dialog: {
ok: 'Ok',
yes: 'Yes',
no: 'No',
delete: 'Delete',
cancel: 'Cancel',
msg: {
titledeleteTask: 'Delete Task',
deleteTask: 'Delete Task {mytodo}?'
}
},
comp: {
Conta: "Count",
},
msg: {
hello: 'Hello!',
myAppName: 'FreePlanet',
underconstruction: 'App in construction...',
myDescriz: '',
sottoTitoloApp: 'The first Real Social',
sottoTitoloApp2: 'Free, Fair and Equitable',
sottoTitoloApp3: 'Where the conscience and community help live',
sottoTitoloApp4: 'Free and without advertising',
},
homepage: {
descrapp_title1: 'Together to Evolve and Experiment',
descrapp_pag1: 'Rediscover how the value of <strong>Sharing</strong> and <strong>Cooperation</strong>, can help us find the deep meaning of' +
'<strong>Life</strong>, lost in this consumer society, and showing those <strong>Healthy Natural Principles</strong> and Human <strong>Brotherhood</strong>' +
'that entire ancient populations knew well.',
descrapp_pag2: 'The time has come to use the new <strong>Technological</strong> tools in our <strong>favor</strong>, to <strong>Free ourselves</strong> ' +
'so slowly from the <strong>slavery</strong> of the <strong>"Work to generate Money"</strong> and transforming our <strong>Capacity</strong> into' +
'<strong>Human Resources</strong> to be able to support and live in <strong>Harmony</strong> with others.',
freesocial: {
title: 'Free Social',
descr: 'A Community organized by <strong>Categories</strong>, where you can join <strong>Thematic Groups</strong>, ' +
'Share <strong>Experiences</strong> and combine Skills to organize and support <strong>Innovative Projects</strong> for the People.<br><br>' +
'<strong>Ethical</strong> developments such as <strong>Auto-Production</strong>, <strong>Sustainability</strong>, ' +
'Good <strong>Natural Health</strong> and <strong>Respect for the Environment</strong> and for all <strong>Living Beings</strong> of this' +
'<strong>Planet</strong>. Anyone can express their <strong>Consent or Dissent</strong> by participating in <strong>Interactive Surveys</strong> ' +
'and carry out together the <strong>Changes</strong> needed for our society.',
},
freetalent: {
title: 'Free Talent',
descr: 'Share your <strong>Talents</strong> and <strong>Skills</strong>, ' +
'instead of money, you\'ll earn <strong>Time</strong>. <br>' +
'<strong>"1 hour"</strong> becomes a currency of exchange, equal for all. <br>' +
'You can use these <strong>"Time Credits"</strong> to meet your needs, looking in <strong>Available Skills</strong>. <br>' +
'In Giving and Receiving, we will thus create bonds of <strong>Friendship, Solidarity, Cooperation and Enjoyment</strong> <br> <br>' +
'This project aims to spread this reality, which already exists for many years and is called <strong>"Time Bank"</strong>. ' +
'The <strong>secretariats</strong> in all over the world, will serve an extra to give greater <strong>reliability</strong> and <strong>trust</strong> in the exchange of talents between unknown people. ' +
'We will thus create a <strong>trust network</strong> in the neighborhood, as is already practiced in numerous <strong>Ecovillages</strong> and Community of the world. ',
},
freegas: {
title: 'Free G.A.S.',
descr: 'Would you like to use an App that allows you to easily Buy Local Products directly from <strong>Manufacturer</strong>? <br> ' +
'With <strong>Solidarity Purchase Groups</strong> (in Italian: "Gruppo di Aacquisto Solidale") we avoid unnecessary intermediaries, obtaining many benefits including: <br>' +
'<ul class="mylist" style="padding-left: 20px;"> <li> <strong>Superior Quality</strong> of the product </li>' +
'<li> Consumer <strong>Reviews</strong> will favor Producers with Healthy Intents </li>' +
'<li> Possibility to interact with the Producer </li>' +
'<li> Open to Relations between people, sharing <strong>Recipes</strong> and precious <strong>Tips</strong> </li>' +
'<li> <strong>Savings</strong> money (wholesale prices) </li>' +
'<li> Enhancing the <strong>Territory</strong> and the <strong>Local Economy</strong> </li>' +
'<li> <strong>Fair Conditions</strong> for Workers </li>' +
'<li> Reduced <strong>Environmental Impact</strong> </ul>'
},
freeliving: {
title: 'Free Co-Living',
descr: 'Join more reality, sharing the experience of living together, for a defined period: <br> ' +
'1) Someone <strong>Lives alone</strong> and has a house. <br>' +
'2) Who needs a temporary <strong> accommodation </strong>. <br><br>' +
'Today more and more people <strong> live alone </strong> and would like to continue living in their own house. <br>' +
'Other people instead need a <strong>room</strong>, by choice or by necessity, and in return they are available to' +
'<strong>contribute to expenses</strong> for households or maybe <strong>help</strong> to <strong>go shopping</strong>, cooking, <strong>cleaning house</strong> or simply offering him <strong>companionship</strong>. <br> ' +
'Through this tool, people can get in touch and decide in which way <strong>co-living</strong>. The <strong>reviews</strong> released and the <strong>detail</strong> of user profiles, ' +
'will help in <strong>choosing</strong> the person more in <strong>tune</strong>.'
},
freecollabora: {
title: 'Who can collaborate?',
descr: 'All those who are in line with <strong>Ethical Principles</strong> and research of <strong>Global Wellness of the Planet</strong> <br> ' +
'Therefore they are welcome:' +
'<ul class = "mylist" style = "padding-left: 20px;">' +
'<li> <strong>Non-profit associations, Ecovillages, Communities</strong> </li>' +
'<li> Groups that want to promote <strong>Innovative Social Projects</strong> for <strong>Happy Degrowth</strong> </li>' +
'<li> Who manages a <strong>Solidarity Purchase Group</strong> </li>' +
'<li> Who manages a <strong>Time Bank</strong> </li>' +
'<li> <strong>Anyone who wants to participate</strong>, in the form it considers most appropriate. </li>' +
'</ul>',
},
freesostieni: {
title: 'How to support the project?',
descr: '<ul class="mylist" style="padding-left: 20px;">' +
'<li> <strong>Sharing it</strong> to all those who want to join together in the growth and development of a New Era </li> ' +
'<li> Answering to <strong>Popular Polls</strong> and leaving <strong>Feedback</strong> </li>' +
'<li> Through a <strong>donation</strong> (<strong>even $ 1</strong>) for expenses. <br>' +
'</ul>',
},
multiplatform: {
title: 'Multi-platform',
descr: 'It is compatible with Google Chrome, Firefox, Safari, iOS, Android and PC. The Application is easily installed, without going through the store. ' +
'just share the name of this site <strong>www.freeplanet.app</strong>.<br>' +
'After registration it will ask to be added to the application list and in the screen',
},
free: {
title: 'Free, Open Source and No Advertising',
descr: 'I see a <strong>future</strong> where you will no longer use money. Where people <strong>will help each other</strong> and won\'t need to "own" things, but <strong>will share</strong> with others. <br> ' +
'This App <strong>is not for sale</strong>, has no commercial purpose, <strong>is priceless</strong> and belongs to the <strong>New World People</strong>. To me the task of managing it and protecting it. ' +
'Only donations from private individuals and non-profit associations will be accepted, in line with the Principles, which will be used to cover the expenses. <br>' +
'<strong>Thanks all for the support</strong>. '
},
contacts: 'Contacts'
},
pages: {
home: 'Dashboard',
SignUp: 'SignUp',
SignIn: 'SignIn',
vreg: 'Verify Reg',
Test: 'Test',
Category: 'Category',
Todo: 'Todo',
personal: 'Personal',
work: 'Work',
shopping: 'Shopping',
Admin: 'Admin',
Test1: 'Test1',
Test2: 'Test2',
},
components: {
authentication: {
login: {
facebook: 'Facebook'
},
email_verification: {
title: 'Begin your registration',
introduce_email: 'Enter your email',
email: 'Email',
invalid_email: 'Your email is invalid',
verify_email: 'Verify your email',
go_login: 'Back to Login',
incorrect_input: 'Incorrect input.',
link_sent: 'To confirm the Registration, read your mailbox and click on "Verify email".\nIf you can not find it check your junk mail or spam.'
}
}
},
fetch: {
errore_generico: 'Generic Error',
errore_server: 'Unable to access to the Server. Retry. Thank you.',
error_doppiologin: 'Signup again. Another access was made with another device.',
},
user: {
notregistered: 'You need first to SignUp before storing data',
loggati: 'User not logged in'
},
reg: {
incorso: 'Registration please wait...',
richiesto: 'Field Required',
email: 'Email',
username_login: 'Username or email',
username: 'Username',
password: 'Password',
repeatPassword: 'Repeat password',
terms: "I agree with the terms and conditions",
submit: "Submit",
title_verif_reg: "Verify Registration",
verificato: "Verified",
non_verificato: "Not Verified",
forgetpassword: "Forget Password?",
err: {
required: 'is required',
email: 'must be a valid email',
errore_generico: 'Please review fields again',
atleast: 'must be at least',
complexity: 'must contains at least 1 lowercase letter, 1 uppercase letter, and 1 digit',
notmore: 'must not be more than',
char: 'characters long',
terms: 'You need to agree with the terms & conditions.',
duplicate_email: 'Email was already registered',
duplicate_username: 'Username is already taken',
sameaspassword: 'Passwords must be identical',
}
},
login: {
incorso: 'Login...',
enter: 'Login',
errato: "Username or password wrong. Please retry again",
completato: 'Login successfully!',
},
reset: {
title_reset_pwd: "Reset your Password",
send_reset_pwd: 'Send password request',
incorso: 'Request New Email...',
email_sent: 'Email sent',
check_email: 'Check your email for a message with a link to update your password. This link will expire in 4 hours for security reasons.',
title_update_pwd: 'Update your password',
update_password: 'Update Password',
},
logout: {
uscito: 'Logout successfully',
},
errors: {
graphql: {
undefined: 'undefined'
}
},
todo: {
titleprioritymenu: 'Priority:',
inserttop: 'Insert Task at the top',
insertbottom: 'Insert Task at the bottom',
edit: 'Task Description:',
completed: 'Lasts Completed',
usernotdefined: 'Attention, you need to be Signed In to add a new Task'
},
notification: {
status: 'Status',
ask: 'Enable Notification',
waitingconfirm: 'Confirm the Request Notification',
confirmed: 'Notifications Enabled!',
denied: 'Notifications Disabled! Attention, you will not see your messages incoming. Reenable it for see it',
titlegranted: 'Notification Permission Granted!',
statusnot: 'status Notification',
titledenied: 'Notification Permission Denied!',
title_subscribed: 'Subscribed to FreePlanet.app!',
subscribed: 'You can now receive Notification and Messages.',
newVersionAvailable: 'Upgrade'
},
connection: 'Conexión',
},
};
export default messages;

View File

@@ -0,0 +1,5 @@
[Dolphin]
PreviewsShown=true
Timestamp=2019,2,24,19,27,34
Version=4
ViewMode=1

Binary file not shown.

After

Width:  |  Height:  |  Size: 211 KiB

View File

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 225 KiB

BIN
src/statics/images/de.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 107 B

BIN
src/statics/images/es.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 90 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 200 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

BIN
src/statics/images/gb.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 597 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

BIN
src/statics/images/it.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 179 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 154 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 190 KiB

461
src/statics/js/fetch.js Normal file
View File

@@ -0,0 +1,461 @@
(function(self) {
'use strict';
if (self.fetch) {
return
}
var support = {
searchParams: 'URLSearchParams' in self,
iterable: 'Symbol' in self && 'iterator' in Symbol,
blob: 'FileReader' in self && 'Blob' in self && (function() {
try {
new Blob()
return true
} catch(e) {
return false
}
})(),
formData: 'FormData' in self,
arrayBuffer: 'ArrayBuffer' in self
}
if (support.arrayBuffer) {
var viewClasses = [
'[object Int8Array]',
'[object Uint8Array]',
'[object Uint8ClampedArray]',
'[object Int16Array]',
'[object Uint16Array]',
'[object Int32Array]',
'[object Uint32Array]',
'[object Float32Array]',
'[object Float64Array]'
]
var isDataView = function(obj) {
return obj && DataView.prototype.isPrototypeOf(obj)
}
var isArrayBufferView = ArrayBuffer.isView || function(obj) {
return obj && viewClasses.indexOf(Object.prototype.toString.call(obj)) > -1
}
}
function normalizeName(name) {
if (typeof name !== 'string') {
name = String(name)
}
if (/[^a-z0-9\-#$%&'*+.\^_`|~]/i.test(name)) {
throw new TypeError('Invalid character in header field name')
}
return name.toLowerCase()
}
function normalizeValue(value) {
if (typeof value !== 'string') {
value = String(value)
}
return value
}
// Build a destructive iterator for the value list
function iteratorFor(items) {
var iterator = {
next: function() {
var value = items.shift()
return {done: value === undefined, value: value}
}
}
if (support.iterable) {
iterator[Symbol.iterator] = function() {
return iterator
}
}
return iterator
}
function Headers(headers) {
this.map = {}
if (headers instanceof Headers) {
headers.forEach(function(value, name) {
this.append(name, value)
}, this)
} else if (Array.isArray(headers)) {
headers.forEach(function(header) {
this.append(header[0], header[1])
}, this)
} else if (headers) {
Object.getOwnPropertyNames(headers).forEach(function(name) {
this.append(name, headers[name])
}, this)
}
}
Headers.prototype.append = function(name, value) {
name = normalizeName(name)
value = normalizeValue(value)
var oldValue = this.map[name]
this.map[name] = oldValue ? oldValue+','+value : value
}
Headers.prototype['delete'] = function(name) {
delete this.map[normalizeName(name)]
}
Headers.prototype.get = function(name) {
name = normalizeName(name)
return this.has(name) ? this.map[name] : null
}
Headers.prototype.has = function(name) {
return this.map.hasOwnProperty(normalizeName(name))
}
Headers.prototype.set = function(name, value) {
this.map[normalizeName(name)] = normalizeValue(value)
}
Headers.prototype.forEach = function(callback, thisArg) {
for (var name in this.map) {
if (this.map.hasOwnProperty(name)) {
callback.call(thisArg, this.map[name], name, this)
}
}
}
Headers.prototype.keys = function() {
var items = []
this.forEach(function(value, name) { items.push(name) })
return iteratorFor(items)
}
Headers.prototype.values = function() {
var items = []
this.forEach(function(value) { items.push(value) })
return iteratorFor(items)
}
Headers.prototype.entries = function() {
var items = []
this.forEach(function(value, name) { items.push([name, value]) })
return iteratorFor(items)
}
if (support.iterable) {
Headers.prototype[Symbol.iterator] = Headers.prototype.entries
}
function consumed(body) {
if (body.bodyUsed) {
return Promise.reject(new TypeError('Already read'))
}
body.bodyUsed = true
}
function fileReaderReady(reader) {
return new Promise(function(resolve, reject) {
reader.onload = function() {
resolve(reader.result)
}
reader.onerror = function() {
reject(reader.error)
}
})
}
function readBlobAsArrayBuffer(blob) {
var reader = new FileReader()
var promise = fileReaderReady(reader)
reader.readAsArrayBuffer(blob)
return promise
}
function readBlobAsText(blob) {
var reader = new FileReader()
var promise = fileReaderReady(reader)
reader.readAsText(blob)
return promise
}
function readArrayBufferAsText(buf) {
var view = new Uint8Array(buf)
var chars = new Array(view.length)
for (var i = 0; i < view.length; i++) {
chars[i] = String.fromCharCode(view[i])
}
return chars.join('')
}
function bufferClone(buf) {
if (buf.slice) {
return buf.slice(0)
} else {
var view = new Uint8Array(buf.byteLength)
view.set(new Uint8Array(buf))
return view.buffer
}
}
function Body() {
this.bodyUsed = false
this._initBody = function(body) {
this._bodyInit = body
if (!body) {
this._bodyText = ''
} else if (typeof body === 'string') {
this._bodyText = body
} else if (support.blob && Blob.prototype.isPrototypeOf(body)) {
this._bodyBlob = body
} else if (support.formData && FormData.prototype.isPrototypeOf(body)) {
this._bodyFormData = body
} else if (support.searchParams && URLSearchParams.prototype.isPrototypeOf(body)) {
this._bodyText = body.toString()
} else if (support.arrayBuffer && support.blob && isDataView(body)) {
this._bodyArrayBuffer = bufferClone(body.buffer)
// IE 10-11 can't handle a DataView body.
this._bodyInit = new Blob([this._bodyArrayBuffer])
} else if (support.arrayBuffer && (ArrayBuffer.prototype.isPrototypeOf(body) || isArrayBufferView(body))) {
this._bodyArrayBuffer = bufferClone(body)
} else {
throw new Error('unsupported BodyInit type')
}
if (!this.headers.get('content-type')) {
if (typeof body === 'string') {
this.headers.set('content-type', 'text/plain;charset=UTF-8')
} else if (this._bodyBlob && this._bodyBlob.type) {
this.headers.set('content-type', this._bodyBlob.type)
} else if (support.searchParams && URLSearchParams.prototype.isPrototypeOf(body)) {
this.headers.set('content-type', 'application/x-www-form-urlencoded;charset=UTF-8')
}
}
}
if (support.blob) {
this.blob = function() {
var rejected = consumed(this)
if (rejected) {
return rejected
}
if (this._bodyBlob) {
return Promise.resolve(this._bodyBlob)
} else if (this._bodyArrayBuffer) {
return Promise.resolve(new Blob([this._bodyArrayBuffer]))
} else if (this._bodyFormData) {
throw new Error('could not read FormData body as blob')
} else {
return Promise.resolve(new Blob([this._bodyText]))
}
}
this.arrayBuffer = function() {
if (this._bodyArrayBuffer) {
return consumed(this) || Promise.resolve(this._bodyArrayBuffer)
} else {
return this.blob().then(readBlobAsArrayBuffer)
}
}
}
this.text = function() {
var rejected = consumed(this)
if (rejected) {
return rejected
}
if (this._bodyBlob) {
return readBlobAsText(this._bodyBlob)
} else if (this._bodyArrayBuffer) {
return Promise.resolve(readArrayBufferAsText(this._bodyArrayBuffer))
} else if (this._bodyFormData) {
throw new Error('could not read FormData body as text')
} else {
return Promise.resolve(this._bodyText)
}
}
if (support.formData) {
this.formData = function() {
return this.text().then(decode)
}
}
this.json = function() {
return this.text().then(JSON.parse)
}
return this
}
// HTTP methods whose capitalization should be normalized
var methods = ['DELETE', 'GET', 'HEAD', 'OPTIONS', 'POST', 'PUT']
function normalizeMethod(method) {
var upcased = method.toUpperCase()
return (methods.indexOf(upcased) > -1) ? upcased : method
}
function Request(input, options) {
options = options || {}
var body = options.body
if (input instanceof Request) {
if (input.bodyUsed) {
throw new TypeError('Already read')
}
this.url = input.url
this.credentials = input.credentials
if (!options.headers) {
this.headers = new Headers(input.headers)
}
this.method = input.method
this.mode = input.mode
if (!body && input._bodyInit != null) {
body = input._bodyInit
input.bodyUsed = true
}
} else {
this.url = String(input)
}
this.credentials = options.credentials || this.credentials || 'omit'
if (options.headers || !this.headers) {
this.headers = new Headers(options.headers)
}
this.method = normalizeMethod(options.method || this.method || 'GET')
this.mode = options.mode || this.mode || null
this.referrer = null
if ((this.method === 'GET' || this.method === 'HEAD') && body) {
throw new TypeError('Body not allowed for GET or HEAD requests')
}
this._initBody(body)
}
Request.prototype.clone = function() {
return new Request(this, { body: this._bodyInit })
}
function decode(body) {
var form = new FormData()
body.trim().split('&').forEach(function(bytes) {
if (bytes) {
var split = bytes.split('=')
var name = split.shift().replace(/\+/g, ' ')
var value = split.join('=').replace(/\+/g, ' ')
form.append(decodeURIComponent(name), decodeURIComponent(value))
}
})
return form
}
function parseHeaders(rawHeaders) {
var headers = new Headers()
rawHeaders.split(/\r?\n/).forEach(function(line) {
var parts = line.split(':')
var key = parts.shift().trim()
if (key) {
var value = parts.join(':').trim()
headers.append(key, value)
}
})
return headers
}
Body.call(Request.prototype)
function Response(bodyInit, options) {
if (!options) {
options = {}
}
this.type = 'default'
this.status = 'status' in options ? options.status : 200
this.ok = this.status >= 200 && this.status < 300
this.statusText = 'statusText' in options ? options.statusText : 'OK'
this.headers = new Headers(options.headers)
this.url = options.url || ''
this._initBody(bodyInit)
}
Body.call(Response.prototype)
Response.prototype.clone = function() {
return new Response(this._bodyInit, {
status: this.status,
statusText: this.statusText,
headers: new Headers(this.headers),
url: this.url
})
}
Response.error = function() {
var response = new Response(null, {status: 0, statusText: ''})
response.type = 'error'
return response
}
var redirectStatuses = [301, 302, 303, 307, 308]
Response.redirect = function(url, status) {
if (redirectStatuses.indexOf(status) === -1) {
throw new RangeError('Invalid status code')
}
return new Response(null, {status: status, headers: {location: url}})
}
self.Headers = Headers
self.Request = Request
self.Response = Response
self.fetch = function(input, init) {
return new Promise(function(resolve, reject) {
var request = new Request(input, init)
var xhr = new XMLHttpRequest()
xhr.onload = function() {
var options = {
status: xhr.status,
statusText: xhr.statusText,
headers: parseHeaders(xhr.getAllResponseHeaders() || '')
}
options.url = 'responseURL' in xhr ? xhr.responseURL : options.headers.get('X-Request-URL')
var body = 'response' in xhr ? xhr.response : xhr.responseText
resolve(new Response(body, options))
}
xhr.onerror = function() {
reject(new TypeError('Network request failed'))
}
xhr.ontimeout = function() {
reject(new TypeError('Network request failed'))
}
xhr.open(request.method, request.url, true)
if (request.credentials === 'include') {
xhr.withCredentials = true
}
if ('responseType' in xhr && support.blob) {
xhr.responseType = 'blob'
}
request.headers.forEach(function(value, name) {
xhr.setRequestHeader(name, value)
})
xhr.send(typeof request._bodyInit === 'undefined' ? null : request._bodyInit)
})
}
self.fetch.polyfill = true
})(typeof self !== 'undefined' ? self : this);

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