- aggiunto componenti per Home Template... ma ancora da provare

- sistemato catprods
- Sistemato menu
This commit is contained in:
Surya Paolo
2025-09-22 19:09:14 +02:00
parent 917cdaa754
commit c8589e794f
114 changed files with 3594207 additions and 316 deletions

4
.env
View File

@@ -1,6 +1,6 @@
VITE_APP_VERSION="1.2.69"
VITE_APP_VERSION="1.2.70"
VITE_LANG_DEFAULT="it"
VITE_PAO_APP_ID="KKPPAA5KJK435J3KSS9F9D8S9F8SD98F9SDF"
VITE_SERVICE_WORKER_FILE="sw-1.2.69.js"
VITE_SERVICE_WORKER_FILE="sw-1.2.70.js"
VITE_PROJECT_ID_MAIN="5cc0a13fe5c9d156728f400a"
VITE_VUE_ROUTER_MODE="history"

View File

@@ -1,12 +1,12 @@
VITE_APP_ID="10"
VITE_APP_ID="18"
VITE_APP_URL="https://localhost"
VITE_MONGODB_HOST="https://localhost:3000"
VITE_LOGO_REG='nuovomondo-logo-full.png'
VITE_LOGO_REG='gruppomacro-logo-full.png'
VITE_PUBLICKEY_PUSH='BDncvMiUZmjaCG2Kr1V9N0_33hOG-AuNSbHSvL24y2dzBiUjAxKm02emx5SeJvz2IGmtRf6YqCgopeQwCwUmZw8'
VITE_DEBUG="1"
VITE_VUE_APP_ISTEST=0
VITE_VUE_APP_INLOCALE=1
DIRECTORY_LOCAL="myprojplanet_vite"
DIRECTORY_LOCAL="newfreeplanet"
DIRECTORY_SERVER="freeplanet_serverside"
SERVERDIR_WEBSITE=""
SERVERPW_WEBSITE=""

View File

@@ -1,11 +1,13 @@
VITE_APP_ID="10"
VITE_APP_URL="https://nuovomondo.app"
VITE_MONGODB_HOST="https://api.nuovomondo.app"
VITE_LOGO_REG='nuovomondo-logo-full.png'
VITE_PUBLICKEY_PUSH="BNM-cEpTbPVc_ujXf3QOC8ggf7b-X44P44esfJUWqNOFq1XhWCoZJpOi71_cbXC5SnfO9HassQ6OouAYgtBA9Pw"
VITE_DEBUG="1"
VITE_VUE_APP_ISTEST=0
VITE_APP_ID="18"
VITE_APP_URL="https://gruppomacro.app"
VITE_MONGODB_HOST="https://api.gruppomacro.app"
VITE_LOGO_REG='gruppomacro-logo-full.png'
VITE_PUBLICKEY_PUSH="BJgo8XR_upbnbMLWgCAUELo6DK7dRXffYAnFOxbaMMz5favBgcQBKT-eISqouO-jRad4Sw8l5nd2wCF6KorGiTc"
VITE_DEBUG="0"
VITE_VUE_APP_ISTEST="0"
DIRECTORY_LOCAL="myprojplanet_vite"
DIRECTORY_SERVER="/var/www/nodejs_riso_server"
SERVERDIR_WEBSITE="/var/www/nuovomondo.app"
DIRECTORY_SERVER="/var/www/nodejs_piuchebuono_server"
SERVERDIR_WEBSITE="/var/www/gruppomacro.app"
SERVERPW_WEBSITE="pwdadmin@1AOK"
PORT_SPA="8089"
PORT_PWA="8099"

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -10,7 +10,7 @@
<meta name="description" content="<%= productDescription %>">
<meta name="format-detection" content="telephone=no">
<meta name="msapplication-tap-highlight" content="no">
<meta name="version" content="1.2.69">
<meta name="version" content="1.2.70">
<meta name="viewport"
content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width<% if (ctx.mode.cordova || ctx.mode.capacitor) { %>, viewport-fit=cover<% } %>">

View File

@@ -1,28 +1,28 @@
{
"name": "nuovomondo",
"version": "1.2.69",
"description": "Nuovo Mondo",
"productName": "Nuovo Mondo",
"name": "gruppomacro",
"version": "1.2.70",
"productName": "Gruppo Macro",
"description": "Il Gruppo Editoriale Macro, attivo dal 1987, è leader europeo nella pubblicazione di libri per il benessere e la consapevolezza. Con oltre 1.500 titoli, promuove una visione armonica del mondo, offrendo opere di autori internazionali e italiani come Gregg Braden, Bruce Lipton, Joe Dispenza, Louise Hay, Eckhart Tolle e molti altri. Scopri un'editoria che abbraccia il corpo, la mente, lo spirito e l'ecologia.",
"author": "Surya",
"private": true,
"keywords": [],
"license": "MIT",
"type": "module",
"scripts": {
"dev": "APP_VERSION='1.2.69' PORT=8083 quasar dev",
"dev": "PORT=8089 APP_VERSION='1.2.70' quasar dev",
"dev_noCheck": "SKIP_TSC=true quasar dev",
"build": "quasar build",
"buildpwa": "NODE_ENV=production APP_VERSION='1.2.69' quasar build -m pwa",
"buildpwatest": "NODE_ENV=production APP_VERSION='1.2.69' quasar build -m pwa",
"buildpwa": "NODE_ENV=production APP_VERSION='1.2.70' quasar build -m pwa",
"buildpwatest": "NODE_ENV=production APP_VERSION='1.2.70' quasar build -m pwa",
"type-check": "vue-tsc --noEmit",
"type-check:watch": "vue-tsc --noEmit --watch",
"buildspa": "quasar build -m spa",
"buildspa": "APP_VERSION='1.2.70' quasar build -m spa",
"lint": "eslint -c ./eslint.config.js \"./src*/**/*.{ts,js,cjs,mjs,vue}\"",
"lintfile": "eslint --ext .js,.ts,.vue --ignore-path .gitignore ./ > file.out.txt",
"lintfileNoJS": "eslint --ext .ts,.vue --ignore-path .gitignore ./ > file.out.txt",
"fix": "eslint -c ./eslint.config.js \"./src*/**/*.{ts,js,cjs,mjs,vue}\" --ignore-pattern .gitignore ./ --fix > file.out.txt",
"pwa": "NODE_ENV=development PORT=8094 APP_VERSION='1.2.69' quasar dev -m pwa",
"spa": "NODE_ENV=development PORT=8083 APP_VERSION='1.2.69' quasar dev",
"pwa": "NODE_ENV=development PORT=8099 APP_VERSION='1.2.70' quasar dev -m pwa",
"spa": "NODE_ENV=development PORT=8089 APP_VERSION='1.2.70' quasar dev",
"debug": "quasar dev --mode debug",
"test": "echo \"No test specified\" && exit 0",
"generate-sw": "workbox generateSW workbox-config.js",
@@ -61,7 +61,6 @@
"leaflet.markercluster": "^1.5.3",
"localforage": "^1.10.0",
"lodash": "^4.17.21",
"mongoose-paginate-v2": "^1.9.1",
"normalize.css": "^8.0.1",
"nprogress": "^0.2.0",
"pinia": "^3.0.3",

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

BIN
public/images/cibo_sano.jpg Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 231 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 158 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 81 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 110 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

BIN
public/images/novita.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 148 KiB

BIN
public/images/ombra.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

2
public/js/workbox-sw-6-1.js Executable file
View File

@@ -0,0 +1,2 @@
!function(){'use strict';try{self['workbox:sw:6.1.0']&&_()}catch(t){}const t={backgroundSync:'background-sync',broadcastUpdate:'broadcast-update',cacheableResponse:'cacheable-response',core:'core',expiration:'expiration',googleAnalytics:'offline-ga',navigationPreload:'navigation-preload',precaching:'precaching',rangeRequests:'range-requests',routing:'routing',strategies:'strategies',streams:'streams',recipes:'recipes'};self.workbox=new class{constructor(){return this.v={},this.Pt={debug:'localhost'===self.location.hostname,modulePathPrefix:null,modulePathCb:null},this.$t=this.Pt.debug?'dev':'prod',this.jt=!1,new Proxy(this,{get(e,s){if(e[s])return e[s];const o=t[s];return o&&e.loadModule('workbox-'+o),e[s]}})}setConfig(t={}){if(this.jt)throw new Error('Config must be set before accessing workbox.* modules');Object.assign(this.Pt,t),this.$t=this.Pt.debug?'dev':'prod'}loadModule(t){const e=this.St(t);try{importScripts(e),this.jt=!0}catch(s){throw console.error(`Unable to import module '${t}' from '${e}'.`),s}}St(t){if(this.Pt.modulePathCb)return this.Pt.modulePathCb(t,this.Pt.debug);let e=['https://storage.googleapis.com/workbox-cdn/releases/6.1.0'];const s=`${t}.${this.$t}.js`,o=this.Pt.modulePathPrefix;return o&&(e=o.split('/'),''===e[e.length-1]&&e.splice(e.length-1,1)),e.push(s),e.join('/')}}}();
//# sourceMappingURL=workbox-sw.js.map

2
public/js/workbox-sw.js Normal file
View File

@@ -0,0 +1,2 @@
!function(){"use strict";try{self["workbox:sw:5.1.4"]&&_()}catch(t){}const t={backgroundSync:"background-sync",broadcastUpdate:"broadcast-update",cacheableResponse:"cacheable-response",core:"core",expiration:"expiration",googleAnalytics:"offline-ga",navigationPreload:"navigation-preload",precaching:"precaching",rangeRequests:"range-requests",routing:"routing",strategies:"strategies",streams:"streams"};self.workbox=new class{constructor(){return this.v={},this.t={debug:"localhost"===self.location.hostname,modulePathPrefix:null,modulePathCb:null},this.s=this.t.debug?"dev":"prod",this.o=!1,new Proxy(this,{get(e,s){if(e[s])return e[s];const o=t[s];return o&&e.loadModule("workbox-"+o),e[s]}})}setConfig(t={}){if(this.o)throw new Error("Config must be set before accessing workbox.* modules");Object.assign(this.t,t),this.s=this.t.debug?"dev":"prod"}loadModule(t){const e=this.i(t);try{importScripts(e),this.o=!0}catch(s){throw console.error(`Unable to import module '${t}' from '${e}'.`),s}}i(t){if(this.t.modulePathCb)return this.t.modulePathCb(t,this.t.debug);let e=["https://storage.googleapis.com/workbox-cdn/releases/5.1.4"];const s=`${t}.${this.s}.js`,o=this.t.modulePathPrefix;return o&&(e=o.split("/"),""===e[e.length-1]&&e.splice(e.length-1,1)),e.push(s),e.join("/")}}}();
//# sourceMappingURL=workbox-sw.js.map

View File

@@ -1,2 +1,2 @@
!function(){"use strict";try{self["workbox:sw:7.3.0"]&&_()}catch(t){}const t={backgroundSync:"background-sync",broadcastUpdate:"broadcast-update",cacheableResponse:"cacheable-response",core:"core",expiration:"expiration",googleAnalytics:"offline-ga",navigationPreload:"navigation-preload",precaching:"precaching",rangeRequests:"range-requests",routing:"routing",strategies:"strategies",streams:"streams",recipes:"recipes"};self.workbox=new class{constructor(){return this.v={},this.Pt={debug:"localhost"===self.location.hostname,modulePathPrefix:null,modulePathCb:null},this.$t=this.Pt.debug?"dev":"prod",this.jt=!1,new Proxy(this,{get(e,s){if(e[s])return e[s];const o=t[s];return o&&e.loadModule(`workbox-${o}`),e[s]}})}setConfig(t={}){if(this.jt)throw new Error("Config must be set before accessing workbox.* modules");Object.assign(this.Pt,t),this.$t=this.Pt.debug?"dev":"prod"}loadModule(t){const e=this.St(t);try{importScripts(e),this.jt=!0}catch(s){throw console.error(`Unable to import module '${t}' from '${e}'.`),s}}St(t){if(this.Pt.modulePathCb)return this.Pt.modulePathCb(t,this.Pt.debug);let e=["https://storage.googleapis.com/workbox-cdn/releases/7.3.0"];const s=`${t}.${this.$t}.js`,o=this.Pt.modulePathPrefix;return o&&(e=o.split("/"),""===e[e.length-1]&&e.splice(e.length-1,1)),e.push(s),e.join("/")}}}();
!function(){"use strict";try{self["workbox:sw:5.1.4"]&&_()}catch(t){}const t={backgroundSync:"background-sync",broadcastUpdate:"broadcast-update",cacheableResponse:"cacheable-response",core:"core",expiration:"expiration",googleAnalytics:"offline-ga",navigationPreload:"navigation-preload",precaching:"precaching",rangeRequests:"range-requests",routing:"routing",strategies:"strategies",streams:"streams"};self.workbox=new class{constructor(){return this.v={},this.t={debug:"localhost"===self.location.hostname,modulePathPrefix:null,modulePathCb:null},this.s=this.t.debug?"dev":"prod",this.o=!1,new Proxy(this,{get(e,s){if(e[s])return e[s];const o=t[s];return o&&e.loadModule("workbox-"+o),e[s]}})}setConfig(t={}){if(this.o)throw new Error("Config must be set before accessing workbox.* modules");Object.assign(this.t,t),this.s=this.t.debug?"dev":"prod"}loadModule(t){const e=this.i(t);try{importScripts(e),this.o=!0}catch(s){throw console.error(`Unable to import module '${t}' from '${e}'.`),s}}i(t){if(this.t.modulePathCb)return this.t.modulePathCb(t,this.t.debug);let e=["https://storage.googleapis.com/workbox-cdn/releases/5.1.4"];const s=`${t}.${this.s}.js`,o=this.t.modulePathPrefix;return o&&(e=o.split("/"),""===e[e.length-1]&&e.splice(e.length-1,1)),e.push(s),e.join("/")}}}();
//# sourceMappingURL=workbox-sw.js.map

View File

@@ -1,6 +1,6 @@
{
"name": "cnm",
"version": "1.2.69",
"version": "1.2.70",
"description": "Comunita Nuovo Mondo",
"productName": "ComunitaNuovoMondo",
"author": "Surya",
@@ -9,7 +9,7 @@
"license": "MIT",
"type": "module",
"scripts": {
"dev": "PORT=8083 APP_VERSION='1.2.69' quasar dev",
"dev": "PORT=8083 APP_VERSION='1.2.70' quasar dev",
"dev_noCheck": "SKIP_TSC=true quasar dev",
"build": "quasar build",
"buildpwa": "NODE_ENV=production quasar build -m pwa",
@@ -21,8 +21,8 @@
"lintfile": "eslint --ext .js,.ts,.vue --ignore-path .gitignore ./ > file.out.txt",
"lintfileNoJS": "eslint --ext .ts,.vue --ignore-path .gitignore ./ > file.out.txt",
"fix": "eslint -c ./eslint.config.js \"./src*/**/*.{ts,js,cjs,mjs,vue}\" --ignore-pattern .gitignore ./ --fix > file.out.txt",
"pwa": "NODE_ENV=development PORT=8093 APP_VERSION='1.2.69' quasar dev -m pwa",
"spa": "NODE_ENV=development PORT=8083 APP_VERSION='1.2.69' quasar dev",
"pwa": "NODE_ENV=development PORT=8093 APP_VERSION='1.2.70' quasar dev -m pwa",
"spa": "NODE_ENV=development PORT=8083 APP_VERSION='1.2.70' quasar dev",
"debug": "quasar dev --mode debug",
"test": "echo \"No test specified\" && exit 0",
"generate-sw": "workbox generateSW workbox-config.js",

View File

@@ -1,6 +1,6 @@
{
"name": "freeplanet",
"version": "1.2.69",
"version": "1.2.70",
"description": "freeplanet",
"productName": "freeplanet",
"author": "Surya",
@@ -9,11 +9,11 @@
"license": "MIT",
"type": "module",
"scripts": {
"dev": "PORT=8087 APP_VERSION='1.2.69' quasar dev",
"dev": "PORT=8087 APP_VERSION='1.2.70' quasar dev",
"dev_noCheck": "SKIP_TSC=true quasar dev",
"build": "quasar build",
"buildpwa": "NODE_ENV=production APP_VERSION='1.2.69' quasar build -m pwa",
"buildpwatest": "NODE_ENV=production APP_VERSION='1.2.69' quasar build -m pwa",
"buildpwa": "NODE_ENV=production APP_VERSION='1.2.70' quasar build -m pwa",
"buildpwatest": "NODE_ENV=production APP_VERSION='1.2.70' quasar build -m pwa",
"type-check": "vue-tsc --noEmit",
"type-check:watch": "vue-tsc --noEmit --watch",
"buildspa": "quasar build -m spa",
@@ -21,8 +21,8 @@
"lintfile": "eslint --ext .js,.ts,.vue --ignore-path .gitignore ./ > file.out.txt",
"lintfileNoJS": "eslint --ext .ts,.vue --ignore-path .gitignore ./ > file.out.txt",
"fix": "eslint -c ./eslint.config.js \"./src*/**/*.{ts,js,cjs,mjs,vue}\" --ignore-pattern .gitignore ./ --fix > file.out.txt",
"pwa": "NODE_ENV=development PORT=8097 APP_VERSION='1.2.69' quasar dev -m pwa",
"spa": "NODE_ENV=development PORT=8087 APP_VERSION='1.2.69' quasar dev",
"pwa": "NODE_ENV=development PORT=8097 APP_VERSION='1.2.70' quasar dev -m pwa",
"spa": "NODE_ENV=development PORT=8087 APP_VERSION='1.2.70' quasar dev",
"debug": "quasar dev --mode debug",
"test": "echo \"No test specified\" && exit 0",
"generate-sw": "workbox generateSW workbox-config.js",

View File

@@ -1,6 +1,6 @@
{
"name": "gruppomacro",
"version": "1.2.69",
"version": "1.2.70",
"productName": "Gruppo Macro",
"description": "Il Gruppo Editoriale Macro, attivo dal 1987, è leader europeo nella pubblicazione di libri per il benessere e la consapevolezza. Con oltre 1.500 titoli, promuove una visione armonica del mondo, offrendo opere di autori internazionali e italiani come Gregg Braden, Bruce Lipton, Joe Dispenza, Louise Hay, Eckhart Tolle e molti altri. Scopri un'editoria che abbraccia il corpo, la mente, lo spirito e l'ecologia.",
"author": "Surya",
@@ -9,20 +9,20 @@
"license": "MIT",
"type": "module",
"scripts": {
"dev": "PORT=8089 APP_VERSION='1.2.69' quasar dev",
"dev": "PORT=8089 APP_VERSION='1.2.70' quasar dev",
"dev_noCheck": "SKIP_TSC=true quasar dev",
"build": "quasar build",
"buildpwa": "NODE_ENV=production APP_VERSION='1.2.69' quasar build -m pwa",
"buildpwatest": "NODE_ENV=production APP_VERSION='1.2.69' quasar build -m pwa",
"buildpwa": "NODE_ENV=production APP_VERSION='1.2.70' quasar build -m pwa",
"buildpwatest": "NODE_ENV=production APP_VERSION='1.2.70' quasar build -m pwa",
"type-check": "vue-tsc --noEmit",
"type-check:watch": "vue-tsc --noEmit --watch",
"buildspa": "APP_VERSION='1.2.69' quasar build -m spa",
"buildspa": "APP_VERSION='1.2.70' quasar build -m spa",
"lint": "eslint -c ./eslint.config.js \"./src*/**/*.{ts,js,cjs,mjs,vue}\"",
"lintfile": "eslint --ext .js,.ts,.vue --ignore-path .gitignore ./ > file.out.txt",
"lintfileNoJS": "eslint --ext .ts,.vue --ignore-path .gitignore ./ > file.out.txt",
"fix": "eslint -c ./eslint.config.js \"./src*/**/*.{ts,js,cjs,mjs,vue}\" --ignore-pattern .gitignore ./ --fix > file.out.txt",
"pwa": "NODE_ENV=development PORT=8099 APP_VERSION='1.2.69' quasar dev -m pwa",
"spa": "NODE_ENV=development PORT=8089 APP_VERSION='1.2.69' quasar dev",
"pwa": "NODE_ENV=development PORT=8099 APP_VERSION='1.2.70' quasar dev -m pwa",
"spa": "NODE_ENV=development PORT=8089 APP_VERSION='1.2.70' quasar dev",
"debug": "quasar dev --mode debug",
"test": "echo \"No test specified\" && exit 0",
"generate-sw": "workbox generateSW workbox-config.js",

View File

@@ -1,11 +1,11 @@
VITE_APP_ID="13"
VITE_APP_URL="https://riso.app"
VITE_MONGODB_HOST="https://api.riso.app"
VITE_LOGO_REG='riso-logo-full.png'
VITE_PUBLICKEY_PUSH="BGXRf1TgcqocqD6J7qnRgCG7AvM2lxAoW7peb7UEzB4SxBb6DxGRdJ0UvD9ewnrB9KrSrh0-aDCODXBm7sZ1DDs"
VITE_DEBUG="0"
VITE_VUE_APP_ISTEST="0"
DIRECTORY_LOCAL=myprojplanet_vite
DIRECTORY_SERVER=/var/www/nodejs_riso_server
SERVERDIR_WEBSITE="/var/www/riso.app"
VITE_APP_ID="10"
VITE_APP_URL="https://nuovomondo.app"
VITE_MONGODB_HOST="https://api.nuovomondo.app"
VITE_LOGO_REG='nuovomondo-logo-full.png'
VITE_PUBLICKEY_PUSH="BNM-cEpTbPVc_ujXf3QOC8ggf7b-X44P44esfJUWqNOFq1XhWCoZJpOi71_cbXC5SnfO9HassQ6OouAYgtBA9Pw"
VITE_DEBUG="1"
VITE_VUE_APP_ISTEST=0
DIRECTORY_LOCAL="myprojplanet_vite"
DIRECTORY_SERVER="/var/www/nodejs_riso_server"
SERVERDIR_WEBSITE="/var/www/nuovomondo.app"
SERVERPW_WEBSITE="pwdadmin@1AOK"

View File

@@ -1,6 +1,6 @@
{
"name": "nuovomondo",
"version": "1.2.69",
"version": "1.2.70",
"description": "Nuovo Mondo",
"productName": "Nuovo Mondo",
"author": "Surya",
@@ -9,11 +9,11 @@
"license": "MIT",
"type": "module",
"scripts": {
"dev": "APP_VERSION='1.2.69' PORT=8083 quasar dev",
"dev": "APP_VERSION='1.2.70' PORT=8083 quasar dev",
"dev_noCheck": "SKIP_TSC=true quasar dev",
"build": "quasar build",
"buildpwa": "NODE_ENV=production APP_VERSION='1.2.69' quasar build -m pwa",
"buildpwatest": "NODE_ENV=production APP_VERSION='1.2.69' quasar build -m pwa",
"buildpwa": "NODE_ENV=production APP_VERSION='1.2.70' quasar build -m pwa",
"buildpwatest": "NODE_ENV=production APP_VERSION='1.2.70' quasar build -m pwa",
"type-check": "vue-tsc --noEmit",
"type-check:watch": "vue-tsc --noEmit --watch",
"buildspa": "quasar build -m spa",
@@ -21,8 +21,8 @@
"lintfile": "eslint --ext .js,.ts,.vue --ignore-path .gitignore ./ > file.out.txt",
"lintfileNoJS": "eslint --ext .ts,.vue --ignore-path .gitignore ./ > file.out.txt",
"fix": "eslint -c ./eslint.config.js \"./src*/**/*.{ts,js,cjs,mjs,vue}\" --ignore-pattern .gitignore ./ --fix > file.out.txt",
"pwa": "NODE_ENV=development PORT=8094 APP_VERSION='1.2.69' quasar dev -m pwa",
"spa": "NODE_ENV=development PORT=8083 APP_VERSION='1.2.69' quasar dev",
"pwa": "NODE_ENV=development PORT=8094 APP_VERSION='1.2.70' quasar dev -m pwa",
"spa": "NODE_ENV=development PORT=8083 APP_VERSION='1.2.70' quasar dev",
"debug": "quasar dev --mode debug",
"test": "echo \"No test specified\" && exit 0",
"generate-sw": "workbox generateSW workbox-config.js",
@@ -88,13 +88,13 @@
"vue3-qr-reader": "^1.0.0",
"vuedraggable": "^4.1.0",
"vuex": "^4.1.0",
"xlsx": "^0.18.5",
"vuex-router-sync": "^6.0.0-rc.1",
"workbox-core": "^7.3.0",
"workbox-precaching": "^7.3.0",
"workbox-routing": "^7.3.0",
"workbox-strategies": "^7.3.0",
"workbox-window": "^7.3.0"
"workbox-window": "^7.3.0",
"xlsx": "^0.18.5"
},
"devDependencies": {
"@eslint/js": "^9.28.0",

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 8.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 148 KiB

After

Width:  |  Height:  |  Size: 199 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 958 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 952 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 958 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 393 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 411 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 952 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 952 KiB

View File

@@ -1,6 +1,6 @@
{
"name": "nutriben",
"version": "1.2.69",
"version": "1.2.70",
"description": "Nutriben",
"productName": "Nutriben",
"author": "Surya",
@@ -9,20 +9,20 @@
"license": "MIT",
"type": "module",
"scripts": {
"dev": "PORT=8093 APP_VERSION='1.2.69' quasar dev",
"dev": "PORT=8093 APP_VERSION='1.2.70' quasar dev",
"dev_noCheck": "SKIP_TSC=true quasar dev",
"build": "quasar build",
"buildpwa": "NODE_ENV=production APP_VERSION='1.2.69' quasar build -m pwa",
"buildpwatest": "NODE_ENV=production APP_VERSION='1.2.69' quasar build -m pwa",
"buildpwa": "NODE_ENV=production APP_VERSION='1.2.70' quasar build -m pwa",
"buildpwatest": "NODE_ENV=production APP_VERSION='1.2.70' quasar build -m pwa",
"type-check": "vue-tsc --noEmit",
"type-check:watch": "vue-tsc --noEmit --watch",
"buildspa": "APP_VERSION='1.2.69' quasar build -m spa",
"buildspa": "APP_VERSION='1.2.70' quasar build -m spa",
"lint": "eslint -c ./eslint.config.js \"./src*/**/*.{ts,js,cjs,mjs,vue}\"",
"lintfile": "eslint --ext .js,.ts,.vue --ignore-path .gitignore ./ > file.out.txt",
"lintfileNoJS": "eslint --ext .ts,.vue --ignore-path .gitignore ./ > file.out.txt",
"fix": "eslint -c ./eslint.config.js \"./src*/**/*.{ts,js,cjs,mjs,vue}\" --ignore-pattern .gitignore ./ --fix > file.out.txt",
"pwa": "NODE_ENV=development PORT=8099 APP_VERSION='1.2.69' quasar dev -m pwa",
"spa": "NODE_ENV=development PORT=8093 APP_VERSION='1.2.69' quasar dev",
"pwa": "NODE_ENV=development PORT=8099 APP_VERSION='1.2.70' quasar dev -m pwa",
"spa": "NODE_ENV=development PORT=8093 APP_VERSION='1.2.70' quasar dev",
"debug": "quasar dev --mode debug",
"test": "echo \"No test specified\" && exit 0",
"generate-sw": "workbox generateSW workbox-config.js",

View File

@@ -1,6 +1,6 @@
{
"name": "piuchebuono",
"version": "1.2.69",
"version": "1.2.70",
"description": "PiuCheBuono",
"productName": "PiuCheBuono",
"author": "Surya",
@@ -9,11 +9,11 @@
"license": "MIT",
"type": "module",
"scripts": {
"dev": "PORT=8085 APP_VERSION='1.2.69' quasar dev",
"dev": "PORT=8085 APP_VERSION='1.2.70' quasar dev",
"dev_noCheck": "SKIP_TSC=true quasar dev",
"build": "quasar build",
"buildpwa": "NODE_ENV=production APP_VERSION='1.2.69' quasar build -m pwa",
"buildpwatest": "NODE_ENV=production APP_VERSION='1.2.69' quasar build -m pwa",
"buildpwa": "NODE_ENV=production APP_VERSION='1.2.70' quasar build -m pwa",
"buildpwatest": "NODE_ENV=production APP_VERSION='1.2.70' quasar build -m pwa",
"type-check": "vue-tsc --noEmit",
"type-check:watch": "vue-tsc --noEmit --watch",
"buildspa": "quasar build -m spa",
@@ -21,8 +21,8 @@
"lintfile": "eslint --ext .js,.ts,.vue --ignore-path .gitignore ./ > file.out.txt",
"lintfileNoJS": "eslint --ext .ts,.vue --ignore-path .gitignore ./ > file.out.txt",
"fix": "eslint -c ./eslint.config.js \"./src*/**/*.{ts,js,cjs,mjs,vue}\" --ignore-pattern .gitignore ./ --fix > file.out.txt",
"pwa": "NODE_ENV=development PORT=8085 APP_VERSION='1.2.69' quasar dev -m pwa",
"spa": "NODE_ENV=development PORT=8085 APP_VERSION='1.2.69' quasar dev",
"pwa": "NODE_ENV=development PORT=8085 APP_VERSION='1.2.70' quasar dev -m pwa",
"spa": "NODE_ENV=development PORT=8085 APP_VERSION='1.2.70' quasar dev",
"debug": "quasar dev --mode debug",
"test": "echo \"No test specified\" && exit 0",
"generate-sw": "workbox generateSW workbox-config.js",

View File

@@ -1,6 +1,6 @@
{
"name": "riso",
"version": "1.2.69",
"version": "1.2.70",
"productName": "Riso 💚 - Rete Italiana Scambi Orizzontali",
"description": "Progetto RISO (Rete Italiana Scambi Orizzontali) promuove una rete di comunità locali che favoriscono scambi di beni, servizi e ospitalità. Con l'App RISO, sviluppata per facilitare il baratto, il dono e l'uso di monete alternative come i RIS, il progetto crea legami autentici basati sulla fiducia e sostenibilità. Partecipa agli scambi e costruisci una comunità più consapevole e autosufficiente.",
"author": "Surya",
@@ -9,11 +9,11 @@
"license": "MIT",
"type": "module",
"scripts": {
"dev": "APP_VERSION='1.2.69' PORT=8084 quasar dev",
"dev": "APP_VERSION='1.2.70' PORT=8084 quasar dev",
"dev_noCheck": "SKIP_TSC=true quasar dev",
"build": "quasar build",
"buildpwa": "NODE_ENV=production APP_VERSION='1.2.69' quasar build -m pwa",
"buildpwatest": "NODE_ENV=production APP_VERSION='1.2.69' quasar build -m pwa",
"buildpwa": "NODE_ENV=production APP_VERSION='1.2.70' quasar build -m pwa",
"buildpwatest": "NODE_ENV=production APP_VERSION='1.2.70' quasar build -m pwa",
"type-check": "vue-tsc --noEmit",
"type-check:watch": "vue-tsc --noEmit --watch",
"buildspa": "quasar build -m spa",
@@ -21,8 +21,8 @@
"lintfile": "eslint --ext .js,.ts,.vue --ignore-path .gitignore ./ > file.out.txt",
"lintfileNoJS": "eslint --ext .ts,.vue --ignore-path .gitignore ./ > file.out.txt",
"fix": "eslint -c ./eslint.config.js \"./src*/**/*.{ts,js,cjs,mjs,vue}\" --ignore-pattern .gitignore ./ --fix > file.out.txt",
"pwa": "NODE_ENV=development PORT=8094 APP_VERSION='1.2.69' quasar dev -m pwa",
"spa": "NODE_ENV=development PORT=8084 APP_VERSION='1.2.69' quasar dev",
"pwa": "NODE_ENV=development PORT=8094 APP_VERSION='1.2.70' quasar dev -m pwa",
"spa": "NODE_ENV=development PORT=8084 APP_VERSION='1.2.70' quasar dev",
"debug": "quasar dev --mode debug",
"test": "echo \"No test specified\" && exit 0",
"generate-sw": "workbox generateSW workbox-config.js",

View File

@@ -1 +1 @@
TERMINA DI LAVORARE SU riso.app: (Sovrascrivo!)
TERMINA DI LAVORARE SU nuovomondo.app: (Sovrascrivo!)

View File

@@ -3,7 +3,7 @@
/* global workbox */
/* global cfgenv */
const VITE_APP_VERSION = '1.2.69';
const VITE_APP_VERSION = '1.2.70';
// Costanti di configurazione
const DYNAMIC_CACHE = 'dynamic-cache-v2';

View File

@@ -1,7 +1,7 @@
{
"name": "PiuCheBuono",
"short_name": "PiuCheBuono",
"description": "PiuCheBuono è un GAS e Bottega",
"name": "Gruppo Macro",
"short_name": "GruppoMacro",
"description": "",
"display": "standalone",
"orientation": "portrait",
"background_color": "#fff",
@@ -11,47 +11,17 @@
"start_url": "/?homescreen=1",
"icons": [
{
"src:": "/images/pcb-android-icon-512x512.png",
"src": "/images/gm-android-icon-512x512.png",
"sizes": "512x512",
"type": "image/png"
},
{
"src:": "/images/pcb-android-icon-384x384.png",
"sizes": "384x384",
"type": "image/png"
},
{
"src:": "/images/pcb-android-icon-192x192.png",
"src": "/images/gm-android-icon-192x192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src:": "/images/pcb-android-icon-144x144.png",
"sizes": "144x144",
"type": "image/png"
},
{
"src:": "/images/pcb-android-icon-96x96.png",
"sizes": "96x96",
"type": "image/png"
},
{
"src:": "/images/pcb-apple-icon-120x120.png",
"sizes": "120x120",
"type": "image/png"
},
{
"src:": "/images/pcb-apple-icon-144x144.png",
"sizes": "144x144",
"type": "image/png"
},
{
"src:": "/images/pcb-apple-icon-152x152.png",
"sizes": "152x152",
"type": "image/png"
},
{
"src:": "/images/pcb-apple-icon-180x180.png",
"src": "/images/gm-apple-touch-icon.png",
"sizes": "180x180",
"type": "image/png"
}

View File

@@ -24,29 +24,35 @@
</q-expansion-item>
<!-- Foglia -->
<router-link v-else :to="getroute(item)">
<q-item clickable :to="getroute(item)" active-class="my-menu-active">
<q-item-section thumbnail>
<q-avatar
:icon="item.materialIcon"
:size="item.iconsize || '2rem'"
:font-size="item.iconsize || '2rem'"
text-color="primary"
square
rounded
/>
</q-item-section>
<q-item-section>
<span :class="item.extraclass">{{ tools.getLabelByItem(item) }}</span>
<span v-if="item.subtitle" class="subtitle">{{ item.subtitle }}</span>
</q-item-section>
</q-item>
</router-link>
<q-item
v-else
clickable
:to="getroute(item)"
active-class="my-menu-active"
>
<q-item-section thumbnail>
<q-avatar
:icon="item.materialIcon"
:size="item.iconsize || '2rem'"
:font-size="item.iconsize || '2rem'"
text-color="primary"
square
rounded
/>
</q-item-section>
<q-item-section>
<span :class="item.extraclass">{{ tools.getLabelByItem(item) }}</span>
<span
v-if="item.subtitle"
class="subtitle"
>{{ item.subtitle }}</span
>
</q-item-section>
</q-item>
</div>
</template>
<script lang="ts" src="./CMenuItem.ts">
</script>
<script lang="ts" src="./CMenuItem.ts"></script>
<style lang="scss" scoped>
@import './CMenuItem.scss';

View File

@@ -35,7 +35,7 @@
<q-editor
ref="editorRef"
content-class="wrap_anywhere"
content-class="styled-content"
toolbar-text-color="white"
toolbar-toggle-color="yellow-8"
toolbar-bg="primary"

View File

View File

@@ -0,0 +1,43 @@
import { defineComponent } from 'vue';
// Importiamo icone da Quasar - esempio con quelle disponibili tramite Quasar Extras
// Assicurati di averle abilitate in quasar.config.js
import { IFeatSection } from 'app/src/model';
import { tools } from 'app/src/store/Modules/tools';
import { useQuasar } from 'quasar';
export default defineComponent({
name: 'HeroSection',
props: {
title: {
type: String,
required: true,
},
isDark: {
type: Boolean,
required: false,
default: false,
},
subtitle: {
type: String,
required: false,
default: '',
},
description: {
type: String,
required: false,
default: '',
},
features: {
type: Array as () => IFeatSection[],
required: true,
},
},
setup(props) {
return {
tools,
};
},
});

View File

@@ -0,0 +1,10 @@
<template>
<div :class="{'bg-dark': isDark}" class="q-py-xl">
</div>
</template>
<script lang="ts" src="./HeroSection.ts"></script>
<style lang="scss" scoped>
@import './HeroSection.scss';
</style>

View File

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

View File

@@ -10,7 +10,7 @@ export default defineComponent({
},
emits: ['select', 'edit', 'delete', 'open'],
setup(props, { emit }) {
const showGrip = computed(() => props.variant === 'menu');
const showGrip = true
const displayPath = (path?: string) => {
if (!path) return '-';

View File

@@ -516,7 +516,7 @@ export default defineComponent({
}
function imglogo() {
return `../../${tools.getimglogo()}`;
return `${tools.getimglogo()}`;
}
function getappname() {

View File

@@ -1,9 +1,25 @@
<template>
<div v-if="globalStore.showHeader">
<q-header v-if="site" reveal elevated :class="getClassColorHeader" :style="`color: ` + getColorText + `;`">
<q-toolbar color="primary" :glossy="!$q.platform.is.ios && !$q.platform.is.android" :inverted="$q.platform.is.ios"
class="toolbar">
<q-btn flat dense round @click="clickMenu3Orizz" aria-label="Menu">
<q-header
v-if="site"
reveal
elevated
:class="getClassColorHeader"
:style="`color: ` + getColorText + `;`"
>
<q-toolbar
color="primary"
:glossy="!$q.platform.is.ios && !$q.platform.is.android"
:inverted="$q.platform.is.ios"
class="toolbar"
>
<q-btn
flat
dense
round
@click="clickMenu3Orizz"
aria-label="Menu"
>
<q-icon name="menu" />
</q-btn>
@@ -19,15 +35,34 @@
<!--I'm only rendered on Electron!-->
</div>
<q-btn size="md" id="newvers" v-if="isNewVersionAvailable() || data.updateExists" color="secondary" rounded
icon="refresh" class="btnNewVersShow" @click="RefreshApp()" :label="t('notification.newVersionAvailable')">
<q-btn
size="md"
id="newvers"
v-if="isNewVersionAvailable() || data.updateExists"
color="secondary"
rounded
icon="refresh"
class="btnNewVersShow"
@click="RefreshApp()"
:label="t('notification.newVersionAvailable')"
>
</q-btn>
<q-toolbar-title class="row items-center">
<q-avatar @click="toHome" class="imglink">
<img :src="imglogo()" height="27" alt="Immagine Logo" />
<q-avatar
@click="toHome"
class="imglink"
>
<img
:src="imglogo()"
height="27"
alt="Immagine Logo"
/>
</q-avatar>
<div v-if="$q.screen.gt.xs" class="q-mx-sm titlesite">
<div
v-if="$q.screen.gt.xs"
class="q-mx-sm titlesite"
>
{{ getappname() }}
</div>
</q-toolbar-title>
@@ -45,28 +80,76 @@
</div>
-->
<div v-if="site.confpages && site.confpages?.show_darkopt" class="text-h7">
<q-toggle :icon="'fas fa-moon'" v-model="dark"> </q-toggle>
<div
v-if="site.confpages && site.confpages?.show_darkopt"
class="text-h7"
>
<q-toggle
:icon="'fas fa-moon'"
v-model="dark"
>
</q-toggle>
</div>
<div v-if="
tools.isLogged() &&
(isAdmin() || tools.isCollaboratore())
" class="text-h7">
<q-toggle :icon="'fas fa-pencil-alt'" v-model="editOn"> </q-toggle>
<div
v-if="tools.isLogged() && (isAdmin() || tools.isCollaboratore())"
class="text-h7"
>
<q-toggle
:icon="'fas fa-pencil-alt'"
v-model="editOn"
>
</q-toggle>
</div>
<q-btn v-if="!isonline() && site.confpages && site.confpages?.showConnected" flat dense round
aria-label="Connection">
<q-icon :name="iconConn" :class="clIconConn"></q-icon>
<q-icon v-if="isUserNotAuth" name="device_unknown"></q-icon>
<div
v-if="tools.isLogged() && (isAdmin() || tools.isCollaboratore())"
>
<q-btn
flat
dense
round
icon="settings"
:to="{ name: 'admin-dashboard' }"
aria-label="Apri pannello amministrazione"
/>
</div>
<q-btn
v-if="!isonline() && site.confpages && site.confpages?.showConnected"
flat
dense
round
aria-label="Connection"
>
<q-icon
:name="iconConn"
:class="clIconConn"
></q-icon>
<q-icon
v-if="isUserNotAuth"
name="device_unknown"
></q-icon>
</q-btn>
<q-btn-dropdown stretch v-if="isfinishLoading && static_data.lang_available.length > 1" flat :label="langshort"
auto-close>
<q-btn-dropdown
stretch
v-if="isfinishLoading && static_data.lang_available.length > 1"
flat
:label="langshort"
auto-close
>
<q-list bordered>
<q-item clickable v-ripple v-for="langrec in static_data.lang_available" :key="langrec.value"
@click="lang = langrec.value">
<q-item
clickable
v-ripple
v-for="langrec in static_data.lang_available"
:key="langrec.value"
@click="lang = langrec.value"
>
<q-item-section avatar>
<img :src="langrec.image" class="flagimg" alt="flag" />
<img
:src="langrec.image"
class="flagimg"
alt="flag"
/>
</q-item-section>
<q-item-section>
{{ langrec.label }}
@@ -92,155 +175,315 @@
<!-- BUTTON USER BAR -->
<q-btn class="q-mx-xs" v-if="
site.confpages && site.confpages?.enableEcommerce && tools.isLogged()
" round dense flat @click="rightCartOpen = !rightCartOpen" icon="fas fa-shopping-cart">
<q-badge v-if="getnumItemsCart() > 0" color="red" floating transparent>
<q-btn
class="q-mx-xs"
v-if="site.confpages && site.confpages?.enableEcommerce && tools.isLogged()"
round
dense
flat
@click="rightCartOpen = !rightCartOpen"
icon="fas fa-shopping-cart"
>
<q-badge
v-if="getnumItemsCart() > 0"
color="red"
floating
transparent
>
{{ getnumItemsCart() }}
</q-badge>
</q-btn>
<q-btn class="q-mx-xs" v-if="
site.confpages &&
site.confpages?.enableEcommerce &&
tools.isLogged() &&
getnumOrdersCart() > 0
" round dense flat to="/orderinfo" icon="fas fa-list-ol">
<q-badge v-if="getnumOrdersCart() > 0" color="blue" floating transparent>
<q-btn
class="q-mx-xs"
v-if="
site.confpages &&
site.confpages?.enableEcommerce &&
tools.isLogged() &&
getnumOrdersCart() > 0
"
round
dense
flat
to="/orderinfo"
icon="fas fa-list-ol"
>
<q-badge
v-if="getnumOrdersCart() > 0"
color="blue"
floating
transparent
>
{{ getnumOrdersCart() }}
</q-badge>
</q-btn>
<q-btn class="q-mx-xs" v-if="
site.confpages && site.confpages?.showUserMenu && !tools.isLogged()
" dense flat round icon="fas fa-user" @click="rightDrawerOpen = !rightDrawerOpen">
<q-btn
class="q-mx-xs"
v-if="site.confpages && site.confpages?.showUserMenu && !tools.isLogged()"
dense
flat
round
icon="fas fa-user"
@click="rightDrawerOpen = !rightDrawerOpen"
>
</q-btn>
<q-avatar v-else-if="
site.confpages &&
site.confpages?.showUserMenu &&
tools.isLogged() &&
getMyImg() &&
$q.screen.gt.sm
" size="36px" class="center_img cursor-pointer" @click="rightDrawerOpen = !rightDrawerOpen">
<q-img ratio="1" fit="cover" :src="getMyImg()" :alt="Username()" img-class="imgprofile_small"
stretch="false" />
<q-avatar
v-else-if="
site.confpages &&
site.confpages?.showUserMenu &&
tools.isLogged() &&
getMyImg() &&
$q.screen.gt.sm
"
size="36px"
class="center_img cursor-pointer"
@click="rightDrawerOpen = !rightDrawerOpen"
>
<q-img
ratio="1"
fit="cover"
:src="getMyImg()"
:alt="Username()"
img-class="imgprofile_small"
stretch="false"
/>
</q-avatar>
<q-btn v-else-if="$q.screen.gt.xs" class="q-mx-xs iconprofile_small" round dense flat
@click="rightDrawerOpen = !rightDrawerOpen" :icon="getMyImgforIcon()" :color="getcolormenu()">
<q-btn
v-else-if="$q.screen.gt.xs"
class="q-mx-xs iconprofile_small"
round
dense
flat
@click="rightDrawerOpen = !rightDrawerOpen"
:icon="getMyImgforIcon()"
:color="getcolormenu()"
>
</q-btn>
</q-toolbar>
</q-header>
<q-drawer side="left" bordered :show-if-above="globalStore.leftDrawerOpen" :breakpoint="800"
v-model="leftDrawerOpen" :content-class="['bg-grey-1', 'q-pa-sm']" :content-style="{ padding: '0px' }">
<q-drawer
side="left"
bordered
:show-if-above="globalStore.leftDrawerOpen"
:breakpoint="800"
v-model="leftDrawerOpen"
:content-class="['bg-grey-1', 'q-pa-sm']"
:content-style="{ padding: '0px' }"
>
<drawer :clBase="clBase"></drawer>
</q-drawer>
<!-- USER BAR -->
<q-drawer v-if="site.confpages && site.confpages?.enableEcommerce" v-model="rightCartOpen" class="q-drawer-cart"
side="right" elevated>
<q-btn class="absolute-top-right" :style="`margin-right: 10px; color:` + getColorText + `;`" dense flat round
icon="close" @click="rightCartOpen = !rightCartOpen">
<q-drawer
v-if="site.confpages && site.confpages?.enableEcommerce"
v-model="rightCartOpen"
class="q-drawer-cart"
side="right"
elevated
>
<q-btn
class="absolute-top-right"
:style="`margin-right: 10px; color:` + getColorText + `;`"
dense
flat
round
icon="close"
@click="rightCartOpen = !rightCartOpen"
>
</q-btn>
<CSelectUserActive></CSelectUserActive>
<div v-if="tools.isLogged()" class="bg-primary text-white q-pa-sm q-mb-md" style="border-radius: 0px">
<q-icon name="fas fa-shopping-cart" class="q-mr-sm" />
{{ $t("ecomm.carrello_di", { user: products.userActive.username }) }}
<div
v-if="tools.isLogged()"
class="bg-primary text-white q-pa-sm q-mb-md"
style="border-radius: 0px"
>
<q-icon
name="fas fa-shopping-cart"
class="q-mr-sm"
/>
{{ $t('ecomm.carrello_di', { user: products.userActive.username }) }}
</div>
<CMyCart v-if="isfinishLoading"></CMyCart>
</q-drawer>
<!-- USER BAR -->
<q-drawer v-if="site.confpages && site.confpages?.showUserMenu" v-model="rightDrawerOpen" side="right" elevated>
<q-drawer
v-if="site.confpages && site.confpages?.showUserMenu"
v-model="rightDrawerOpen"
side="right"
elevated
>
<div id="profile">
<q-img class="absolute-top" src="/images/landing_first_section.png" style="height: 150px" alt="section page">
<q-img
class="absolute-top"
src="/images/landing_first_section.png"
style="height: 150px"
alt="section page"
>
</q-img>
<div class="absolute-top bg-transparent text-black center_img" style="margin-top: 10px">
<div :class="`text-center q-ma-xs boldhigh text-` + getColorText + ` text-h7`
">
{{ t("header.area_personale") }}
<div
class="absolute-top bg-transparent text-black center_img"
style="margin-top: 10px"
>
<div :class="`text-center q-ma-xs boldhigh text-` + getColorText + ` text-h7`">
{{ t('header.area_personale') }}
</div>
<div v-if="getMyImg()" class="row justify-center q-pa-md">
<q-avatar size="80px" class="center_img q-ma-md">
<q-img fit="cover" :src="getMyImg()" :alt="Username()" img-class="imgprofile" height="80px" />
<div
v-if="getMyImg()"
class="row justify-center q-pa-md"
>
<q-avatar
size="80px"
class="center_img q-ma-md"
>
<q-img
fit="cover"
:src="getMyImg()"
:alt="Username()"
img-class="imgprofile"
height="80px"
/>
</q-avatar>
</div>
<div v-if="tools.isLogged()" class="text-weight-bold text-user">
<div
v-if="tools.isLogged()"
class="text-weight-bold text-user"
>
{{ Username() }}<span v-if="myName()"> - {{ myName() }}</span>
<span v-if="mySurname()">&nbsp;{{ mySurname() }}</span>
</div>
<div class="row justify-evenly q-pa-xs-sm">
<div v-if="tools.isLogged() && isAdmin()" class="text-weight-bold text-user bg-red q-px-xs">
<div
v-if="tools.isLogged() && isAdmin()"
class="text-weight-bold text-user bg-red q-px-xs"
>
Admin
</div>
<div v-if="isSocio" class="text-weight-bold text-user q-px-xs">
<div
v-if="isSocio"
class="text-weight-bold text-user q-px-xs"
>
Socio
</div>
<div v-if="isSocioResidente()" class="text-weight-bold text-user q-px-xs bg-amber">
<div
v-if="isSocioResidente()"
class="text-weight-bold text-user q-px-xs bg-amber"
>
Residente
</div>
<div v-if="isConsiglio()" class="text-weight-bold text-user q-px-xs bg-deep-orange-10">
<div
v-if="isConsiglio()"
class="text-weight-bold text-user q-px-xs bg-deep-orange-10"
>
Consiglio
</div>
<div v-if="tools.isManager()" class="text-weight-bold text-user bg-blue q-px-xs">
<div
v-if="tools.isManager()"
class="text-weight-bold text-user bg-blue q-px-xs"
>
Segreteria
</div>
<div v-if="tools.isEditor()" class="text-weight-bold text-user bg-indigo q-px-xs">
<div
v-if="tools.isEditor()"
class="text-weight-bold text-user bg-indigo q-px-xs"
>
Editore
</div>
<div v-if="tools.isCommerciale()" class="text-weight-bold text-user bg-brown q-px-xs">
<div
v-if="tools.isCommerciale()"
class="text-weight-bold text-user bg-brown q-px-xs"
>
Commerciale
</div>
<div v-if="isFacilitatore()" class="text-weight-bold text-user q-px-xs">
<div
v-if="isFacilitatore()"
class="text-weight-bold text-user q-px-xs"
>
Facilitatore
</div>
<div v-if="isTratuttrici()" class="text-weight-bold text-user q-px-xs">
<div
v-if="isTratuttrici()"
class="text-weight-bold text-user q-px-xs"
>
Editor
</div>
</div>
<div v-if="!tools.isLogged()" class="text-user text-italic bg-red">
{{ t("user.loggati") }}
<div
v-if="!tools.isLogged()"
class="text-user text-italic bg-red"
>
{{ t('user.loggati') }}
</div>
<div v-if="tools.isLogged() && !tools.isVerified()" class="text-verified">
{{ t("components.authentication.email_verification.verify_email") }}
<div
v-if="tools.isLogged() && !tools.isVerified()"
class="text-verified"
>
{{ t('components.authentication.email_verification.verify_email') }}
</div>
<div v-if="tools.isLogged()" class="text-verified">
<div
v-if="tools.isLogged()"
class="text-verified"
>
<!-- <span class="text-white" v-if="Verificato()"> {{t('reg.verificato')}} </span> -->
<span class="text-user text-italic bg-red" v-if="!tools.Verificato()">
{{ t("reg.non_verificato") }}
<span
class="text-user text-italic bg-red"
v-if="!tools.Verificato()"
>
{{ t('reg.non_verificato') }}
</span>
</div>
<div v-if="tools.isLogged()" id="user-actions" class="column justify-center q-gutter-sm q-ma-sm center-150">
<q-btn rounded color="primary" icon="person" :to="`/my/` + getMyUsername()">{{ t("pages.profile") }}
<div
v-if="tools.isLogged()"
id="user-actions"
class="column justify-center q-gutter-sm q-ma-sm center-150"
>
<q-btn
rounded
color="primary"
icon="person"
:to="`/my/` + getMyUsername()"
>{{ t('pages.profile') }}
</q-btn>
<q-btn rounded color="negative" icon="exit_to_app" @click="logoutHandler">{{ t("login.esci") }}</q-btn>
<q-btn
rounded
color="negative"
icon="exit_to_app"
@click="logoutHandler"
>{{ t('login.esci') }}</q-btn
>
</div>
</div>
<div style="margin-top: 120px"></div>
<div v-show="!tools.isLogged()">
<div v-if="site.confpages && site.confpages?.showRegButton" class="q-ma-md" style="">
<div
v-if="site.confpages && site.confpages?.showRegButton"
class="q-ma-md"
style=""
>
<CSigninNoreg :showregbutt="site.confpages && site.confpages?.showRegButton">
</CSigninNoreg>
</div>
</div>
</div>
<div v-if="tools.isLogged()" class="q-mt-lg"></div>
<div
v-if="tools.isLogged()"
class="q-mt-lg"
></div>
</q-drawer>
</div>
</template>
<script lang="ts" src="./MyHeader.ts">
</script>
<script lang="ts" src="./MyHeader.ts"></script>
<style lang="scss" scoped>
@import "./MyHeader.scss";
@import './MyHeader.scss';
</style>

View File

View File

@@ -0,0 +1,168 @@
import { defineComponent, computed, ref, onMounted, watch } from 'vue';
import { useHomeStore } from 'src/stores/home.store';
import type { HomeCMS, GalleryItem, Pillar } from 'src/types/home';
import { date } from 'quasar';
import { Notify } from 'quasar';
import './HomePage.scss';
export default defineComponent({
name: 'HomePage',
props: {
initialData: { type: Object as () => HomeCMS | undefined, default: undefined },
enableParallax: { type: Boolean, default: true },
// SEO/Head (esposti per integrazione router-meta)
pageTitle: { type: String, default: 'Comunità & Permacultura' },
pageDescription: { type: String, default: 'Vita di comunità, autosufficienza, eventi e progetti.' },
ogImage: { type: String, default: '' }
},
setup(props) {
const store = useHomeStore();
// Stato UI editor
const sectionsEnabled = ref({
hero: true,
vision: true,
pillars: true,
events: true,
collabora: true,
testimonials: true,
gallery: true,
faq: true,
posts: true,
map: true,
newsletter: true,
finalCta: true
});
const sectionOptions = [
{ key: 'hero', label: 'Hero' },
{ key: 'vision', label: 'Visione' },
{ key: 'pillars', label: 'Pillars' },
{ key: 'events', label: 'Eventi' },
{ key: 'collabora', label: 'Collabora' },
{ key: 'testimonials', label: 'Testimonianze' },
{ key: 'gallery', label: 'Galleria' },
{ key: 'faq', label: 'FAQ' },
{ key: 'posts', label: 'News' },
{ key: 'map', label: 'Mappa' },
{ key: 'newsletter', label: 'Newsletter' },
{ key: 'finalCta', label: 'CTA finale' }
] as const;
// Lightbox
const lightbox = ref<{ open: boolean; current?: GalleryItem | null }>({ open: false, current: null });
const currentImage = computed(() => lightbox.value.current || null);
const openLightbox = (g: GalleryItem) => { lightbox.value.open = true; lightbox.value.current = g; };
// Carousel
const carouselSlide = ref(0);
const pauseCarousel = ref(false);
// Newsletter
const newsletter = ref({ email: '' });
const emailRule = (val: string) => /.+@.+\..+/.test(val) || 'Email non valida';
const subscribe = async () => {
try {
await store.subscribeNewsletter(newsletter.value.email);
Notify.create({ type: 'positive', message: 'Iscrizione effettuata. Grazie!' });
newsletter.value.email = '';
} catch (e: any) {
// Lo snackbar globale è già gestito dallinterceptor, ma mostriamo feedback locale
Notify.create({ type: 'negative', message: e?.message || 'Errore iscrizione' });
}
};
// Collabora
const collaboraOptions = [
{ key: 'vol', title: 'Volontariato', icon: 'volunteer_activism', excerpt: 'Dai una mano ai progetti in corso.', cta: 'Scrivici', to: '/collabora' },
{ key: 'res', title: 'Residenzialità', icon: 'home', excerpt: 'Vivi con noi periodi di prova e scambio.', cta: 'Info', to: '/residenzialita' },
{ key: 'don', title: 'Sostieni', icon: 'diversity_2', excerpt: 'Sostieni lecovillaggio con una donazione.', cta: 'Dona ora', to: '/sostieni' }
] as const;
// Vision values: usiamo i primi 4 pillars come “valori”
const visionValues = computed<Pillar[]>(() => (store.data?.pillars || []).slice(0, 4));
// Link utili
const collaboraLink = computed(() => '/collabora');
const eventsLink = computed(() => '/calendario-eventi');
const directionsLink = computed(() => 'https://maps.app.goo.gl/');
// Stato derivato
const data = computed(() => store.data);
const loading = computed(() => store.loading);
const eventsState = computed(() => ({ loading: store.loadingEvents, error: store.errorEvents }));
const postsState = computed(() => ({ loading: store.loadingPosts, error: store.errorPosts }));
const nextEvents = computed(() => store.nextEvents);
const latestPosts = computed(() => store.latestPosts);
// Formattazione date
const formatDate = (iso: string) => date.formatDate(iso, 'D MMMM YYYY', { locale: 'it-IT' });
// CTA click (tracking, scroll, ecc.)
const onCta = (cta: { label: string; to?: string; href?: string }) => {
if (cta.to === '/calendario-eventi') {
// esempio: potresti fare scroll a sezione eventi
const el = document.getElementById('events-heading');
el?.scrollIntoView({ behavior: 'smooth', block: 'start' });
}
};
// Caricamento iniziale
const reloadAll = async () => {
await Promise.all([
store.fetchHome(props.initialData),
store.fetchEvents(),
store.fetchPosts()
]);
};
// Salvataggio layout (solo client-side per demo)
const saveLayout = () => {
localStorage.setItem('home.sections', JSON.stringify(sectionsEnabled.value));
Notify.create({ type: 'positive', message: 'Layout salvato (locale).' });
};
// Ripristino layout
onMounted(async () => {
try {
const saved = localStorage.getItem('home.sections');
if (saved) sectionsEnabled.value = JSON.parse(saved);
} catch {}
await reloadAll();
});
// Aggiorna vision se cambia data
watch(() => store.data?.pillars, () => { /* no-op, computed si aggiorna */ });
return {
// props
enableParallax: props.enableParallax,
// data
data, loading,
sectionsEnabled, sectionOptions,
// events
nextEvents, latestPosts, eventsState, postsState,
formatDate,
// collabora
collaboraOptions, collaboraLink, eventsLink, directionsLink,
// gallery
lightbox, currentImage, openLightbox,
// newsletter
newsletter, emailRule, subscribe,
// carousel
carouselSlide, pauseCarousel,
// editor actions
reloadAll, saveLayout,
// cta
onCta
};
}
});

View File

@@ -0,0 +1,392 @@
<template>
<q-page class="home-page">
<!-- Skip link -->
<a class="skip-link" href="#main-content">Salta al contenuto principale</a>
<!-- Toolbar editor (toggle sezioni) -->
<div class="editor-toolbar q-pa-md q-gutter-sm" role="region" aria-label="Editor sezione pagina">
<q-card flat bordered class="q-pa-md rounded-xl editor-card">
<div class="row items-center q-col-gutter-sm">
<div class="col-12 col-sm-auto">
<div class="text-subtitle1 text-weight-medium">Sezioni visibili</div>
</div>
<div class="col-12 col-sm">
<div class="row q-col-gutter-sm">
<div class="col-auto" v-for="opt in sectionOptions" :key="opt.key">
<q-toggle
v-model="sectionsEnabled[opt.key]"
:label="opt.label"
size="md"
color="primary"
keep-color
dense
:aria-label="`Attiva sezione ${opt.label}`"
/>
</div>
</div>
</div>
<div class="col-12 col-sm-auto q-gutter-sm flex">
<q-btn unelevated color="primary" icon="refresh" label="Ricarica contenuti" @click="reloadAll" />
<q-btn flat color="primary" icon="save" label="Salva configurazione" @click="saveLayout" />
</div>
</div>
</q-card>
</div>
<!-- HERO -->
<section v-if="sectionsEnabled.hero" class="section section--hero" aria-labelledby="hero-heading">
<q-skeleton v-if="loading && !data?.hero" type="rect" height="60vh" />
<template v-else>
<q-parallax v-if="enableParallax" :src="data?.hero?.mediaUrl" :height="560">
<div class="hero-overlay" aria-hidden="true"></div>
<div class="hero-content">
<q-badge v-if="data?.hero?.badge" color="secondary" class="q-mb-md">{{ data?.hero?.badge }}</q-badge>
<h1 id="hero-heading" class="hero-title">{{ data?.hero?.title }}</h1>
<p class="hero-subtitle" v-if="data?.hero?.subtitle">{{ data?.hero?.subtitle }}</p>
<div class="q-gutter-sm">
<q-btn
v-for="(cta, i) in data?.hero?.ctas"
:key="'hero-cta-' + i"
:label="cta.label"
color="primary"
unelevated
:to="cta.to"
:href="cta.href"
@click="onCta(cta)"
/>
</div>
<slot name="hero-extra" />
</div>
</q-parallax>
<div v-else class="hero-fallback">
<q-img :src="data?.hero?.mediaUrl" ratio="16/9">
<div class="absolute-full hero-overlay"></div>
<div class="absolute-full flex flex-center column hero-content">
<q-badge v-if="data?.hero?.badge" color="secondary" class="q-mb-md">{{ data?.hero?.badge }}</q-badge>
<h1 id="hero-heading" class="hero-title">{{ data?.hero?.title }}</h1>
<p class="hero-subtitle" v-if="data?.hero?.subtitle">{{ data?.hero?.subtitle }}</p>
<div class="q-gutter-sm">
<q-btn
v-for="(cta, i) in data?.hero?.ctas"
:key="'hero-cta2-' + i"
:label="cta.label"
color="primary"
unelevated
:to="cta.to"
:href="cta.href"
@click="onCta(cta)"
/>
</div>
<slot name="hero-extra" />
</div>
</q-img>
</div>
</template>
</section>
<main id="main-content">
<!-- Visione/Mission -->
<section v-if="sectionsEnabled.vision" class="section section--vision" aria-labelledby="vision-heading">
<div class="container">
<h2 id="vision-heading" class="section-title">Visione &amp; Mission</h2>
<q-skeleton v-if="loading && !data?.pillars?.length" type="text" class="q-mb-md" />
<div class="row q-col-gutter-md">
<div
v-for="(val, idx) in visionValues"
:key="'vision-' + idx"
class="col-12 col-sm-6 col-md-3"
>
<q-card flat bordered class="rounded-xl h-100">
<q-card-section class="text-center">
<q-icon :name="val.icon" size="md" aria-hidden="true" />
<div class="text-subtitle1 q-mt-sm">{{ val.title }}</div>
<div class="text-body2 text-secondary" v-html="val.excerpt"></div>
</q-card-section>
</q-card>
</div>
</div>
</div>
</section>
<!-- Pillars -->
<section v-if="sectionsEnabled.pillars" class="section section--pillars" aria-labelledby="pillars-heading">
<div class="container">
<h2 id="pillars-heading" class="section-title">Il nostro Progetto</h2>
<q-skeleton v-if="loading && !data?.pillars?.length" type="rect" height="120px" class="q-mb-md" />
<div v-else class="row q-col-gutter-md">
<div
v-for="p in data?.pillars"
:key="p.id"
class="col-12 col-md-4"
>
<q-card flat bordered class="rounded-xl h-100">
<q-card-section>
<div class="row items-center no-wrap">
<q-icon :name="p.icon" size="md" class="q-mr-sm" :aria-label="p.title" />
<div class="text-h6 q-my-none">{{ p.title }}</div>
</div>
<p class="q-mt-sm text-body2">{{ p.excerpt }}</p>
</q-card-section>
<q-card-actions align="right">
<q-btn flat color="primary" label="Scopri di più" :to="p.to" />
</q-card-actions>
</q-card>
</div>
</div>
</div>
</section>
<!-- Eventi -->
<section v-if="sectionsEnabled.events" class="section section--events" aria-labelledby="events-heading">
<div class="container">
<div class="row items-end justify-between q-mb-md">
<h2 id="events-heading" class="section-title col-auto">Eventi</h2>
<div class="col-auto">
<q-btn flat color="primary" label="Vedi tutti" to="/calendario-eventi" />
</div>
</div>
<div v-if="eventsState.loading" class="q-gutter-md">
<q-skeleton type="rect" height="120px" v-for="i in 3" :key="'ev-sk-' + i" />
</div>
<div v-else-if="eventsState.error" class="empty-state">
<q-icon name="warning" class="q-mr-sm" />
<span>{{ eventsState.error }}</span>
</div>
<div v-else-if="!nextEvents?.length" class="empty-state">
<q-icon name="event_busy" class="q-mr-sm" />
<span>Nessun evento in programma. <q-btn flat color="primary" label="Proponi un evento" :to="collaboraLink" /></span>
</div>
<div v-else class="row q-col-gutter-md">
<div v-for="ev in nextEvents" :key="ev.id" class="col-12 col-md-6 col-lg-3">
<q-card flat bordered class="rounded-xl h-100">
<q-img :src="ev.cover" ratio="16/9" />
<q-card-section>
<div class="text-subtitle1 q-mb-xs">{{ ev.title }}</div>
<div class="text-caption text-secondary">
<q-icon name="event" size="16px" aria-hidden="true" /> {{ formatDate(ev.start) }}
<span v-if="ev.place"> · <q-icon name="place" size="16px" aria-hidden="true" /> {{ ev.place }}</span>
</div>
<p class="q-mt-sm text-body2 ellipsis-2-lines">{{ ev.teaser }}</p>
</q-card-section>
<q-card-actions align="right">
<q-btn flat color="primary" label="Dettagli/Iscriviti" :to="ev.to" />
</q-card-actions>
</q-card>
</div>
</div>
</div>
<slot name="below-events" />
</section>
<!-- Collabora / Unisciti -->
<section v-if="sectionsEnabled.collabora" class="section section--collabora" aria-labelledby="collabora-heading">
<div class="container">
<h2 id="collabora-heading" class="section-title">Collabora / Unisciti</h2>
<div class="row q-col-gutter-md">
<div v-for="opt in collaboraOptions" :key="opt.key" class="col-12 col-md-4">
<q-card flat bordered class="rounded-xl h-100">
<q-card-section>
<div class="row items-center no-wrap">
<q-icon :name="opt.icon" size="md" class="q-mr-sm" />
<div class="text-h6 q-my-none">{{ opt.title }}</div>
</div>
<p class="q-mt-sm text-body2">{{ opt.excerpt }}</p>
</q-card-section>
<q-card-actions align="right" class="q-pt-none">
<q-btn :label="opt.cta" color="primary" flat :href="opt.href" :to="opt.to" />
</q-card-actions>
</q-card>
</div>
</div>
</div>
<slot name="below-collabora" />
</section>
<!-- Testimonianze -->
<section v-if="sectionsEnabled.testimonials" class="section section--testi" aria-labelledby="testi-heading">
<div class="container">
<h2 id="testi-heading" class="section-title">Testimonianze</h2>
<q-carousel
v-model="carouselSlide"
:autoplay="5000"
animated
transition-prev="slide-right"
transition-next="slide-left"
swipeable
infinite
height="220px"
@mouseenter="pauseCarousel = true"
@mouseleave="pauseCarousel = false"
:autoplay="pauseCarousel ? 0 : 5000"
>
<q-carousel-slide
v-for="t in data?.testimonials"
:key="t.id"
>
<div class="testimonial">
<q-avatar v-if="t.avatar" size="56px" class="q-mb-sm"><img :src="t.avatar" :alt="t.author" /></q-avatar>
<blockquote class="quote">{{ t.quote }}</blockquote>
<div class="author">{{ t.author }} <span v-if="t.role" class="role"> {{ t.role }}</span></div>
</div>
</q-carousel-slide>
</q-carousel>
</div>
</section>
<!-- Galleria -->
<section v-if="sectionsEnabled.gallery" class="section section--gallery" aria-labelledby="gallery-heading">
<div class="container">
<h2 id="gallery-heading" class="section-title">Galleria</h2>
<div class="row q-col-gutter-sm">
<div v-for="g in data?.gallery" :key="g.id" class="col-6 col-md-3">
<q-img :src="g.src" :alt="g.alt" ratio="1" class="rounded-xl cursor-pointer" @click="openLightbox(g)" />
</div>
</div>
<q-dialog v-model="lightbox.open" persistent>
<q-card class="bg-dark text-white">
<q-card-section class="row items-center justify-between">
<div>{{ currentImage?.alt }}</div>
<q-btn flat dense round icon="close" v-close-popup aria-label="Chiudi" />
</q-card-section>
<q-img :src="currentImage?.src" :alt="currentImage?.alt" ratio="16/9" />
</q-card>
</q-dialog>
</div>
</section>
<!-- FAQ -->
<section v-if="sectionsEnabled.faq" class="section section--faq" aria-labelledby="faq-heading">
<div class="container">
<h2 id="faq-heading" class="section-title">FAQ</h2>
<q-list bordered class="rounded-xl">
<q-expansion-item
v-for="(f, i) in data?.faq"
:key="'faq-' + i"
expand-separator
:label="f.q"
dense
>
<q-card>
<q-card-section class="text-body2">{{ f.a }}</q-card-section>
</q-card>
</q-expansion-item>
</q-list>
</div>
</section>
<!-- News / Blog -->
<section v-if="sectionsEnabled.posts" class="section section--news" aria-labelledby="news-heading">
<div class="container">
<div class="row items-end justify-between q-mb-md">
<h2 id="news-heading" class="section-title">News / Blog</h2>
<div class="col-auto">
<q-btn flat color="primary" label="Tutti gli articoli" to="/blog" />
</div>
</div>
<div v-if="postsState.loading" class="q-gutter-md">
<q-skeleton type="rect" height="100px" v-for="i in 3" :key="'post-sk-' + i" />
</div>
<div v-else-if="postsState.error" class="empty-state">
<q-icon name="warning" class="q-mr-sm" />
<span>{{ postsState.error }}</span>
</div>
<div v-else class="row q-col-gutter-md">
<div v-for="p in latestPosts" :key="p.id" class="col-12 col-md-4">
<q-card flat bordered class="rounded-xl h-100">
<q-img v-if="p.cover" :src="p.cover" ratio="16/9" />
<q-card-section>
<div class="text-subtitle1">{{ p.title }}</div>
<div class="text-caption text-secondary q-mt-xs">
<q-icon name="schedule" size="16px" aria-hidden="true" />
{{ formatDate(p.date) }}
<span v-if="p.category"> · {{ p.category }}</span>
</div>
<p class="q-mt-sm text-body2 ellipsis-3-lines">{{ p.teaser }}</p>
</q-card-section>
<q-card-actions align="right">
<q-btn flat color="primary" label="Leggi tutto" :to="p.to" />
</q-card-actions>
</q-card>
</div>
</div>
</div>
</section>
<!-- Mappa / Sedi -->
<section v-if="sectionsEnabled.map" class="section section--map" aria-labelledby="map-heading">
<div class="container">
<h2 id="map-heading" class="section-title">Dove siamo</h2>
<div class="map-wrap rounded-xl">
<slot name="map">
<iframe
class="map-iframe"
title="Mappa della comunità"
src="https://www.openstreetmap.org/export/embed.html?bbox=12.30%2C45.21%2C12.34%2C45.23&layer=mapnik"
style="border:0;"
loading="lazy"
referrerpolicy="no-referrer-when-downgrade"
></iframe>
</slot>
</div>
<div class="q-mt-md">
<q-btn color="primary" unelevated label="Come arrivare" :href="directionsLink" target="_blank" />
</div>
</div>
</section>
<!-- Newsletter -->
<section v-if="sectionsEnabled.newsletter" class="section section--newsletter" aria-labelledby="newsletter-heading">
<div class="container">
<h2 id="newsletter-heading" class="section-title">Newsletter</h2>
<q-form @submit.prevent="subscribe">
<div class="row items-center q-col-gutter-sm">
<div class="col-12 col-md">
<q-input
v-model="newsletter.email"
type="email"
label="La tua email"
:rules="[emailRule]"
dense
outlined
aria-label="Email per iscrizione newsletter"
>
<template #prepend><q-icon name="mail" /></template>
</q-input>
</div>
<div class="col-12 col-md-auto">
<q-btn type="submit" color="primary" unelevated label="Iscriviti" />
</div>
</div>
<div class="text-caption text-secondary q-mt-xs">
Iscrivendoti accetti la <a :href="privacyLink">privacy policy</a>.
</div>
</q-form>
</div>
</section>
<!-- CTA finale -->
<section v-if="sectionsEnabled.finalCta" class="section section--cta" aria-labelledby="cta-heading">
<div class="container">
<div class="cta-card rounded-xl">
<h2 id="cta-heading" class="cta-title">Progettiamo insieme un nuovo mondo</h2>
<div class="q-gutter-sm">
<q-btn color="secondary" unelevated label="Eventi" :to="eventsLink" />
<q-btn color="primary" unelevated label="Collabora" :to="collaboraLink" />
</div>
</div>
</div>
<slot name="footer-cta" />
</section>
</main>
</q-page>
</template>
<script lang="ts" src="./HomePage.ts"></script>
<style lang="scss" scoped>
@import './HomePage.scss';
</style>

View File

@@ -2684,7 +2684,90 @@ body.body--dark {
text-align: right;
}
.ordine_scontato{
.ordine_scontato {
color: gray;
font-size: 0.85rem;
}
.hero {
position: relative;
border-radius: 20px;
overflow: hidden;
text-align: center;
padding: 40px 20px;
color: white;
// Altezza minima per evitare il collassamento
min-height: 400px;
// Centra il contenuto verticalmente
display: flex;
flex-direction: column;
justify-content: center;
// Background: immagine + overlay
background-size: cover;
background-position: center;
background-repeat: no-repeat;
&::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.5); // overlay scuro
z-index: 1;
border-radius: 20px;
}
}
.hero-content {
position: relative;
z-index: 2; // sopra l'overlay
max-width: 800px;
margin: 0 auto;
width: 100%;
}
.intro {
font-size: 1.3rem;
color: #ddd; // testo chiaro, visibile sopra lo sfondo scuro
margin-bottom: 1.5rem;
font-style: italic;
}
.cta {
display: inline-block;
margin-top: 1rem;
padding: 14px 28px;
background-color: #4caf50;
color: white;
border-radius: 50px;
font-weight: 600;
text-decoration: none;
transition: all 0.3s ease;
box-shadow: 0 4px 10px rgba(76, 175, 80, 0.3);
align-self: center; // centrato in flex-column
&:hover {
background-color: #388e3c;
transform: translateY(-2px);
box-shadow: 0 6px 14px rgba(76, 175, 80, 0.4);
}
}
// Stili aggiuntivi per la pagina
.container {
background: white;
border-radius: 18px;
box-shadow: 0 12px 35px rgba(0, 0, 0, 0.09);
padding: 32px;
margin-bottom: 32px;
transition: transform 0.2s ease;
}
.container:hover {
transform: translateY(-4px);
}

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